mirror of
https://github.com/ocornut/imgui.git
synced 2024-12-13 04:39:02 +08:00
Examples: Vulkan: Further refactor.
This commit is contained in:
parent
e0cbfd74d7
commit
cab41d954e
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (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-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-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.
|
// 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)
|
void ImGui_ImplVulkan_Render(VkCommandBuffer command_buffer)
|
||||||
{
|
{
|
||||||
ImGui::Render();
|
|
||||||
ImGui_ImplVulkan_RenderDrawData(command_buffer, ImGui::GetDrawData());
|
ImGui_ImplVulkan_RenderDrawData(command_buffer, ImGui::GetDrawData());
|
||||||
g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
|
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
|
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);
|
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;
|
VkResult err;
|
||||||
VkSwapchainKHR old_swapchain = wd->Swapchain;
|
VkSwapchainKHR old_swapchain = wd->Swapchain;
|
||||||
err = vkDeviceWaitIdle(device);
|
err = vkDeviceWaitIdle(device);
|
||||||
@ -972,6 +1015,7 @@ void ImGui_ImplVulkanH_DestroyWindowData(VkInstance instance, VkDevice device, I
|
|||||||
vkDestroyRenderPass(device, wd->RenderPass, allocator);
|
vkDestroyRenderPass(device, wd->RenderPass, allocator);
|
||||||
vkDestroySwapchainKHR(device, wd->Swapchain, allocator);
|
vkDestroySwapchainKHR(device, wd->Swapchain, allocator);
|
||||||
vkDestroySurfaceKHR(instance, wd->Surface, 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_FrameData;
|
||||||
struct ImGui_ImplVulkan_WindowData;
|
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 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 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
|
struct ImGui_ImplVulkan_FrameData
|
||||||
{
|
{
|
||||||
@ -68,7 +68,8 @@ struct ImGui_ImplVulkan_FrameData
|
|||||||
|
|
||||||
struct ImGui_ImplVulkan_WindowData
|
struct ImGui_ImplVulkan_WindowData
|
||||||
{
|
{
|
||||||
int Width, Height;
|
int Width;
|
||||||
|
int Height;
|
||||||
VkSwapchainKHR Swapchain;
|
VkSwapchainKHR Swapchain;
|
||||||
VkSurfaceKHR Surface;
|
VkSurfaceKHR Surface;
|
||||||
VkSurfaceFormatKHR SurfaceFormat;
|
VkSurfaceFormatKHR SurfaceFormat;
|
||||||
|
@ -44,57 +44,53 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags,
|
|||||||
}
|
}
|
||||||
#endif // IMGUI_VULKAN_DEBUG_REPORT
|
#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;
|
VkResult err;
|
||||||
|
|
||||||
VkInstanceCreateInfo create_info = {};
|
|
||||||
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
|
||||||
create_info.enabledExtensionCount = extensions_count;
|
|
||||||
create_info.ppEnabledExtensionNames = extensions;
|
|
||||||
|
|
||||||
#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
|
||||||
// Enabling multiple validation layers grouped as LunarG standard validation
|
|
||||||
const char* layers[] = { "VK_LAYER_LUNARG_standard_validation" };
|
|
||||||
create_info.enabledLayerCount = 1;
|
|
||||||
create_info.ppEnabledLayerNames = layers;
|
|
||||||
|
|
||||||
// Enable debug report extension (we need additional storage, so we duplicate the user array to add our new extension to it)
|
|
||||||
const char** extensions_ext = (const char**)malloc(sizeof(const char*) * (extensions_count + 1));
|
|
||||||
memcpy(extensions_ext, extensions, extensions_count * sizeof(const char*));
|
|
||||||
extensions_ext[extensions_count] = "VK_EXT_debug_report";
|
|
||||||
create_info.enabledExtensionCount = extensions_count + 1;
|
|
||||||
create_info.ppEnabledExtensionNames = extensions_ext;
|
|
||||||
|
|
||||||
// Create Vulkan Instance
|
// Create Vulkan Instance
|
||||||
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
|
{
|
||||||
check_vk_result(err);
|
VkInstanceCreateInfo create_info = {};
|
||||||
free(extensions_ext);
|
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
|
create_info.enabledExtensionCount = extensions_count;
|
||||||
|
create_info.ppEnabledExtensionNames = extensions;
|
||||||
|
|
||||||
// Get the function pointer (required for any extensions)
|
#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
||||||
auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
|
// Enabling multiple validation layers grouped as LunarG standard validation
|
||||||
IM_ASSERT(vkCreateDebugReportCallbackEXT != NULL);
|
const char* layers[] = { "VK_LAYER_LUNARG_standard_validation" };
|
||||||
|
create_info.enabledLayerCount = 1;
|
||||||
|
create_info.ppEnabledLayerNames = layers;
|
||||||
|
|
||||||
// Setup the debug report callback
|
// Enable debug report extension (we need additional storage, so we duplicate the user array to add our new extension to it)
|
||||||
VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
|
const char** extensions_ext = (const char**)malloc(sizeof(const char*) * (extensions_count + 1));
|
||||||
debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
|
memcpy(extensions_ext, extensions, extensions_count * sizeof(const char*));
|
||||||
debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
|
extensions_ext[extensions_count] = "VK_EXT_debug_report";
|
||||||
debug_report_ci.pfnCallback = debug_report;
|
create_info.enabledExtensionCount = extensions_count + 1;
|
||||||
debug_report_ci.pUserData = NULL;
|
create_info.ppEnabledExtensionNames = extensions_ext;
|
||||||
err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport);
|
|
||||||
check_vk_result(err);
|
// Create Vulkan Instance
|
||||||
|
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
|
||||||
|
check_vk_result(err);
|
||||||
|
free(extensions_ext);
|
||||||
|
|
||||||
|
// Get the function pointer (required for any extensions)
|
||||||
|
auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
|
||||||
|
IM_ASSERT(vkCreateDebugReportCallbackEXT != NULL);
|
||||||
|
|
||||||
|
// Setup the debug report callback
|
||||||
|
VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
|
||||||
|
debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
|
||||||
|
debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
|
||||||
|
debug_report_ci.pfnCallback = debug_report;
|
||||||
|
debug_report_ci.pUserData = NULL;
|
||||||
|
err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport);
|
||||||
|
check_vk_result(err);
|
||||||
#else
|
#else
|
||||||
// Create Vulkan Instance without any debug feature
|
// Create Vulkan Instance without any debug feature
|
||||||
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
|
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetupVulkan(ImGui_ImplVulkan_WindowData* wd)
|
|
||||||
{
|
|
||||||
IM_ASSERT(wd->Surface != NULL);
|
|
||||||
|
|
||||||
VkResult err;
|
|
||||||
|
|
||||||
// Select GPU
|
// Select GPU
|
||||||
{
|
{
|
||||||
@ -129,34 +125,6 @@ static void SetupVulkan(ImGui_ImplVulkan_WindowData* wd)
|
|||||||
IM_ASSERT(g_QueueFamily != -1);
|
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)
|
// Create Logical Device (with 1 queue)
|
||||||
{
|
{
|
||||||
int device_extension_count = 1;
|
int device_extension_count = 1;
|
||||||
@ -178,44 +146,6 @@ static void SetupVulkan(ImGui_ImplVulkan_WindowData* wd)
|
|||||||
vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue);
|
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
|
// Create Descriptor Pool
|
||||||
{
|
{
|
||||||
VkDescriptorPoolSize pool_sizes[] =
|
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;
|
ImGui_ImplVulkan_WindowData* wd = &g_WindowData;
|
||||||
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
|
|
||||||
ImGui_ImplVulkanH_DestroyWindowData(g_Instance, g_Device, wd, g_Allocator);
|
ImGui_ImplVulkanH_DestroyWindowData(g_Instance, g_Device, wd, g_Allocator);
|
||||||
|
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
|
||||||
|
|
||||||
#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
||||||
// Remove the debug report callback
|
// Remove the debug report callback
|
||||||
@ -259,7 +220,7 @@ static void cleanup_vulkan()
|
|||||||
vkDestroyInstance(g_Instance, g_Allocator);
|
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];
|
ImGui_ImplVulkan_FrameData* fd = &wd->Frames[wd->FrameIndex];
|
||||||
VkResult err;
|
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];
|
ImGui_ImplVulkan_FrameData* fd = &wd->Frames[wd->FrameIndex];
|
||||||
VkResult err;
|
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;
|
VkResult err;
|
||||||
// If IMGUI_UNLIMITED_FRAME_RATE is defined we present the latest but one frame. Otherwise we present the latest rendered frame
|
// 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
|
#ifdef IMGUI_UNLIMITED_FRAME_RATE
|
||||||
uint32_t PresentIndex = (wd->FrameIndex + IMGUI_VK_QUEUED_FRAMES - 1) % IMGUI_VK_QUEUED_FRAMES;
|
uint32_t PresentIndex = (wd->FrameIndex + IMGUI_VK_QUEUED_FRAMES - 1) % IMGUI_VK_QUEUED_FRAMES;
|
||||||
#else
|
#else
|
||||||
uint32_t PresentIndex = g_FrameIndex;
|
uint32_t PresentIndex = wd->FrameIndex;
|
||||||
#endif // IMGUI_UNLIMITED_FRAME_RATE
|
#endif // IMGUI_UNLIMITED_FRAME_RATE
|
||||||
|
|
||||||
ImGui_ImplVulkan_FrameData* fd = &wd->Frames[PresentIndex];
|
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);
|
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
|
// Setup Vulkan
|
||||||
uint32_t sdl_extensions_count;
|
uint32_t extensions_count = 0;
|
||||||
SDL_Vulkan_GetInstanceExtensions(window, &sdl_extensions_count, NULL);
|
SDL_Vulkan_GetInstanceExtensions(window, &extensions_count, NULL);
|
||||||
const char** sdl_extensions = new const char*[sdl_extensions_count];
|
const char** extensions = new const char*[extensions_count];
|
||||||
SDL_Vulkan_GetInstanceExtensions(window, &sdl_extensions_count, sdl_extensions);
|
SDL_Vulkan_GetInstanceExtensions(window, &extensions_count, extensions);
|
||||||
CreateVulkanInstance(sdl_extensions, sdl_extensions_count);
|
SetupVulkan(extensions, extensions_count);
|
||||||
delete[] sdl_extensions;
|
delete[] extensions;
|
||||||
|
|
||||||
// Create Window Surface
|
// Create Window Surface
|
||||||
ImGui_ImplVulkan_WindowData* wd = &g_WindowData;
|
VkSurfaceKHR surface;
|
||||||
SDL_bool result = SDL_Vulkan_CreateSurface(window, g_Instance, &wd->Surface);
|
if (SDL_Vulkan_CreateSurface(window, g_Instance, &surface) == 0)
|
||||||
if (result == 0)
|
|
||||||
{
|
{
|
||||||
printf("Failed to create Vulkan surface.\n");
|
printf("Failed to create Vulkan surface.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetupVulkan(wd);
|
|
||||||
|
|
||||||
// Create Framebuffers
|
// Create Framebuffers
|
||||||
{
|
int w, h;
|
||||||
int w, h;
|
SDL_GetWindowSize(window, &w, &h);
|
||||||
SDL_GetWindowSize(window, &w, &h);
|
ImGui_ImplVulkan_WindowData* wd = &g_WindowData;
|
||||||
ImGui_ImplVulkanH_CreateOrResizeWindowData(g_PhysicalDevice, g_Device, wd, g_Allocator, w, h);
|
SetupVulkanWindowData(wd, surface, w, h);
|
||||||
}
|
|
||||||
|
|
||||||
// Setup ImGui binding
|
// Setup ImGui binding
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_MultiViewports;
|
io.ConfigFlags |= ImGuiConfigFlags_MultiViewports;
|
||||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
@ -399,8 +355,8 @@ int main(int, char**)
|
|||||||
init_info.DescriptorPool = g_DescriptorPool;
|
init_info.DescriptorPool = g_DescriptorPool;
|
||||||
init_info.Allocator = g_Allocator;
|
init_info.Allocator = g_Allocator;
|
||||||
init_info.CheckVkResultFn = check_vk_result;
|
init_info.CheckVkResultFn = check_vk_result;
|
||||||
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
|
|
||||||
ImGui_ImplSDL2_Init(window, NULL);
|
ImGui_ImplSDL2_Init(window, NULL);
|
||||||
|
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
|
||||||
|
|
||||||
// Setup style
|
// Setup style
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
@ -473,7 +429,7 @@ int main(int, char**)
|
|||||||
if (event.type == SDL_QUIT)
|
if (event.type == SDL_QUIT)
|
||||||
done = true;
|
done = true;
|
||||||
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED && event.window.windowID == SDL_GetWindowID(window))
|
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_ImplVulkan_NewFrame();
|
||||||
ImGui_ImplSDL2_NewFrame(window);
|
ImGui_ImplSDL2_NewFrame(window);
|
||||||
@ -516,10 +472,11 @@ int main(int, char**)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
|
ImGui::Render();
|
||||||
memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
|
memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
|
||||||
frame_begin(wd);
|
FrameBegin(wd);
|
||||||
ImGui_ImplVulkan_Render(wd->Frames[wd->FrameIndex].CommandBuffer);
|
ImGui_ImplVulkan_Render(wd->Frames[wd->FrameIndex].CommandBuffer);
|
||||||
frame_end(wd);
|
FrameEnd(wd);
|
||||||
|
|
||||||
ImGui::RenderAdditionalViewports();
|
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.
|
// 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.
|
// Hence we must render once and increase the FrameIndex without presenting.
|
||||||
if (swap_chain_has_at_least_one_image)
|
if (swap_chain_has_at_least_one_image)
|
||||||
frame_present(wd);
|
FramePresent(wd);
|
||||||
#else
|
#else
|
||||||
frame_present(wd);
|
FramePresent(wd);
|
||||||
#endif
|
#endif
|
||||||
swap_chain_has_at_least_one_image = true;
|
swap_chain_has_at_least_one_image = true;
|
||||||
wd->FrameIndex = (wd->FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
|
wd->FrameIndex = (wd->FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
|
||||||
@ -542,7 +499,7 @@ int main(int, char**)
|
|||||||
ImGui_ImplSDL2_Shutdown();
|
ImGui_ImplSDL2_Shutdown();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
cleanup_vulkan();
|
CleanupVulkan();
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -47,57 +47,53 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags,
|
|||||||
}
|
}
|
||||||
#endif // IMGUI_VULKAN_DEBUG_REPORT
|
#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;
|
VkResult err;
|
||||||
|
|
||||||
VkInstanceCreateInfo create_info = {};
|
|
||||||
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
|
||||||
create_info.enabledExtensionCount = extensions_count;
|
|
||||||
create_info.ppEnabledExtensionNames = extensions;
|
|
||||||
|
|
||||||
#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
|
||||||
// Enabling multiple validation layers grouped as LunarG standard validation
|
|
||||||
const char* layers[] = { "VK_LAYER_LUNARG_standard_validation" };
|
|
||||||
create_info.enabledLayerCount = 1;
|
|
||||||
create_info.ppEnabledLayerNames = layers;
|
|
||||||
|
|
||||||
// Enable debug report extension (we need additional storage, so we duplicate the user array to add our new extension to it)
|
|
||||||
const char** extensions_ext = (const char**)malloc(sizeof(const char*) * (extensions_count + 1));
|
|
||||||
memcpy(extensions_ext, extensions, extensions_count * sizeof(const char*));
|
|
||||||
extensions_ext[extensions_count] = "VK_EXT_debug_report";
|
|
||||||
create_info.enabledExtensionCount = extensions_count + 1;
|
|
||||||
create_info.ppEnabledExtensionNames = extensions_ext;
|
|
||||||
|
|
||||||
// Create Vulkan Instance
|
// Create Vulkan Instance
|
||||||
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
|
{
|
||||||
check_vk_result(err);
|
VkInstanceCreateInfo create_info = {};
|
||||||
free(extensions_ext);
|
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
|
create_info.enabledExtensionCount = extensions_count;
|
||||||
|
create_info.ppEnabledExtensionNames = extensions;
|
||||||
|
|
||||||
// Get the function pointer (required for any extensions)
|
#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
||||||
auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
|
// Enabling multiple validation layers grouped as LunarG standard validation
|
||||||
IM_ASSERT(vkCreateDebugReportCallbackEXT != NULL);
|
const char* layers[] = { "VK_LAYER_LUNARG_standard_validation" };
|
||||||
|
create_info.enabledLayerCount = 1;
|
||||||
|
create_info.ppEnabledLayerNames = layers;
|
||||||
|
|
||||||
// Setup the debug report callback
|
// Enable debug report extension (we need additional storage, so we duplicate the user array to add our new extension to it)
|
||||||
VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
|
const char** extensions_ext = (const char**)malloc(sizeof(const char*) * (extensions_count + 1));
|
||||||
debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
|
memcpy(extensions_ext, extensions, extensions_count * sizeof(const char*));
|
||||||
debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
|
extensions_ext[extensions_count] = "VK_EXT_debug_report";
|
||||||
debug_report_ci.pfnCallback = debug_report;
|
create_info.enabledExtensionCount = extensions_count + 1;
|
||||||
debug_report_ci.pUserData = NULL;
|
create_info.ppEnabledExtensionNames = extensions_ext;
|
||||||
err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport);
|
|
||||||
check_vk_result(err);
|
// Create Vulkan Instance
|
||||||
|
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
|
||||||
|
check_vk_result(err);
|
||||||
|
free(extensions_ext);
|
||||||
|
|
||||||
|
// Get the function pointer (required for any extensions)
|
||||||
|
auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
|
||||||
|
IM_ASSERT(vkCreateDebugReportCallbackEXT != NULL);
|
||||||
|
|
||||||
|
// Setup the debug report callback
|
||||||
|
VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
|
||||||
|
debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
|
||||||
|
debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
|
||||||
|
debug_report_ci.pfnCallback = debug_report;
|
||||||
|
debug_report_ci.pUserData = NULL;
|
||||||
|
err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport);
|
||||||
|
check_vk_result(err);
|
||||||
#else
|
#else
|
||||||
// Create Vulkan Instance without any debug feature
|
// Create Vulkan Instance without any debug feature
|
||||||
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
|
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetupVulkan(ImGui_ImplVulkan_WindowData* wd)
|
|
||||||
{
|
|
||||||
IM_ASSERT(wd->Surface != NULL);
|
|
||||||
|
|
||||||
VkResult err;
|
|
||||||
|
|
||||||
// Select GPU
|
// Select GPU
|
||||||
{
|
{
|
||||||
@ -132,34 +128,6 @@ static void SetupVulkan(ImGui_ImplVulkan_WindowData* wd)
|
|||||||
IM_ASSERT(g_QueueFamily != -1);
|
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)
|
// Create Logical Device (with 1 queue)
|
||||||
{
|
{
|
||||||
int device_extension_count = 1;
|
int device_extension_count = 1;
|
||||||
@ -181,44 +149,6 @@ static void SetupVulkan(ImGui_ImplVulkan_WindowData* wd)
|
|||||||
vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue);
|
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
|
// Create Descriptor Pool
|
||||||
{
|
{
|
||||||
VkDescriptorPoolSize pool_sizes[] =
|
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;
|
ImGui_ImplVulkan_WindowData* wd = &g_WindowData;
|
||||||
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
|
|
||||||
ImGui_ImplVulkanH_DestroyWindowData(g_Instance, g_Device, wd, g_Allocator);
|
ImGui_ImplVulkanH_DestroyWindowData(g_Instance, g_Device, wd, g_Allocator);
|
||||||
|
vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator);
|
||||||
|
|
||||||
#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
#ifdef IMGUI_VULKAN_DEBUG_REPORT
|
||||||
// Remove the debug report callback
|
// Remove the debug report callback
|
||||||
@ -262,7 +223,7 @@ static void cleanup_vulkan()
|
|||||||
vkDestroyInstance(g_Instance, g_Allocator);
|
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];
|
ImGui_ImplVulkan_FrameData* fd = &wd->Frames[wd->FrameIndex];
|
||||||
VkResult err;
|
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];
|
ImGui_ImplVulkan_FrameData* fd = &wd->Frames[wd->FrameIndex];
|
||||||
VkResult err;
|
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;
|
VkResult err;
|
||||||
// If IMGUI_UNLIMITED_FRAME_RATE is defined we present the latest but one frame. Otherwise we present the latest rendered frame
|
// 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
|
#ifdef IMGUI_UNLIMITED_FRAME_RATE
|
||||||
uint32_t PresentIndex = (wd->FrameIndex + IMGUI_VK_QUEUED_FRAMES - 1) % IMGUI_VK_QUEUED_FRAMES;
|
uint32_t PresentIndex = (wd->FrameIndex + IMGUI_VK_QUEUED_FRAMES - 1) % IMGUI_VK_QUEUED_FRAMES;
|
||||||
#else
|
#else
|
||||||
uint32_t PresentIndex = g_FrameIndex;
|
uint32_t PresentIndex = wd->FrameIndex;
|
||||||
#endif // IMGUI_UNLIMITED_FRAME_RATE
|
#endif // IMGUI_UNLIMITED_FRAME_RATE
|
||||||
|
|
||||||
ImGui_ImplVulkan_FrameData* fd = &wd->Frames[PresentIndex];
|
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)
|
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**)
|
int main(int, char**)
|
||||||
@ -373,26 +334,24 @@ int main(int, char**)
|
|||||||
printf("GLFW: Vulkan Not Supported\n");
|
printf("GLFW: Vulkan Not Supported\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
uint32_t glfw_extensions_count = 0;
|
uint32_t extensions_count = 0;
|
||||||
const char** glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extensions_count);
|
const char** extensions = glfwGetRequiredInstanceExtensions(&extensions_count);
|
||||||
CreateVulkanInstance(glfw_extensions, glfw_extensions_count);
|
SetupVulkan(extensions, extensions_count);
|
||||||
|
|
||||||
// Create Window Surface
|
// Create Window Surface
|
||||||
ImGui_ImplVulkan_WindowData* wd = &g_WindowData;
|
VkSurfaceKHR surface;
|
||||||
VkResult err = glfwCreateWindowSurface(g_Instance, window, g_Allocator, &wd->Surface);
|
VkResult err = glfwCreateWindowSurface(g_Instance, window, g_Allocator, &surface);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
|
|
||||||
SetupVulkan(wd);
|
|
||||||
|
|
||||||
// Create Framebuffers
|
// Create Framebuffers
|
||||||
int w, h;
|
int w, h;
|
||||||
glfwGetFramebufferSize(window, &w, &h);
|
glfwGetFramebufferSize(window, &w, &h);
|
||||||
ImGui_ImplVulkanH_CreateOrResizeWindowData(g_PhysicalDevice, g_Device, wd, g_Allocator, w, h);
|
|
||||||
glfwSetFramebufferSizeCallback(window, glfw_resize_callback);
|
glfwSetFramebufferSizeCallback(window, glfw_resize_callback);
|
||||||
|
ImGui_ImplVulkan_WindowData* wd = &g_WindowData;
|
||||||
|
SetupVulkanWindowData(wd, surface, w, h);
|
||||||
|
|
||||||
// Setup ImGui binding
|
// Setup ImGui binding
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_MultiViewports;
|
io.ConfigFlags |= ImGuiConfigFlags_MultiViewports;
|
||||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
@ -405,8 +364,8 @@ int main(int, char**)
|
|||||||
init_info.DescriptorPool = g_DescriptorPool;
|
init_info.DescriptorPool = g_DescriptorPool;
|
||||||
init_info.Allocator = g_Allocator;
|
init_info.Allocator = g_Allocator;
|
||||||
init_info.CheckVkResultFn = check_vk_result;
|
init_info.CheckVkResultFn = check_vk_result;
|
||||||
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
|
|
||||||
ImGui_ImplGlfw_InitForVulkan(window, true);
|
ImGui_ImplGlfw_InitForVulkan(window, true);
|
||||||
|
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
|
||||||
|
|
||||||
// Setup style
|
// Setup style
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
@ -513,10 +472,11 @@ int main(int, char**)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
|
ImGui::Render();
|
||||||
memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
|
memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
|
||||||
frame_begin(wd);
|
FrameBegin(wd);
|
||||||
ImGui_ImplVulkan_Render(wd->Frames[wd->FrameIndex].CommandBuffer);
|
ImGui_ImplVulkan_Render(wd->Frames[wd->FrameIndex].CommandBuffer);
|
||||||
frame_end(wd);
|
FrameEnd(wd);
|
||||||
|
|
||||||
ImGui::RenderAdditionalViewports();
|
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.
|
// 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.
|
// Hence we must render once and increase the FrameIndex without presenting.
|
||||||
if (swap_chain_has_at_least_one_image)
|
if (swap_chain_has_at_least_one_image)
|
||||||
frame_present(wd);
|
FramePresent(wd);
|
||||||
#else
|
#else
|
||||||
frame_present(wd);
|
FramePresent(wd);
|
||||||
#endif
|
#endif
|
||||||
swap_chain_has_at_least_one_image = true;
|
swap_chain_has_at_least_one_image = true;
|
||||||
wd->FrameIndex = (wd->FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
|
wd->FrameIndex = (wd->FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
|
||||||
@ -538,7 +498,7 @@ int main(int, char**)
|
|||||||
ImGui_ImplVulkan_Shutdown();
|
ImGui_ImplVulkan_Shutdown();
|
||||||
ImGui_ImplGlfw_Shutdown();
|
ImGui_ImplGlfw_Shutdown();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
cleanup_vulkan();
|
CleanupVulkan();
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user