mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-10-26 12:27:30 +00:00 
			
		
		
		
	Examples: Vulkan: Further refactor.
This commit is contained in:
		| @@ -11,6 +11,7 @@ | ||||
|  | ||||
| // CHANGELOG | ||||
| // (minor and older changes stripped away, please see git history for details) | ||||
| //  2018-03-03: Vulkan: Various refactor, created a couple of ImGui_ImplVulkanH_XXX helper that the example can use and that viewport support will use. | ||||
| //  2018-03-01: Vulkan: Renamed ImGui_ImplVulkan_Init_Info to ImGui_ImplVulkan_InitInfo and fields to match more closely Vulkan terminology. | ||||
| //  2018-02-18: Vulkan: Offset projection matrix and clipping rectangle by io.DisplayPos (which will be non-zero for multi-viewport applications). | ||||
| //  2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback, ImGui_ImplVulkan_Render() calls ImGui_ImplVulkan_RenderDrawData() itself. | ||||
| @@ -720,7 +721,6 @@ void ImGui_ImplVulkan_NewFrame() | ||||
|  | ||||
| void ImGui_ImplVulkan_Render(VkCommandBuffer command_buffer) | ||||
| { | ||||
|     ImGui::Render(); | ||||
|     ImGui_ImplVulkan_RenderDrawData(command_buffer, ImGui::GetDrawData()); | ||||
|     g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES; | ||||
| } | ||||
| @@ -821,10 +821,53 @@ VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_d | ||||
|     return VK_PRESENT_MODE_FIFO_KHR; // Always available | ||||
| } | ||||
|  | ||||
| void ImGui_ImplVulkanH_CreateOrResizeWindowData(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkan_WindowData* wd, const VkAllocationCallbacks* allocator, int w, int h) | ||||
| void ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, uint32_t queue_family, ImGui_ImplVulkan_WindowData* wd, const VkAllocationCallbacks* allocator) | ||||
| { | ||||
|     IM_ASSERT(physical_device != NULL && device != NULL); | ||||
|     (void)allocator; | ||||
|  | ||||
|     // Create Command Buffers | ||||
|     VkResult err; | ||||
|     for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++) | ||||
|     { | ||||
|         ImGui_ImplVulkan_FrameData* fd = &wd->Frames[i]; | ||||
|         { | ||||
|             VkCommandPoolCreateInfo info = {}; | ||||
|             info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; | ||||
|             info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; | ||||
|             info.queueFamilyIndex = queue_family; | ||||
|             err = vkCreateCommandPool(device, &info, allocator, &fd->CommandPool); | ||||
|             check_vk_result(err); | ||||
|         } | ||||
|         { | ||||
|             VkCommandBufferAllocateInfo info = {}; | ||||
|             info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; | ||||
|             info.commandPool = fd->CommandPool; | ||||
|             info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; | ||||
|             info.commandBufferCount = 1; | ||||
|             err = vkAllocateCommandBuffers(device, &info, &fd->CommandBuffer); | ||||
|             check_vk_result(err); | ||||
|         } | ||||
|         { | ||||
|             VkFenceCreateInfo info = {}; | ||||
|             info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; | ||||
|             info.flags = VK_FENCE_CREATE_SIGNALED_BIT; | ||||
|             err = vkCreateFence(device, &info, allocator, &fd->Fence); | ||||
|             check_vk_result(err); | ||||
|         } | ||||
|         { | ||||
|             VkSemaphoreCreateInfo info = {}; | ||||
|             info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; | ||||
|             err = vkCreateSemaphore(device, &info, allocator, &fd->PresentCompleteSemaphore); | ||||
|             check_vk_result(err); | ||||
|             err = vkCreateSemaphore(device, &info, allocator, &fd->RenderCompleteSemaphore); | ||||
|             check_vk_result(err); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkan_WindowData* wd, const VkAllocationCallbacks* allocator, int w, int h) | ||||
| { | ||||
|     VkResult err; | ||||
|     VkSwapchainKHR old_swapchain = wd->Swapchain; | ||||
|     err = vkDeviceWaitIdle(device); | ||||
| @@ -972,6 +1015,7 @@ void ImGui_ImplVulkanH_DestroyWindowData(VkInstance instance, VkDevice device, I | ||||
|     vkDestroyRenderPass(device, wd->RenderPass, allocator); | ||||
|     vkDestroySwapchainKHR(device, wd->Swapchain, allocator); | ||||
|     vkDestroySurfaceKHR(instance, wd->Surface, allocator); | ||||
|     *wd = ImGui_ImplVulkan_WindowData(); | ||||
| } | ||||
|  | ||||
| //-------------------------------------------------------------------------------------------------------- | ||||
|   | ||||
| @@ -47,12 +47,12 @@ IMGUI_API bool        ImGui_ImplVulkan_CreateDeviceObjects(); | ||||
|  | ||||
| struct ImGui_ImplVulkan_FrameData; | ||||
| struct ImGui_ImplVulkan_WindowData; | ||||
| struct ImGui_ImplVulkan_WindowDataCreateInfo; | ||||
|  | ||||
| IMGUI_API void                  ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, uint32_t queue_family, ImGui_ImplVulkan_WindowData* wd, const VkAllocationCallbacks* allocator); | ||||
| IMGUI_API void                  ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkan_WindowData* wd, const VkAllocationCallbacks* allocator, int w, int h); | ||||
| IMGUI_API void                  ImGui_ImplVulkanH_DestroyWindowData(VkInstance instance, VkDevice device, ImGui_ImplVulkan_WindowData* wd, const VkAllocationCallbacks* allocator); | ||||
| IMGUI_API VkSurfaceFormatKHR    ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space); | ||||
| IMGUI_API VkPresentModeKHR      ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count); | ||||
| IMGUI_API void                  ImGui_ImplVulkanH_CreateOrResizeWindowData(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkan_WindowData* wd, const VkAllocationCallbacks* allocator, int w, int h); | ||||
| IMGUI_API void                  ImGui_ImplVulkanH_DestroyWindowData(VkInstance instance, VkDevice device, ImGui_ImplVulkan_WindowData* wd, const VkAllocationCallbacks* allocator); | ||||
|  | ||||
| struct ImGui_ImplVulkan_FrameData | ||||
| { | ||||
| @@ -68,7 +68,8 @@ struct ImGui_ImplVulkan_FrameData | ||||
|  | ||||
| struct ImGui_ImplVulkan_WindowData | ||||
| { | ||||
|     int                 Width, Height; | ||||
|     int                 Width; | ||||
|     int                 Height; | ||||
|     VkSwapchainKHR      Swapchain; | ||||
|     VkSurfaceKHR        Surface; | ||||
|     VkSurfaceFormatKHR  SurfaceFormat; | ||||
|   | ||||
| @@ -44,10 +44,12 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, | ||||
| } | ||||
| #endif // IMGUI_VULKAN_DEBUG_REPORT | ||||
|  | ||||
| static void CreateVulkanInstance(const char** extensions, uint32_t extensions_count) | ||||
| static void SetupVulkan(const char** extensions, uint32_t extensions_count) | ||||
| { | ||||
|     VkResult err; | ||||
|  | ||||
|     // Create Vulkan Instance | ||||
|     { | ||||
|         VkInstanceCreateInfo create_info = {}; | ||||
|         create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; | ||||
|         create_info.enabledExtensionCount = extensions_count; | ||||
| @@ -88,13 +90,7 @@ static void CreateVulkanInstance(const char** extensions, uint32_t extensions_co | ||||
|         err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); | ||||
|         check_vk_result(err); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| static void SetupVulkan(ImGui_ImplVulkan_WindowData* wd) | ||||
| { | ||||
|     IM_ASSERT(wd->Surface != NULL); | ||||
|  | ||||
|     VkResult err; | ||||
|     } | ||||
|  | ||||
|     // Select GPU | ||||
|     { | ||||
| @@ -129,34 +125,6 @@ static void SetupVulkan(ImGui_ImplVulkan_WindowData* wd) | ||||
|         IM_ASSERT(g_QueueFamily != -1); | ||||
|     } | ||||
|  | ||||
|     // Check for WSI support | ||||
|     { | ||||
|         VkBool32 res; | ||||
|         vkGetPhysicalDeviceSurfaceSupportKHR(g_PhysicalDevice, g_QueueFamily, wd->Surface, &res); | ||||
|         if (res != VK_TRUE) | ||||
|         { | ||||
|             fprintf(stderr, "Error no WSI support on physical device 0\n"); | ||||
|             exit(-1); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Get Surface Format | ||||
|     { | ||||
|         const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM }; | ||||
|         const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; | ||||
|         wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace); | ||||
|     } | ||||
|  | ||||
|     // Get Present Mode | ||||
|     { | ||||
| #ifdef IMGUI_UNLIMITED_FRAME_RATE | ||||
|         VkPresentModeKHR present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; | ||||
| #else | ||||
|         VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR; | ||||
| #endif | ||||
|         wd->PresentMode = ImGui_ImplVulkanH_SelectPresentMode(g_PhysicalDevice, wd->Surface, &present_mode, 1); | ||||
|     } | ||||
|  | ||||
|     // Create Logical Device (with 1 queue) | ||||
|     { | ||||
|         int device_extension_count = 1; | ||||
| @@ -178,44 +146,6 @@ static void SetupVulkan(ImGui_ImplVulkan_WindowData* wd) | ||||
|         vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue); | ||||
|     } | ||||
|  | ||||
|     // Create Command Buffers | ||||
|     for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++) | ||||
|     { | ||||
|         ImGui_ImplVulkan_FrameData* fd = &wd->Frames[i]; | ||||
|         { | ||||
|             VkCommandPoolCreateInfo info = {}; | ||||
|             info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; | ||||
|             info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; | ||||
|             info.queueFamilyIndex = g_QueueFamily; | ||||
|             err = vkCreateCommandPool(g_Device, &info, g_Allocator, &fd->CommandPool); | ||||
|             check_vk_result(err); | ||||
|         } | ||||
|         { | ||||
|             VkCommandBufferAllocateInfo info = {}; | ||||
|             info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; | ||||
|             info.commandPool = fd->CommandPool; | ||||
|             info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; | ||||
|             info.commandBufferCount = 1; | ||||
|             err = vkAllocateCommandBuffers(g_Device, &info, &fd->CommandBuffer); | ||||
|             check_vk_result(err); | ||||
|         } | ||||
|         { | ||||
|             VkFenceCreateInfo info = {}; | ||||
|             info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; | ||||
|             info.flags = VK_FENCE_CREATE_SIGNALED_BIT; | ||||
|             err = vkCreateFence(g_Device, &info, g_Allocator, &fd->Fence); | ||||
|             check_vk_result(err); | ||||
|         } | ||||
|         { | ||||
|             VkSemaphoreCreateInfo info = {}; | ||||
|             info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; | ||||
|             err = vkCreateSemaphore(g_Device, &info, g_Allocator, &fd->PresentCompleteSemaphore); | ||||
|             check_vk_result(err); | ||||
|             err = vkCreateSemaphore(g_Device, &info, g_Allocator, &fd->RenderCompleteSemaphore); | ||||
|             check_vk_result(err); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Create Descriptor Pool | ||||
|     { | ||||
|         VkDescriptorPoolSize pool_sizes[] = | ||||
| @@ -243,11 +173,42 @@ static void SetupVulkan(ImGui_ImplVulkan_WindowData* wd) | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void cleanup_vulkan() | ||||
| static void SetupVulkanWindowData(ImGui_ImplVulkan_WindowData* wd, VkSurfaceKHR surface, int width, int height) | ||||
| { | ||||
|     wd->Surface = surface; | ||||
|  | ||||
|     // Check for WSI support | ||||
|     VkBool32 res; | ||||
|     vkGetPhysicalDeviceSurfaceSupportKHR(g_PhysicalDevice, g_QueueFamily, wd->Surface, &res); | ||||
|     if (res != VK_TRUE) | ||||
|     { | ||||
|         fprintf(stderr, "Error no WSI support on physical device 0\n"); | ||||
|         exit(-1); | ||||
|     } | ||||
|  | ||||
|     // Get Surface Format | ||||
|     const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM }; | ||||
|     const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; | ||||
|     wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace); | ||||
|  | ||||
|     // Get Present Mode | ||||
| #ifdef IMGUI_UNLIMITED_FRAME_RATE | ||||
|     VkPresentModeKHR present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; | ||||
| #else | ||||
|     VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR; | ||||
| #endif | ||||
|     wd->PresentMode = ImGui_ImplVulkanH_SelectPresentMode(g_PhysicalDevice, wd->Surface, &present_mode, 1); | ||||
|  | ||||
|     // Create SwapChain, RenderPass, Framebuffer, etc. | ||||
|     ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(g_PhysicalDevice, g_Device, g_QueueFamily, wd, g_Allocator); | ||||
|     ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, wd, g_Allocator, width, height); | ||||
| } | ||||
|  | ||||
| static void CleanupVulkan() | ||||
| { | ||||
|     ImGui_ImplVulkan_WindowData* wd = &g_WindowData; | ||||
|     vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); | ||||
|     ImGui_ImplVulkanH_DestroyWindowData(g_Instance, g_Device, wd, g_Allocator); | ||||
|     vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); | ||||
|  | ||||
| #ifdef IMGUI_VULKAN_DEBUG_REPORT | ||||
|     // Remove the debug report callback | ||||
| @@ -259,7 +220,7 @@ static void cleanup_vulkan() | ||||
|     vkDestroyInstance(g_Instance, g_Allocator); | ||||
| } | ||||
|  | ||||
| static void frame_begin(ImGui_ImplVulkan_WindowData* wd) | ||||
| static void FrameBegin(ImGui_ImplVulkan_WindowData* wd) | ||||
| { | ||||
|     ImGui_ImplVulkan_FrameData* fd = &wd->Frames[wd->FrameIndex]; | ||||
|     VkResult err; | ||||
| @@ -296,7 +257,7 @@ static void frame_begin(ImGui_ImplVulkan_WindowData* wd) | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void frame_end(ImGui_ImplVulkan_WindowData* wd) | ||||
| static void FrameEnd(ImGui_ImplVulkan_WindowData* wd) | ||||
| { | ||||
|     ImGui_ImplVulkan_FrameData* fd = &wd->Frames[wd->FrameIndex]; | ||||
|     VkResult err; | ||||
| @@ -322,14 +283,14 @@ static void frame_end(ImGui_ImplVulkan_WindowData* wd) | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void frame_present(ImGui_ImplVulkan_WindowData* wd) | ||||
| static void FramePresent(ImGui_ImplVulkan_WindowData* wd) | ||||
| { | ||||
|     VkResult err; | ||||
|     // If IMGUI_UNLIMITED_FRAME_RATE is defined we present the latest but one frame. Otherwise we present the latest rendered frame | ||||
| #ifdef IMGUI_UNLIMITED_FRAME_RATE | ||||
|     uint32_t PresentIndex = (wd->FrameIndex + IMGUI_VK_QUEUED_FRAMES - 1) % IMGUI_VK_QUEUED_FRAMES; | ||||
| #else | ||||
|     uint32_t PresentIndex = g_FrameIndex; | ||||
|     uint32_t PresentIndex = wd->FrameIndex; | ||||
| #endif // IMGUI_UNLIMITED_FRAME_RATE | ||||
|  | ||||
|     ImGui_ImplVulkan_FrameData* fd = &wd->Frames[PresentIndex]; | ||||
| @@ -359,34 +320,29 @@ int main(int, char**) | ||||
|     SDL_Window* window = SDL_CreateWindow("ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_VULKAN|SDL_WINDOW_RESIZABLE); | ||||
|  | ||||
|     // Setup Vulkan | ||||
|     uint32_t sdl_extensions_count; | ||||
|     SDL_Vulkan_GetInstanceExtensions(window, &sdl_extensions_count, NULL); | ||||
|     const char** sdl_extensions = new const char*[sdl_extensions_count]; | ||||
|     SDL_Vulkan_GetInstanceExtensions(window, &sdl_extensions_count, sdl_extensions); | ||||
|     CreateVulkanInstance(sdl_extensions, sdl_extensions_count); | ||||
|     delete[] sdl_extensions; | ||||
|     uint32_t extensions_count = 0; | ||||
|     SDL_Vulkan_GetInstanceExtensions(window, &extensions_count, NULL); | ||||
|     const char** extensions = new const char*[extensions_count]; | ||||
|     SDL_Vulkan_GetInstanceExtensions(window, &extensions_count, extensions); | ||||
|     SetupVulkan(extensions, extensions_count); | ||||
|     delete[] extensions; | ||||
|  | ||||
|     // Create Window Surface | ||||
|     ImGui_ImplVulkan_WindowData* wd = &g_WindowData; | ||||
|     SDL_bool result = SDL_Vulkan_CreateSurface(window, g_Instance, &wd->Surface); | ||||
|     if (result == 0)  | ||||
|     VkSurfaceKHR surface; | ||||
|     if (SDL_Vulkan_CreateSurface(window, g_Instance, &surface) == 0) | ||||
|     { | ||||
|         printf("Failed to create Vulkan surface.\n"); | ||||
|         return 1; | ||||
|     } | ||||
|  | ||||
|     SetupVulkan(wd); | ||||
|  | ||||
|     // Create Framebuffers | ||||
|     { | ||||
|     int w, h; | ||||
|     SDL_GetWindowSize(window, &w, &h); | ||||
|         ImGui_ImplVulkanH_CreateOrResizeWindowData(g_PhysicalDevice, g_Device, wd, g_Allocator, w, h); | ||||
|     } | ||||
|     ImGui_ImplVulkan_WindowData* wd = &g_WindowData; | ||||
|     SetupVulkanWindowData(wd, surface, w, h); | ||||
|  | ||||
|     // Setup ImGui binding | ||||
|     ImGui::CreateContext(); | ||||
|  | ||||
|     ImGuiIO& io = ImGui::GetIO(); (void)io; | ||||
|     io.ConfigFlags |= ImGuiConfigFlags_MultiViewports; | ||||
|     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls | ||||
| @@ -399,8 +355,8 @@ int main(int, char**) | ||||
|     init_info.DescriptorPool = g_DescriptorPool; | ||||
|     init_info.Allocator = g_Allocator; | ||||
|     init_info.CheckVkResultFn = check_vk_result; | ||||
|     ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); | ||||
|     ImGui_ImplSDL2_Init(window, NULL); | ||||
|     ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); | ||||
|  | ||||
|     // Setup style | ||||
|     ImGui::StyleColorsDark(); | ||||
| @@ -473,7 +429,7 @@ int main(int, char**) | ||||
|             if (event.type == SDL_QUIT) | ||||
|                 done = true; | ||||
|             if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED && event.window.windowID == SDL_GetWindowID(window))  | ||||
|                 ImGui_ImplVulkanH_CreateOrResizeWindowData(g_PhysicalDevice, g_Device, &g_WindowData, g_Allocator, (int)event.window.data1, (int)event.window.data2); | ||||
|                 ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, &g_WindowData, g_Allocator, (int)event.window.data1, (int)event.window.data2); | ||||
|         } | ||||
|         ImGui_ImplVulkan_NewFrame(); | ||||
|         ImGui_ImplSDL2_NewFrame(window); | ||||
| @@ -516,10 +472,11 @@ int main(int, char**) | ||||
|         } | ||||
|  | ||||
|         // Rendering | ||||
|         ImGui::Render(); | ||||
|         memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); | ||||
|         frame_begin(wd); | ||||
|         FrameBegin(wd); | ||||
|         ImGui_ImplVulkan_Render(wd->Frames[wd->FrameIndex].CommandBuffer); | ||||
|         frame_end(wd); | ||||
|         FrameEnd(wd); | ||||
|  | ||||
| 		ImGui::RenderAdditionalViewports(); | ||||
|  | ||||
| @@ -527,9 +484,9 @@ int main(int, char**) | ||||
|         // When IMGUI_UNLIMITED_FRAME_RATE is defined we render into latest image acquired from the swapchain but we display the image which was rendered before. | ||||
|         // Hence we must render once and increase the FrameIndex without presenting. | ||||
|         if (swap_chain_has_at_least_one_image) | ||||
|             frame_present(wd); | ||||
|             FramePresent(wd); | ||||
| #else | ||||
|         frame_present(wd); | ||||
|         FramePresent(wd); | ||||
| #endif | ||||
|         swap_chain_has_at_least_one_image = true; | ||||
|         wd->FrameIndex = (wd->FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES; | ||||
| @@ -542,7 +499,7 @@ int main(int, char**) | ||||
|     ImGui_ImplSDL2_Shutdown(); | ||||
|     ImGui::DestroyContext(); | ||||
|     SDL_DestroyWindow(window); | ||||
|     cleanup_vulkan(); | ||||
|     CleanupVulkan(); | ||||
|     SDL_Quit(); | ||||
|  | ||||
|     return 0; | ||||
|   | ||||
| @@ -47,10 +47,12 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, | ||||
| } | ||||
| #endif // IMGUI_VULKAN_DEBUG_REPORT | ||||
|  | ||||
| static void CreateVulkanInstance(const char** extensions, uint32_t extensions_count) | ||||
| static void SetupVulkan(const char** extensions, uint32_t extensions_count) | ||||
| { | ||||
|     VkResult err; | ||||
|  | ||||
|     // Create Vulkan Instance | ||||
|     { | ||||
|         VkInstanceCreateInfo create_info = {}; | ||||
|         create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; | ||||
|         create_info.enabledExtensionCount = extensions_count; | ||||
| @@ -91,13 +93,7 @@ static void CreateVulkanInstance(const char** extensions, uint32_t extensions_co | ||||
|         err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); | ||||
|         check_vk_result(err); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| static void SetupVulkan(ImGui_ImplVulkan_WindowData* wd) | ||||
| { | ||||
|     IM_ASSERT(wd->Surface != NULL); | ||||
|  | ||||
|     VkResult err; | ||||
|     } | ||||
|  | ||||
|     // Select GPU | ||||
|     { | ||||
| @@ -132,34 +128,6 @@ static void SetupVulkan(ImGui_ImplVulkan_WindowData* wd) | ||||
|         IM_ASSERT(g_QueueFamily != -1); | ||||
|     } | ||||
|  | ||||
|     // Check for WSI support | ||||
|     { | ||||
|         VkBool32 res; | ||||
|         vkGetPhysicalDeviceSurfaceSupportKHR(g_PhysicalDevice, g_QueueFamily, wd->Surface, &res); | ||||
|         if (res != VK_TRUE) | ||||
|         { | ||||
|             fprintf(stderr, "Error no WSI support on physical device 0\n"); | ||||
|             exit(-1); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Get Surface Format | ||||
|     { | ||||
|         const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM }; | ||||
|         const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; | ||||
|         wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace); | ||||
|     } | ||||
|  | ||||
|     // Get Present Mode | ||||
|     { | ||||
| #ifdef IMGUI_UNLIMITED_FRAME_RATE | ||||
|         VkPresentModeKHR present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; | ||||
| #else | ||||
|         VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR; | ||||
| #endif | ||||
|         wd->PresentMode = ImGui_ImplVulkanH_SelectPresentMode(g_PhysicalDevice, wd->Surface, &present_mode, 1); | ||||
|     } | ||||
|  | ||||
|     // Create Logical Device (with 1 queue) | ||||
|     { | ||||
|         int device_extension_count = 1; | ||||
| @@ -181,44 +149,6 @@ static void SetupVulkan(ImGui_ImplVulkan_WindowData* wd) | ||||
|         vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue); | ||||
|     } | ||||
|  | ||||
|     // Create Command Buffers | ||||
|     for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++) | ||||
|     { | ||||
|         ImGui_ImplVulkan_FrameData* fd = &wd->Frames[i]; | ||||
|         { | ||||
|             VkCommandPoolCreateInfo info = {}; | ||||
|             info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; | ||||
|             info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; | ||||
|             info.queueFamilyIndex = g_QueueFamily; | ||||
|             err = vkCreateCommandPool(g_Device, &info, g_Allocator, &fd->CommandPool); | ||||
|             check_vk_result(err); | ||||
|         } | ||||
|         { | ||||
|             VkCommandBufferAllocateInfo info = {}; | ||||
|             info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; | ||||
|             info.commandPool = fd->CommandPool; | ||||
|             info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; | ||||
|             info.commandBufferCount = 1; | ||||
|             err = vkAllocateCommandBuffers(g_Device, &info, &fd->CommandBuffer); | ||||
|             check_vk_result(err); | ||||
|         } | ||||
|         { | ||||
|             VkFenceCreateInfo info = {}; | ||||
|             info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; | ||||
|             info.flags = VK_FENCE_CREATE_SIGNALED_BIT; | ||||
|             err = vkCreateFence(g_Device, &info, g_Allocator, &fd->Fence); | ||||
|             check_vk_result(err); | ||||
|         } | ||||
|         { | ||||
|             VkSemaphoreCreateInfo info = {}; | ||||
|             info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; | ||||
|             err = vkCreateSemaphore(g_Device, &info, g_Allocator, &fd->PresentCompleteSemaphore); | ||||
|             check_vk_result(err); | ||||
|             err = vkCreateSemaphore(g_Device, &info, g_Allocator, &fd->RenderCompleteSemaphore); | ||||
|             check_vk_result(err); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Create Descriptor Pool | ||||
|     { | ||||
|         VkDescriptorPoolSize pool_sizes[] = | ||||
| @@ -246,11 +176,42 @@ static void SetupVulkan(ImGui_ImplVulkan_WindowData* wd) | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void cleanup_vulkan() | ||||
| static void SetupVulkanWindowData(ImGui_ImplVulkan_WindowData* wd, VkSurfaceKHR surface, int width, int height) | ||||
| { | ||||
|     wd->Surface = surface; | ||||
|  | ||||
|     // Check for WSI support | ||||
|     VkBool32 res; | ||||
|     vkGetPhysicalDeviceSurfaceSupportKHR(g_PhysicalDevice, g_QueueFamily, wd->Surface, &res); | ||||
|     if (res != VK_TRUE) | ||||
|     { | ||||
|         fprintf(stderr, "Error no WSI support on physical device 0\n"); | ||||
|         exit(-1); | ||||
|     } | ||||
|  | ||||
|     // Get Surface Format | ||||
|     const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM }; | ||||
|     const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; | ||||
|     wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace); | ||||
|  | ||||
|     // Get Present Mode | ||||
| #ifdef IMGUI_UNLIMITED_FRAME_RATE | ||||
|     VkPresentModeKHR present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; | ||||
| #else | ||||
|     VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR; | ||||
| #endif | ||||
|     wd->PresentMode = ImGui_ImplVulkanH_SelectPresentMode(g_PhysicalDevice, wd->Surface, &present_mode, 1); | ||||
|  | ||||
|     // Create SwapChain, RenderPass, Framebuffer, etc. | ||||
|     ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(g_PhysicalDevice, g_Device, g_QueueFamily, wd, g_Allocator); | ||||
|     ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, wd, g_Allocator, width, height); | ||||
| } | ||||
|  | ||||
| static void CleanupVulkan() | ||||
| { | ||||
|     ImGui_ImplVulkan_WindowData* wd = &g_WindowData; | ||||
|     vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); | ||||
|     ImGui_ImplVulkanH_DestroyWindowData(g_Instance, g_Device, wd, g_Allocator); | ||||
|     vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); | ||||
|  | ||||
| #ifdef IMGUI_VULKAN_DEBUG_REPORT | ||||
|     // Remove the debug report callback | ||||
| @@ -262,7 +223,7 @@ static void cleanup_vulkan() | ||||
|     vkDestroyInstance(g_Instance, g_Allocator); | ||||
| } | ||||
|  | ||||
| static void frame_begin(ImGui_ImplVulkan_WindowData* wd) | ||||
| static void FrameBegin(ImGui_ImplVulkan_WindowData* wd) | ||||
| { | ||||
|     ImGui_ImplVulkan_FrameData* fd = &wd->Frames[wd->FrameIndex]; | ||||
|     VkResult err; | ||||
| @@ -299,7 +260,7 @@ static void frame_begin(ImGui_ImplVulkan_WindowData* wd) | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void frame_end(ImGui_ImplVulkan_WindowData* wd) | ||||
| static void FrameEnd(ImGui_ImplVulkan_WindowData* wd) | ||||
| { | ||||
|     ImGui_ImplVulkan_FrameData* fd = &wd->Frames[wd->FrameIndex]; | ||||
|     VkResult err; | ||||
| @@ -325,14 +286,14 @@ static void frame_end(ImGui_ImplVulkan_WindowData* wd) | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void frame_present(ImGui_ImplVulkan_WindowData* wd) | ||||
| static void FramePresent(ImGui_ImplVulkan_WindowData* wd) | ||||
| { | ||||
|     VkResult err; | ||||
|     // If IMGUI_UNLIMITED_FRAME_RATE is defined we present the latest but one frame. Otherwise we present the latest rendered frame | ||||
| #ifdef IMGUI_UNLIMITED_FRAME_RATE | ||||
|     uint32_t PresentIndex = (wd->FrameIndex + IMGUI_VK_QUEUED_FRAMES - 1) % IMGUI_VK_QUEUED_FRAMES; | ||||
| #else | ||||
|     uint32_t PresentIndex = g_FrameIndex; | ||||
|     uint32_t PresentIndex = wd->FrameIndex; | ||||
| #endif // IMGUI_UNLIMITED_FRAME_RATE | ||||
|  | ||||
|     ImGui_ImplVulkan_FrameData* fd = &wd->Frames[PresentIndex]; | ||||
| @@ -354,7 +315,7 @@ static void glfw_error_callback(int error, const char* description) | ||||
|  | ||||
| static void glfw_resize_callback(GLFWwindow*, int w, int h) | ||||
| { | ||||
|     ImGui_ImplVulkanH_CreateOrResizeWindowData(g_PhysicalDevice, g_Device, &g_WindowData, g_Allocator, w, h); | ||||
|     ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, &g_WindowData, g_Allocator, w, h); | ||||
| } | ||||
|  | ||||
| int main(int, char**) | ||||
| @@ -373,26 +334,24 @@ int main(int, char**) | ||||
|         printf("GLFW: Vulkan Not Supported\n"); | ||||
|         return 1; | ||||
|     } | ||||
|     uint32_t glfw_extensions_count = 0; | ||||
|     const char** glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extensions_count); | ||||
|     CreateVulkanInstance(glfw_extensions, glfw_extensions_count); | ||||
|     uint32_t extensions_count = 0; | ||||
|     const char** extensions = glfwGetRequiredInstanceExtensions(&extensions_count); | ||||
|     SetupVulkan(extensions, extensions_count); | ||||
|  | ||||
|     // Create Window Surface | ||||
|     ImGui_ImplVulkan_WindowData* wd = &g_WindowData; | ||||
|     VkResult err = glfwCreateWindowSurface(g_Instance, window, g_Allocator, &wd->Surface); | ||||
|     VkSurfaceKHR surface; | ||||
|     VkResult err = glfwCreateWindowSurface(g_Instance, window, g_Allocator, &surface); | ||||
|     check_vk_result(err); | ||||
|  | ||||
|     SetupVulkan(wd); | ||||
|  | ||||
|     // Create Framebuffers | ||||
|     int w, h; | ||||
|     glfwGetFramebufferSize(window, &w, &h); | ||||
|     ImGui_ImplVulkanH_CreateOrResizeWindowData(g_PhysicalDevice, g_Device, wd, g_Allocator, w, h); | ||||
|     glfwSetFramebufferSizeCallback(window, glfw_resize_callback); | ||||
|     ImGui_ImplVulkan_WindowData* wd = &g_WindowData; | ||||
|     SetupVulkanWindowData(wd, surface, w, h); | ||||
|  | ||||
|     // Setup ImGui binding | ||||
|     ImGui::CreateContext(); | ||||
|  | ||||
|     ImGuiIO& io = ImGui::GetIO(); (void)io; | ||||
|     io.ConfigFlags |= ImGuiConfigFlags_MultiViewports; | ||||
|     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls | ||||
| @@ -405,8 +364,8 @@ int main(int, char**) | ||||
|     init_info.DescriptorPool = g_DescriptorPool; | ||||
|     init_info.Allocator = g_Allocator; | ||||
|     init_info.CheckVkResultFn = check_vk_result; | ||||
|     ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); | ||||
|     ImGui_ImplGlfw_InitForVulkan(window, true); | ||||
|     ImGui_ImplVulkan_Init(&init_info, wd->RenderPass); | ||||
|  | ||||
|     // Setup style | ||||
|     ImGui::StyleColorsDark(); | ||||
| @@ -513,10 +472,11 @@ int main(int, char**) | ||||
|         } | ||||
|  | ||||
|         // Rendering | ||||
|         ImGui::Render(); | ||||
|         memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); | ||||
|         frame_begin(wd); | ||||
|         FrameBegin(wd); | ||||
|         ImGui_ImplVulkan_Render(wd->Frames[wd->FrameIndex].CommandBuffer); | ||||
|         frame_end(wd); | ||||
|         FrameEnd(wd); | ||||
|  | ||||
| 		ImGui::RenderAdditionalViewports(); | ||||
|  | ||||
| @@ -524,9 +484,9 @@ int main(int, char**) | ||||
|         // When IMGUI_UNLIMITED_FRAME_RATE is defined we render into latest image acquired from the swapchain but we display the image which was rendered before. | ||||
|         // Hence we must render once and increase the FrameIndex without presenting. | ||||
|         if (swap_chain_has_at_least_one_image) | ||||
|             frame_present(wd); | ||||
|             FramePresent(wd); | ||||
| #else | ||||
|         frame_present(wd); | ||||
|         FramePresent(wd); | ||||
| #endif | ||||
|         swap_chain_has_at_least_one_image = true; | ||||
|         wd->FrameIndex = (wd->FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES; | ||||
| @@ -538,7 +498,7 @@ int main(int, char**) | ||||
|     ImGui_ImplVulkan_Shutdown(); | ||||
|     ImGui_ImplGlfw_Shutdown(); | ||||
|     ImGui::DestroyContext(); | ||||
|     cleanup_vulkan(); | ||||
|     CleanupVulkan(); | ||||
|     glfwTerminate(); | ||||
|  | ||||
|     return 0; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 omar
					omar