Browse Source

Merge branch 'examples_refactor' into viewport

# Conflicts:
#	examples/directx10_example/main.cpp
#	examples/directx11_example/main.cpp
#	examples/directx12_example/main.cpp
#	examples/opengl3_example/main.cpp
#	examples/sdl_opengl2_example/main.cpp
#	examples/sdl_opengl3_example/main.cpp
#	examples/sdl_vulkan_example/main.cpp
#	examples/vulkan_example/main.cpp
#	imgui.h
omar 7 years ago
parent
commit
fc80f2b41a

+ 1 - 0
examples/imgui_impl_glfw.cpp

@@ -176,6 +176,7 @@ static void ImGui_ImplGlfw_UpdateMouse()
     io.MouseHoveredViewport = 0;
     io.MouseHoveredViewport = 0;
 
 
     // Update buttons
     // Update buttons
+    ImGuiIO& io = ImGui::GetIO();
     for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
     for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
     {
     {
         // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
         // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.

+ 88 - 17
examples/imgui_impl_vulkan.cpp

@@ -11,7 +11,8 @@
 
 
 // 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-XX-XX: Vulkan: Offset projection matrix and clipping rectangle by io.DisplayPos (which will be non-zero for multi-viewport applications).
+//  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.
 //  2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback, ImGui_ImplVulkan_Render() calls ImGui_ImplVulkan_RenderDrawData() itself.
 //  2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
 //  2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
 //  2017-05-15: Vulkan: Fix scissor offset being negative. Fix new Vulkan validation warnings. Set required depth member for buffer image copy.
 //  2017-05-15: Vulkan: Fix scissor offset being negative. Fix new Vulkan validation warnings. Set required depth member for buffer image copy.
@@ -23,13 +24,13 @@
 #include "imgui_impl_vulkan.h"
 #include "imgui_impl_vulkan.h"
 
 
 // Vulkan data
 // Vulkan data
-static VkAllocationCallbacks* g_Allocator = NULL;
-static VkPhysicalDevice       g_Gpu = VK_NULL_HANDLE;
-static VkDevice               g_Device = VK_NULL_HANDLE;
-static VkRenderPass           g_RenderPass = VK_NULL_HANDLE;
-static VkPipelineCache        g_PipelineCache = VK_NULL_HANDLE;
-static VkDescriptorPool       g_DescriptorPool = VK_NULL_HANDLE;
-static void (*g_CheckVkResult)(VkResult err) = NULL;
+static const VkAllocationCallbacks* g_Allocator = NULL;
+static VkPhysicalDevice             g_PhysicalDevice = VK_NULL_HANDLE;
+static VkDevice                     g_Device = VK_NULL_HANDLE;
+static VkRenderPass                 g_RenderPass = VK_NULL_HANDLE;
+static VkPipelineCache              g_PipelineCache = VK_NULL_HANDLE;
+static VkDescriptorPool             g_DescriptorPool = VK_NULL_HANDLE;
+static void                         (*g_CheckVkResult)(VkResult err) = NULL;
 
 
 static VkCommandBuffer        g_CommandBuffer = VK_NULL_HANDLE;
 static VkCommandBuffer        g_CommandBuffer = VK_NULL_HANDLE;
 static VkDeviceSize           g_BufferMemoryAlignment = 256;
 static VkDeviceSize           g_BufferMemoryAlignment = 256;
@@ -133,7 +134,7 @@ static uint32_t __glsl_shader_frag_spv[] =
 static uint32_t ImGui_ImplVulkan_MemoryType(VkMemoryPropertyFlags properties, uint32_t type_bits)
 static uint32_t ImGui_ImplVulkan_MemoryType(VkMemoryPropertyFlags properties, uint32_t type_bits)
 {
 {
     VkPhysicalDeviceMemoryProperties prop;
     VkPhysicalDeviceMemoryProperties prop;
-    vkGetPhysicalDeviceMemoryProperties(g_Gpu, &prop);
+    vkGetPhysicalDeviceMemoryProperties(g_PhysicalDevice, &prop);
     for (uint32_t i = 0; i < prop.memoryTypeCount; i++)
     for (uint32_t i = 0; i < prop.memoryTypeCount; i++)
         if ((prop.memoryTypes[i].propertyFlags & properties) == properties && type_bits & (1<<i))
         if ((prop.memoryTypes[i].propertyFlags & properties) == properties && type_bits & (1<<i))
             return i;
             return i;
@@ -688,15 +689,15 @@ void    ImGui_ImplVulkan_InvalidateDeviceObjects()
     if (g_Pipeline)             { vkDestroyPipeline(g_Device, g_Pipeline, g_Allocator); g_Pipeline = VK_NULL_HANDLE; }
     if (g_Pipeline)             { vkDestroyPipeline(g_Device, g_Pipeline, g_Allocator); g_Pipeline = VK_NULL_HANDLE; }
 }
 }
 
 
-bool    ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitData *init_data)
+bool    ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo *init_data)
 {
 {
-    g_Allocator = init_data->allocator;
-    g_Gpu = init_data->gpu;
-    g_Device = init_data->device;
-    g_RenderPass = init_data->render_pass;
-    g_PipelineCache = init_data->pipeline_cache;
-    g_DescriptorPool = init_data->descriptor_pool;
-    g_CheckVkResult = init_data->check_vk_result;
+    g_Allocator = init_data->Allocator;
+    g_PhysicalDevice = init_data->PhysicalDevice;
+    g_Device = init_data->Device;
+    g_RenderPass = init_data->RenderPass;
+    g_PipelineCache = init_data->PipelineCache;
+    g_DescriptorPool = init_data->DescriptorPool;
+    g_CheckVkResult = init_data->CheckVkResultFn;
 
 
     ImGui_ImplVulkan_CreateDeviceObjects();
     ImGui_ImplVulkan_CreateDeviceObjects();
     return true;
     return true;
@@ -719,3 +720,73 @@ void ImGui_ImplVulkan_Render(VkCommandBuffer command_buffer)
     g_CommandBuffer = VK_NULL_HANDLE;
     g_CommandBuffer = VK_NULL_HANDLE;
     g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
     g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES;
 }
 }
+
+//-------------------------------------------------------------------------
+// Miscellaneous Vulkan Helpers
+// (Those are currently not strictly needed by the binding, but will be once if we support multi-viewports)
+//-------------------------------------------------------------------------
+
+#include <stdlib.h> // malloc
+
+VkSurfaceFormatKHR ImGui_ImplVulkan_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space)
+{
+    IM_ASSERT(request_formats != NULL);
+    IM_ASSERT(request_formats_count > 0);
+
+    // Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation
+    // Assuming that the default behavior is without setting this bit, there is no need for separate Swapchain image and image view format
+    // Additionally several new color spaces were introduced with Vulkan Spec v1.0.40,
+    // hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used.
+    uint32_t avail_count;
+    vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &avail_count, NULL);
+    ImVector<VkSurfaceFormatKHR> avail_format;
+    avail_format.resize((int)avail_count);
+    vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface, &avail_count, avail_format.Data);
+
+    // First check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available
+    if (avail_count == 1)
+    {
+        if (avail_format[0].format == VK_FORMAT_UNDEFINED)
+        {
+            VkSurfaceFormatKHR ret;
+            ret.format = request_formats[0];
+            ret.colorSpace = request_color_space;
+            return ret;
+        }
+        else
+        {
+            // No point in searching another format
+            return avail_format[0];
+        }
+    }
+    else
+    {
+        // Request several formats, the first found will be used 
+        for (int request_i = 0; request_i < request_formats_count; request_i++)
+            for (uint32_t avail_i = 0; avail_i < avail_count; avail_i++)
+                if (avail_format[avail_i].format == request_formats[request_i] && avail_format[avail_i].colorSpace == request_color_space)
+                    return avail_format[avail_i];
+
+        // If none of the requested image formats could be found, use the first available
+        return avail_format[0];
+    }
+}
+
+VkPresentModeKHR ImGui_ImplVulkan_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count)
+{
+    IM_ASSERT(request_modes != NULL);
+    IM_ASSERT(request_modes_count > 0);
+
+    // Request a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory
+    uint32_t avail_count = 0;
+    vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &avail_count, NULL);
+    ImVector<VkPresentModeKHR> avail_modes;
+    avail_modes.resize((int)avail_count);
+    vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface, &avail_count, avail_modes.Data);
+    for (int request_i = 0; request_i < request_modes_count; request_i++)
+        for (uint32_t avail_i = 0; avail_i < avail_count; avail_i++)
+            if (request_modes[request_i] == avail_modes[avail_i])
+                return request_modes[request_i];
+
+    return VK_PRESENT_MODE_FIFO_KHR; // Always available
+}

+ 13 - 9
examples/imgui_impl_vulkan.h

@@ -13,18 +13,18 @@
 
 
 #define IMGUI_VK_QUEUED_FRAMES 2
 #define IMGUI_VK_QUEUED_FRAMES 2
 
 
-struct ImGui_ImplVulkan_InitData
+struct ImGui_ImplVulkan_InitInfo
 {
 {
-    VkAllocationCallbacks* allocator;
-    VkPhysicalDevice       gpu;
-    VkDevice               device;
-    VkRenderPass           render_pass;
-    VkPipelineCache        pipeline_cache;
-    VkDescriptorPool       descriptor_pool;
-    void (*check_vk_result)(VkResult err);
+    const VkAllocationCallbacks*    Allocator;
+    VkPhysicalDevice                PhysicalDevice;
+    VkDevice                        Device;
+    VkRenderPass                    RenderPass;
+    VkPipelineCache                 PipelineCache;
+    VkDescriptorPool                DescriptorPool;
+    void                            (*CheckVkResultFn)(VkResult err);
 };
 };
 
 
-IMGUI_API bool        ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitData *init_data);
+IMGUI_API bool        ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo *init_data);
 IMGUI_API void        ImGui_ImplVulkan_Shutdown();
 IMGUI_API void        ImGui_ImplVulkan_Shutdown();
 IMGUI_API void        ImGui_ImplVulkan_NewFrame();
 IMGUI_API void        ImGui_ImplVulkan_NewFrame();
 IMGUI_API void        ImGui_ImplVulkan_Render(VkCommandBuffer command_buffer);
 IMGUI_API void        ImGui_ImplVulkan_Render(VkCommandBuffer command_buffer);
@@ -34,3 +34,7 @@ IMGUI_API void        ImGui_ImplVulkan_InvalidateFontUploadObjects();
 IMGUI_API void        ImGui_ImplVulkan_InvalidateDeviceObjects();
 IMGUI_API void        ImGui_ImplVulkan_InvalidateDeviceObjects();
 IMGUI_API bool        ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer);
 IMGUI_API bool        ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer);
 IMGUI_API bool        ImGui_ImplVulkan_CreateDeviceObjects();
 IMGUI_API bool        ImGui_ImplVulkan_CreateDeviceObjects();
+
+// Miscellaneous Vulkan Helpers
+IMGUI_API VkSurfaceFormatKHR    ImGui_ImplVulkan_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space);
+IMGUI_API VkPresentModeKHR      ImGui_ImplVulkan_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count);

+ 1 - 0
examples/opengl3_example/main.cpp

@@ -38,6 +38,7 @@ int main(int, char**)
     io.ConfigFlags |= ImGuiConfigFlags_MultiViewports;
     io.ConfigFlags |= ImGuiConfigFlags_MultiViewports;
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;   // Enable Gamepad Controls
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;   // Enable Gamepad Controls
+
     ImGui_ImplGlfw_Init(window, true);
     ImGui_ImplGlfw_Init(window, true);
     ImGui_ImplOpenGL3_Init();
     ImGui_ImplOpenGL3_Init();
 
 

+ 71 - 133
examples/sdl_vulkan_example/main.cpp

@@ -9,25 +9,25 @@
 #include <SDL_vulkan.h>
 #include <SDL_vulkan.h>
 #include <vulkan/vulkan.h>
 #include <vulkan/vulkan.h>
 
 
+// FIXME-VULKAN: Resizing with IMGUI_UNLIMITED_FRAME_RATE triggers errors from the validation layer.
 #define IMGUI_MAX_POSSIBLE_BACK_BUFFERS 16
 #define IMGUI_MAX_POSSIBLE_BACK_BUFFERS 16
 #define IMGUI_UNLIMITED_FRAME_RATE
 #define IMGUI_UNLIMITED_FRAME_RATE
-//#ifdef _DEBUG
-//#define IMGUI_VULKAN_DEBUG_REPORT
-//#endif
+#ifdef _DEBUG
+#define IMGUI_VULKAN_DEBUG_REPORT
+#endif
 
 
 static VkAllocationCallbacks*   g_Allocator = NULL;
 static VkAllocationCallbacks*   g_Allocator = NULL;
 static VkInstance               g_Instance = VK_NULL_HANDLE;
 static VkInstance               g_Instance = VK_NULL_HANDLE;
 static VkSurfaceKHR             g_Surface = VK_NULL_HANDLE;
 static VkSurfaceKHR             g_Surface = VK_NULL_HANDLE;
-static VkPhysicalDevice         g_Gpu = VK_NULL_HANDLE;
+static VkPhysicalDevice         g_PhysicalDevice = VK_NULL_HANDLE;
 static VkDevice                 g_Device = VK_NULL_HANDLE;
 static VkDevice                 g_Device = VK_NULL_HANDLE;
 static VkSwapchainKHR           g_Swapchain = VK_NULL_HANDLE;
 static VkSwapchainKHR           g_Swapchain = VK_NULL_HANDLE;
 static VkRenderPass             g_RenderPass = VK_NULL_HANDLE;
 static VkRenderPass             g_RenderPass = VK_NULL_HANDLE;
-static uint32_t                 g_QueueFamily = 0;
+static uint32_t                 g_QueueFamily = (uint32_t)-1;
 static VkQueue                  g_Queue = VK_NULL_HANDLE;
 static VkQueue                  g_Queue = VK_NULL_HANDLE;
-static VkDebugReportCallbackEXT g_Debug_Report = VK_NULL_HANDLE;
+static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE;
 
 
 static VkSurfaceFormatKHR       g_SurfaceFormat;
 static VkSurfaceFormatKHR       g_SurfaceFormat;
-static VkImageSubresourceRange  g_ImageRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
 static VkPresentModeKHR         g_PresentMode;
 static VkPresentModeKHR         g_PresentMode;
 
 
 static VkPipelineCache          g_PipelineCache = VK_NULL_HANDLE;
 static VkPipelineCache          g_PipelineCache = VK_NULL_HANDLE;
@@ -57,24 +57,25 @@ static void check_vk_result(VkResult err)
         abort();
         abort();
 }
 }
 
 
-static void resize_vulkan(SDL_Window*, int w, int h)
+static void CreateOrResizeSwapChainAndFrameBuffer(int w, int h)
 {
 {
     VkResult err;
     VkResult err;
     VkSwapchainKHR old_swapchain = g_Swapchain;
     VkSwapchainKHR old_swapchain = g_Swapchain;
     err = vkDeviceWaitIdle(g_Device);
     err = vkDeviceWaitIdle(g_Device);
     check_vk_result(err);
     check_vk_result(err);
 
 
-    // Destroy old Framebuffer:
+    // Destroy old Framebuffer
     for (uint32_t i = 0; i < g_BackBufferCount; i++)
     for (uint32_t i = 0; i < g_BackBufferCount; i++)
+    {
         if (g_BackBufferView[i])
         if (g_BackBufferView[i])
             vkDestroyImageView(g_Device, g_BackBufferView[i], g_Allocator);
             vkDestroyImageView(g_Device, g_BackBufferView[i], g_Allocator);
-    for (uint32_t i = 0; i < g_BackBufferCount; i++)
         if (g_Framebuffer[i])
         if (g_Framebuffer[i])
             vkDestroyFramebuffer(g_Device, g_Framebuffer[i], g_Allocator);
             vkDestroyFramebuffer(g_Device, g_Framebuffer[i], g_Allocator);
+    }
     if (g_RenderPass)
     if (g_RenderPass)
         vkDestroyRenderPass(g_Device, g_RenderPass, g_Allocator);
         vkDestroyRenderPass(g_Device, g_RenderPass, g_Allocator);
 
 
-    // Create Swapchain:
+    // Create Swapchain
     {
     {
         VkSwapchainCreateInfoKHR info = {};
         VkSwapchainCreateInfoKHR info = {};
         info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
         info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
@@ -82,15 +83,15 @@ static void resize_vulkan(SDL_Window*, int w, int h)
         info.imageFormat = g_SurfaceFormat.format;
         info.imageFormat = g_SurfaceFormat.format;
         info.imageColorSpace = g_SurfaceFormat.colorSpace;
         info.imageColorSpace = g_SurfaceFormat.colorSpace;
         info.imageArrayLayers = 1;
         info.imageArrayLayers = 1;
-        info.imageUsage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
-        info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+        info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+        info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;           // Assume that graphics family == present family
         info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
         info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
         info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
         info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
         info.presentMode = g_PresentMode;
         info.presentMode = g_PresentMode;
         info.clipped = VK_TRUE;
         info.clipped = VK_TRUE;
         info.oldSwapchain = old_swapchain;
         info.oldSwapchain = old_swapchain;
         VkSurfaceCapabilitiesKHR cap;
         VkSurfaceCapabilitiesKHR cap;
-        err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_Gpu, g_Surface, &cap);
+        err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_PhysicalDevice, g_Surface, &cap);
         check_vk_result(err);
         check_vk_result(err);
         if (cap.maxImageCount > 0)
         if (cap.maxImageCount > 0)
             info.minImageCount = (cap.minImageCount + 2 < cap.maxImageCount) ? (cap.minImageCount + 2) : cap.maxImageCount;
             info.minImageCount = (cap.minImageCount + 2 < cap.maxImageCount) ? (cap.minImageCount + 2) : cap.maxImageCount;
@@ -99,17 +100,13 @@ static void resize_vulkan(SDL_Window*, int w, int h)
 
 
         if (cap.currentExtent.width == 0xffffffff)
         if (cap.currentExtent.width == 0xffffffff)
         {
         {
-            fb_width = w;
-            fb_height = h;
-            info.imageExtent.width = fb_width;
-            info.imageExtent.height = fb_height;
+            info.imageExtent.width = fb_width = w;
+            info.imageExtent.height = fb_height = h;
         }
         }
         else
         else
         {
         {
-            fb_width = cap.currentExtent.width;
-            fb_height = cap.currentExtent.height;
-            info.imageExtent.width = fb_width;
-            info.imageExtent.height = fb_height;
+            info.imageExtent.width = fb_width = cap.currentExtent.width;
+            info.imageExtent.height = fb_height = cap.currentExtent.height;
         }
         }
         err = vkCreateSwapchainKHR(g_Device, &info, g_Allocator, &g_Swapchain);
         err = vkCreateSwapchainKHR(g_Device, &info, g_Allocator, &g_Swapchain);
         check_vk_result(err);
         check_vk_result(err);
@@ -121,7 +118,7 @@ static void resize_vulkan(SDL_Window*, int w, int h)
     if (old_swapchain)
     if (old_swapchain)
         vkDestroySwapchainKHR(g_Device, old_swapchain, g_Allocator);
         vkDestroySwapchainKHR(g_Device, old_swapchain, g_Allocator);
 
 
-    // Create the Render Pass:
+    // Create the Render Pass
     {
     {
         VkAttachmentDescription attachment = {};
         VkAttachmentDescription attachment = {};
         attachment.format = g_SurfaceFormat.format;
         attachment.format = g_SurfaceFormat.format;
@@ -159,7 +156,8 @@ static void resize_vulkan(SDL_Window*, int w, int h)
         info.components.g = VK_COMPONENT_SWIZZLE_G;
         info.components.g = VK_COMPONENT_SWIZZLE_G;
         info.components.b = VK_COMPONENT_SWIZZLE_B;
         info.components.b = VK_COMPONENT_SWIZZLE_B;
         info.components.a = VK_COMPONENT_SWIZZLE_A;
         info.components.a = VK_COMPONENT_SWIZZLE_A;
-        info.subresourceRange = g_ImageRange;
+        VkImageSubresourceRange image_range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
+        info.subresourceRange = image_range;
         for (uint32_t i = 0; i < g_BackBufferCount; i++)
         for (uint32_t i = 0; i < g_BackBufferCount; i++)
         {
         {
             info.image = g_BackBuffer[i];
             info.image = g_BackBuffer[i];
@@ -168,7 +166,7 @@ static void resize_vulkan(SDL_Window*, int w, int h)
         }
         }
     }
     }
 
 
-    // Create Framebuffer:
+    // Create Framebuffer
     {
     {
         VkImageView attachment[1];
         VkImageView attachment[1];
         VkFramebufferCreateInfo info = {};
         VkFramebufferCreateInfo info = {};
@@ -189,9 +187,9 @@ static void resize_vulkan(SDL_Window*, int w, int h)
 }
 }
 
 
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
-static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(
-    VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData)
+static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData)
 {
 {
+    (void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguemnts
     printf("[vulkan] ObjectType: %i\nMessage: %s\n\n", objectType, pMessage);
     printf("[vulkan] ObjectType: %i\nMessage: %s\n\n", objectType, pMessage);
     return VK_FALSE;
     return VK_FALSE;
 }
 }
@@ -209,38 +207,36 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e
         create_info.ppEnabledExtensionNames = extensions;
         create_info.ppEnabledExtensionNames = extensions;
 
 
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
-        // enabling multiple validation layers grouped as lunarg standard validation
+        // Enabling multiple validation layers grouped as LunarG standard validation
         const char* layers[] = { "VK_LAYER_LUNARG_standard_validation" };
         const char* layers[] = { "VK_LAYER_LUNARG_standard_validation" };
         create_info.enabledLayerCount = 1;
         create_info.enabledLayerCount = 1;
         create_info.ppEnabledLayerNames = layers;
         create_info.ppEnabledLayerNames = layers;
 
 
-        // need additional storage for char pointer to debug report extension
-        const char** extensions = (const char**)malloc(sizeof(const char*) * (extensions_count + 1));
-        for (size_t i = 0; i < extensions_count; i++)
-            extensions[i] = extensions[i];
-        extensions[extensions_count] = "VK_EXT_debug_report";
+        // 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.enabledExtensionCount = extensions_count + 1;
-        create_info.ppEnabledExtensionNames = extensions;
+        create_info.ppEnabledExtensionNames = extensions_ext;
 #endif // IMGUI_VULKAN_DEBUG_REPORT
 #endif // IMGUI_VULKAN_DEBUG_REPORT
 
 
         err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
         err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
         check_vk_result(err);
         check_vk_result(err);
 
 
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
-        free(extensions);
+        free(extensions_ext);
+
+        // Get the function pointer (required for any extensions)
+        auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
+        IM_ASSERT(vkCreateDebugReportCallbackEXT != NULL);
 
 
-        // create the debug report callback
+        // Setup the debug report callback
         VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
         VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
         debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
         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.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.pfnCallback = debug_report;
         debug_report_ci.pUserData = NULL;
         debug_report_ci.pUserData = NULL;
-
-        // get the proc address of the function pointer, required for used extensions
-        PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT =
-            (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
-
-        err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_Debug_Report);
+        err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport);
         check_vk_result(err);
         check_vk_result(err);
 #endif // IMGUI_VULKAN_DEBUG_REPORT
 #endif // IMGUI_VULKAN_DEBUG_REPORT
     }
     }
@@ -255,7 +251,7 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e
         }
         }
     }
     }
 
 
-    // Get GPU
+    // Select GPU
     {
     {
         uint32_t gpu_count;
         uint32_t gpu_count;
         err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL);
         err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL);
@@ -268,31 +264,30 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e
         // If a number >1 of GPUs got reported, you should find the best fit GPU for your purpose
         // If a number >1 of GPUs got reported, you should find the best fit GPU for your purpose
         // e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc.
         // e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc.
         // for sake of simplicity we'll just take the first one, assuming it has a graphics queue family.
         // for sake of simplicity we'll just take the first one, assuming it has a graphics queue family.
-        g_Gpu = gpus[0];
+        g_PhysicalDevice = gpus[0];
         free(gpus);
         free(gpus);
     }
     }
 
 
-    // Get queue
+    // Select graphics queue family
     {
     {
         uint32_t count;
         uint32_t count;
-        vkGetPhysicalDeviceQueueFamilyProperties(g_Gpu, &count, NULL);
+        vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, NULL);
         VkQueueFamilyProperties* queues = (VkQueueFamilyProperties*)malloc(sizeof(VkQueueFamilyProperties) * count);
         VkQueueFamilyProperties* queues = (VkQueueFamilyProperties*)malloc(sizeof(VkQueueFamilyProperties) * count);
-        vkGetPhysicalDeviceQueueFamilyProperties(g_Gpu, &count, queues);
+        vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, queues);
         for (uint32_t i = 0; i < count; i++)
         for (uint32_t i = 0; i < count; i++)
-        {
             if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
             if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
             {
             {
                 g_QueueFamily = i;
                 g_QueueFamily = i;
                 break;
                 break;
             }
             }
-        }
         free(queues);
         free(queues);
+        IM_ASSERT(g_QueueFamily != -1);
     }
     }
 
 
     // Check for WSI support
     // Check for WSI support
     {
     {
         VkBool32 res;
         VkBool32 res;
-        vkGetPhysicalDeviceSurfaceSupportKHR(g_Gpu, g_QueueFamily, g_Surface, &res);
+        vkGetPhysicalDeviceSurfaceSupportKHR(g_PhysicalDevice, g_QueueFamily, g_Surface, &res);
         if (res != VK_TRUE)
         if (res != VK_TRUE)
         {
         {
             fprintf(stderr, "Error no WSI support on physical device 0\n");
             fprintf(stderr, "Error no WSI support on physical device 0\n");
@@ -302,93 +297,32 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e
 
 
     // Get Surface Format
     // Get Surface Format
     {
     {
-        // Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation
-        // Assuming that the default behavior is without setting this bit, there is no need for separate Spawchain image and image view format
-        // additionally several new color spaces were introduced with Vulkan Spec v1.0.40
-        // hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used
-        uint32_t count;
-        vkGetPhysicalDeviceSurfaceFormatsKHR(g_Gpu, g_Surface, &count, NULL);
-        VkSurfaceFormatKHR *formats = (VkSurfaceFormatKHR*)malloc(sizeof(VkSurfaceFormatKHR) * count);
-        vkGetPhysicalDeviceSurfaceFormatsKHR(g_Gpu, g_Surface, &count, formats);
-
-        // first check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available
-        if (count == 1)
-        {
-            if (formats[0].format == VK_FORMAT_UNDEFINED)
-            {
-                g_SurfaceFormat.format = VK_FORMAT_B8G8R8A8_UNORM;
-                g_SurfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
-            }
-            else
-            {   // no point in searching another format
-                g_SurfaceFormat = formats[0];
-            }
-        }
-        else
-        {
-            // request several formats, the first found will be used 
-            VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
-            VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
-            bool requestedFound = false;
-            for (size_t i = 0; i < sizeof(requestSurfaceImageFormat) / sizeof(requestSurfaceImageFormat[0]); i++)
-            {
-                if (requestedFound)
-                    break;
-                for (uint32_t j = 0; j < count; j++)
-                {
-                    if (formats[j].format == requestSurfaceImageFormat[i] && formats[j].colorSpace == requestSurfaceColorSpace)
-                    {
-                        g_SurfaceFormat = formats[j];
-                        requestedFound = true;
-                    }
-                }
-            }
-
-            // if none of the requested image formats could be found, use the first available
-            if (!requestedFound)
-                g_SurfaceFormat = formats[0];
-        }
-        free(formats);
+        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;
+        g_SurfaceFormat = ImGui_ImplVulkan_SelectSurfaceFormat(g_PhysicalDevice, g_Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace);
     }
     }
 
 
 
 
     // Get Present Mode
     // Get Present Mode
     {
     {
-        // Requst a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory
 #ifdef IMGUI_UNLIMITED_FRAME_RATE
 #ifdef IMGUI_UNLIMITED_FRAME_RATE
-        g_PresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
+        VkPresentModeKHR present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR;
 #else
 #else
-        g_PresentMode = VK_PRESENT_MODE_FIFO_KHR;
+        VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR;
 #endif
 #endif
-        uint32_t count = 0;
-        vkGetPhysicalDeviceSurfacePresentModesKHR(g_Gpu, g_Surface, &count, NULL);
-        VkPresentModeKHR* presentModes = (VkPresentModeKHR*)malloc(sizeof(VkQueueFamilyProperties) * count);
-        vkGetPhysicalDeviceSurfacePresentModesKHR(g_Gpu, g_Surface, &count, presentModes);
-        bool presentModeAvailable = false;
-        for (size_t i = 0; i < count; i++)
-        {
-            if (presentModes[i] == g_PresentMode)
-            {
-                presentModeAvailable = true;
-                break;
-            }
-        }
-        if (!presentModeAvailable)
-            g_PresentMode = VK_PRESENT_MODE_FIFO_KHR;   // always available
+        g_PresentMode = ImGui_ImplVulkan_SelectPresentMode(g_PhysicalDevice, g_Surface, &present_mode, 1);
     }
     }
 
 
 
 
-    // Create Logical Device
+    // Create Logical Device (with 1 queue)
     {
     {
         int device_extension_count = 1;
         int device_extension_count = 1;
         const char* device_extensions[] = { "VK_KHR_swapchain" };
         const char* device_extensions[] = { "VK_KHR_swapchain" };
-        const uint32_t queue_index = 0;
-        const uint32_t queue_count = 1;
         const float queue_priority[] = { 1.0f };
         const float queue_priority[] = { 1.0f };
         VkDeviceQueueCreateInfo queue_info[1] = {};
         VkDeviceQueueCreateInfo queue_info[1] = {};
         queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
         queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
         queue_info[0].queueFamilyIndex = g_QueueFamily;
         queue_info[0].queueFamilyIndex = g_QueueFamily;
-        queue_info[0].queueCount = queue_count;
+        queue_info[0].queueCount = 1;
         queue_info[0].pQueuePriorities = queue_priority;
         queue_info[0].pQueuePriorities = queue_priority;
         VkDeviceCreateInfo create_info = {};
         VkDeviceCreateInfo create_info = {};
         create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
         create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
@@ -396,18 +330,20 @@ static void setup_vulkan(SDL_Window* window, const char** extensions, uint32_t e
         create_info.pQueueCreateInfos = queue_info;
         create_info.pQueueCreateInfos = queue_info;
         create_info.enabledExtensionCount = device_extension_count;
         create_info.enabledExtensionCount = device_extension_count;
         create_info.ppEnabledExtensionNames = device_extensions;
         create_info.ppEnabledExtensionNames = device_extensions;
-        err = vkCreateDevice(g_Gpu, &create_info, g_Allocator, &g_Device);
+        err = vkCreateDevice(g_PhysicalDevice, &create_info, g_Allocator, &g_Device);
         check_vk_result(err);
         check_vk_result(err);
-        vkGetDeviceQueue(g_Device, g_QueueFamily, queue_index, &g_Queue);
+        vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue);
     }
     }
 
 
+
     // Create Framebuffers
     // Create Framebuffers
     {
     {
         int w, h;
         int w, h;
         SDL_GetWindowSize(window, &w, &h);
         SDL_GetWindowSize(window, &w, &h);
-        resize_vulkan(window, w, h);
+        CreateOrResizeSwapChainAndFrameBuffer(w, h);
     }
     }
 
 
+
     // Create Command Buffers
     // Create Command Buffers
     for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++)
     for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++)
     {
     {
@@ -493,9 +429,9 @@ static void cleanup_vulkan()
     vkDestroySurfaceKHR(g_Instance, g_Surface, g_Allocator);
     vkDestroySurfaceKHR(g_Instance, g_Surface, g_Allocator);
 
 
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
-    // get the proc address of the function pointer, required for used extensions
+    // Remove the debug report callback
     auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT");
     auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT");
-    vkDestroyDebugReportCallbackEXT(g_Instance, g_Debug_Report, g_Allocator);
+    vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator);
 #endif // IMGUI_VULKAN_DEBUG_REPORT
 #endif // IMGUI_VULKAN_DEBUG_REPORT
 
 
     vkDestroyDevice(g_Device, g_Allocator);
     vkDestroyDevice(g_Device, g_Allocator);
@@ -613,18 +549,18 @@ int main(int, char**)
     // Setup ImGui binding
     // Setup ImGui binding
     ImGui::CreateContext();
     ImGui::CreateContext();
 
 
-    ImGui_ImplVulkan_InitData init_data = {};
-    init_data.allocator = g_Allocator;
-    init_data.gpu = g_Gpu;
-    init_data.device = g_Device;
-    init_data.render_pass = g_RenderPass;
-    init_data.pipeline_cache = g_PipelineCache;
-    init_data.descriptor_pool = g_DescriptorPool;
-    init_data.check_vk_result = check_vk_result;
+    ImGui_ImplVulkan_InitInfo init_info = {};
+    init_info.Allocator = g_Allocator;
+    init_info.PhysicalDevice = g_PhysicalDevice;
+    init_info.Device = g_Device;
+    init_info.RenderPass = g_RenderPass;
+    init_info.PipelineCache = g_PipelineCache;
+    init_info.DescriptorPool = g_DescriptorPool;
+    init_info.CheckVkResultFn = check_vk_result;
 
 
     ImGuiIO& io = ImGui::GetIO(); (void)io;
     ImGuiIO& io = ImGui::GetIO(); (void)io;
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls
-    ImGui_ImplVulkan_Init(&init_data);
+    ImGui_ImplVulkan_Init(&init_info);
     ImGui_ImplSDL2_Init(window, NULL);
     ImGui_ImplSDL2_Init(window, NULL);
 
 
     // Setup style
     // Setup style
@@ -703,6 +639,8 @@ int main(int, char**)
             ImGui_ImplSDL2_ProcessEvent(&event);
             ImGui_ImplSDL2_ProcessEvent(&event);
             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)) 
+                CreateOrResizeSwapChainAndFrameBuffer((int)event.window.data1, (int)event.window.data2);
         }
         }
         ImGui_ImplVulkan_NewFrame();
         ImGui_ImplVulkan_NewFrame();
         ImGui_ImplSDL2_NewFrame(window);
         ImGui_ImplSDL2_NewFrame(window);

+ 77 - 134
examples/vulkan_example/main.cpp

@@ -12,25 +12,25 @@
 #include <GLFW/glfw3.h>
 #include <GLFW/glfw3.h>
 #include <vulkan/vulkan.h>
 #include <vulkan/vulkan.h>
 
 
+// FIXME-VULKAN: Resizing with IMGUI_UNLIMITED_FRAME_RATE triggers errors from the validation layer.
 #define IMGUI_MAX_POSSIBLE_BACK_BUFFERS 16
 #define IMGUI_MAX_POSSIBLE_BACK_BUFFERS 16
 #define IMGUI_UNLIMITED_FRAME_RATE
 #define IMGUI_UNLIMITED_FRAME_RATE
-//#ifdef _DEBUG
-//#define IMGUI_VULKAN_DEBUG_REPORT
-//#endif
+#ifdef _DEBUG
+#define IMGUI_VULKAN_DEBUG_REPORT
+#endif
 
 
 static VkAllocationCallbacks*   g_Allocator = NULL;
 static VkAllocationCallbacks*   g_Allocator = NULL;
 static VkInstance               g_Instance = VK_NULL_HANDLE;
 static VkInstance               g_Instance = VK_NULL_HANDLE;
 static VkSurfaceKHR             g_Surface = VK_NULL_HANDLE;
 static VkSurfaceKHR             g_Surface = VK_NULL_HANDLE;
-static VkPhysicalDevice         g_Gpu = VK_NULL_HANDLE;
+static VkPhysicalDevice         g_PhysicalDevice = VK_NULL_HANDLE;
 static VkDevice                 g_Device = VK_NULL_HANDLE;
 static VkDevice                 g_Device = VK_NULL_HANDLE;
 static VkSwapchainKHR           g_Swapchain = VK_NULL_HANDLE;
 static VkSwapchainKHR           g_Swapchain = VK_NULL_HANDLE;
 static VkRenderPass             g_RenderPass = VK_NULL_HANDLE;
 static VkRenderPass             g_RenderPass = VK_NULL_HANDLE;
-static uint32_t                 g_QueueFamily = 0;
+static uint32_t                 g_QueueFamily = (uint32_t)-1;
 static VkQueue                  g_Queue = VK_NULL_HANDLE;
 static VkQueue                  g_Queue = VK_NULL_HANDLE;
-static VkDebugReportCallbackEXT g_Debug_Report = VK_NULL_HANDLE;
+static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE;
 
 
 static VkSurfaceFormatKHR       g_SurfaceFormat;
 static VkSurfaceFormatKHR       g_SurfaceFormat;
-static VkImageSubresourceRange  g_ImageRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
 static VkPresentModeKHR         g_PresentMode;
 static VkPresentModeKHR         g_PresentMode;
 
 
 static VkPipelineCache          g_PipelineCache = VK_NULL_HANDLE;
 static VkPipelineCache          g_PipelineCache = VK_NULL_HANDLE;
@@ -60,24 +60,25 @@ static void check_vk_result(VkResult err)
         abort();
         abort();
 }
 }
 
 
-static void resize_vulkan(GLFWwindow*, int w, int h)
+static void CreateOrResizeSwapChainAndFrameBuffer(int w, int h)
 {
 {
     VkResult err;
     VkResult err;
     VkSwapchainKHR old_swapchain = g_Swapchain;
     VkSwapchainKHR old_swapchain = g_Swapchain;
     err = vkDeviceWaitIdle(g_Device);
     err = vkDeviceWaitIdle(g_Device);
     check_vk_result(err);
     check_vk_result(err);
 
 
-    // Destroy old Framebuffer:
+    // Destroy old Framebuffer
     for (uint32_t i = 0; i < g_BackBufferCount; i++)
     for (uint32_t i = 0; i < g_BackBufferCount; i++)
+    {
         if (g_BackBufferView[i])
         if (g_BackBufferView[i])
             vkDestroyImageView(g_Device, g_BackBufferView[i], g_Allocator);
             vkDestroyImageView(g_Device, g_BackBufferView[i], g_Allocator);
-    for (uint32_t i = 0; i < g_BackBufferCount; i++)
         if (g_Framebuffer[i])
         if (g_Framebuffer[i])
             vkDestroyFramebuffer(g_Device, g_Framebuffer[i], g_Allocator);
             vkDestroyFramebuffer(g_Device, g_Framebuffer[i], g_Allocator);
+    }
     if (g_RenderPass)
     if (g_RenderPass)
         vkDestroyRenderPass(g_Device, g_RenderPass, g_Allocator);
         vkDestroyRenderPass(g_Device, g_RenderPass, g_Allocator);
 
 
-    // Create Swapchain:
+    // Create Swapchain
     {
     {
         VkSwapchainCreateInfoKHR info = {};
         VkSwapchainCreateInfoKHR info = {};
         info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
         info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
@@ -85,15 +86,15 @@ static void resize_vulkan(GLFWwindow*, int w, int h)
         info.imageFormat = g_SurfaceFormat.format;
         info.imageFormat = g_SurfaceFormat.format;
         info.imageColorSpace = g_SurfaceFormat.colorSpace;
         info.imageColorSpace = g_SurfaceFormat.colorSpace;
         info.imageArrayLayers = 1;
         info.imageArrayLayers = 1;
-        info.imageUsage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
-        info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+        info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+        info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;           // Assume that graphics family == present family
         info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
         info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
         info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
         info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
         info.presentMode = g_PresentMode;
         info.presentMode = g_PresentMode;
         info.clipped = VK_TRUE;
         info.clipped = VK_TRUE;
         info.oldSwapchain = old_swapchain;
         info.oldSwapchain = old_swapchain;
         VkSurfaceCapabilitiesKHR cap;
         VkSurfaceCapabilitiesKHR cap;
-        err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_Gpu, g_Surface, &cap);
+        err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_PhysicalDevice, g_Surface, &cap);
         check_vk_result(err);
         check_vk_result(err);
         if (cap.maxImageCount > 0)
         if (cap.maxImageCount > 0)
             info.minImageCount = (cap.minImageCount + 2 < cap.maxImageCount) ? (cap.minImageCount + 2) : cap.maxImageCount;
             info.minImageCount = (cap.minImageCount + 2 < cap.maxImageCount) ? (cap.minImageCount + 2) : cap.maxImageCount;
@@ -102,17 +103,13 @@ static void resize_vulkan(GLFWwindow*, int w, int h)
 
 
         if (cap.currentExtent.width == 0xffffffff)
         if (cap.currentExtent.width == 0xffffffff)
         {
         {
-            fb_width = w;
-            fb_height = h;
-            info.imageExtent.width = fb_width;
-            info.imageExtent.height = fb_height;
+            info.imageExtent.width = fb_width = w;
+            info.imageExtent.height = fb_height = h;
         }
         }
         else
         else
         {
         {
-            fb_width = cap.currentExtent.width;
-            fb_height = cap.currentExtent.height;
-            info.imageExtent.width = fb_width;
-            info.imageExtent.height = fb_height;
+            info.imageExtent.width = fb_width = cap.currentExtent.width;
+            info.imageExtent.height = fb_height = cap.currentExtent.height;
         }
         }
         err = vkCreateSwapchainKHR(g_Device, &info, g_Allocator, &g_Swapchain);
         err = vkCreateSwapchainKHR(g_Device, &info, g_Allocator, &g_Swapchain);
         check_vk_result(err);
         check_vk_result(err);
@@ -124,7 +121,7 @@ static void resize_vulkan(GLFWwindow*, int w, int h)
     if (old_swapchain)
     if (old_swapchain)
         vkDestroySwapchainKHR(g_Device, old_swapchain, g_Allocator);
         vkDestroySwapchainKHR(g_Device, old_swapchain, g_Allocator);
 
 
-    // Create the Render Pass:
+    // Create the Render Pass
     {
     {
         VkAttachmentDescription attachment = {};
         VkAttachmentDescription attachment = {};
         attachment.format = g_SurfaceFormat.format;
         attachment.format = g_SurfaceFormat.format;
@@ -162,7 +159,8 @@ static void resize_vulkan(GLFWwindow*, int w, int h)
         info.components.g = VK_COMPONENT_SWIZZLE_G;
         info.components.g = VK_COMPONENT_SWIZZLE_G;
         info.components.b = VK_COMPONENT_SWIZZLE_B;
         info.components.b = VK_COMPONENT_SWIZZLE_B;
         info.components.a = VK_COMPONENT_SWIZZLE_A;
         info.components.a = VK_COMPONENT_SWIZZLE_A;
-        info.subresourceRange = g_ImageRange;
+        VkImageSubresourceRange image_range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 };
+        info.subresourceRange = image_range;
         for (uint32_t i = 0; i < g_BackBufferCount; i++)
         for (uint32_t i = 0; i < g_BackBufferCount; i++)
         {
         {
             info.image = g_BackBuffer[i];
             info.image = g_BackBuffer[i];
@@ -171,7 +169,7 @@ static void resize_vulkan(GLFWwindow*, int w, int h)
         }
         }
     }
     }
 
 
-    // Create Framebuffer:
+    // Create Framebuffer
     {
     {
         VkImageView attachment[1];
         VkImageView attachment[1];
         VkFramebufferCreateInfo info = {};
         VkFramebufferCreateInfo info = {};
@@ -191,10 +189,15 @@ static void resize_vulkan(GLFWwindow*, int w, int h)
     }
     }
 }
 }
 
 
+static void GlfwResizeCallback(GLFWwindow*, int w, int h)
+{
+    CreateOrResizeSwapChainAndFrameBuffer(w, h);
+}
+
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
-static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(
-    VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData)
+static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData)
 {
 {
+    (void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguemnts
     printf("[vulkan] ObjectType: %i\nMessage: %s\n\n", objectType, pMessage);
     printf("[vulkan] ObjectType: %i\nMessage: %s\n\n", objectType, pMessage);
     return VK_FALSE;
     return VK_FALSE;
 }
 }
@@ -212,38 +215,36 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e
         create_info.ppEnabledExtensionNames = extensions;
         create_info.ppEnabledExtensionNames = extensions;
 
 
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
-        // enabling multiple validation layers grouped as lunarg standard validation
+        // Enabling multiple validation layers grouped as LunarG standard validation
         const char* layers[] = { "VK_LAYER_LUNARG_standard_validation" };
         const char* layers[] = { "VK_LAYER_LUNARG_standard_validation" };
         create_info.enabledLayerCount = 1;
         create_info.enabledLayerCount = 1;
         create_info.ppEnabledLayerNames = layers;
         create_info.ppEnabledLayerNames = layers;
 
 
-        // need additional storage for char pointer to debug report extension
-        const char** extensions = (const char**)malloc(sizeof(const char*) * (extensions_count + 1));
-        for (size_t i = 0; i < extensions_count; i++)
-            extensions[i] = extensions[i];
-        extensions[extensions_count] = "VK_EXT_debug_report";
+        // 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.enabledExtensionCount = extensions_count + 1;
-        create_info.ppEnabledExtensionNames = extensions;
+        create_info.ppEnabledExtensionNames = extensions_ext;
 #endif // IMGUI_VULKAN_DEBUG_REPORT
 #endif // IMGUI_VULKAN_DEBUG_REPORT
 
 
         err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
         err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
         check_vk_result(err);
         check_vk_result(err);
 
 
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
-        free(extensions);
+        free(extensions_ext);
+
+        // Get the function pointer (required for any extensions)
+        auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
+        IM_ASSERT(vkCreateDebugReportCallbackEXT != NULL);
 
 
-        // create the debug report callback
+        // Setup the debug report callback
         VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
         VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
         debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
         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.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.pfnCallback = debug_report;
         debug_report_ci.pUserData = NULL;
         debug_report_ci.pUserData = NULL;
-        
-        // get the proc address of the function pointer, required for used extensions
-        PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT = 
-            (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
-
-        err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_Debug_Report);
+        err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport);
         check_vk_result(err);
         check_vk_result(err);
 #endif // IMGUI_VULKAN_DEBUG_REPORT
 #endif // IMGUI_VULKAN_DEBUG_REPORT
     }
     }
@@ -254,7 +255,7 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e
         check_vk_result(err);
         check_vk_result(err);
     }
     }
 
 
-    // Get GPU
+    // Select GPU
     {
     {
         uint32_t gpu_count;
         uint32_t gpu_count;
         err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL);
         err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, NULL);
@@ -267,31 +268,30 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e
         // If a number >1 of GPUs got reported, you should find the best fit GPU for your purpose
         // If a number >1 of GPUs got reported, you should find the best fit GPU for your purpose
         // e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc.
         // e.g. VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU if available, or with the greatest memory available, etc.
         // for sake of simplicity we'll just take the first one, assuming it has a graphics queue family.
         // for sake of simplicity we'll just take the first one, assuming it has a graphics queue family.
-        g_Gpu = gpus[0];
+        g_PhysicalDevice = gpus[0];
         free(gpus);
         free(gpus);
     }
     }
 
 
-    // Get queue
+    // Select graphics queue family
     {
     {
         uint32_t count;
         uint32_t count;
-        vkGetPhysicalDeviceQueueFamilyProperties(g_Gpu, &count, NULL);
+        vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, NULL);
         VkQueueFamilyProperties* queues = (VkQueueFamilyProperties*)malloc(sizeof(VkQueueFamilyProperties) * count);
         VkQueueFamilyProperties* queues = (VkQueueFamilyProperties*)malloc(sizeof(VkQueueFamilyProperties) * count);
-        vkGetPhysicalDeviceQueueFamilyProperties(g_Gpu, &count, queues);
+        vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, queues);
         for (uint32_t i = 0; i < count; i++)
         for (uint32_t i = 0; i < count; i++)
-        {
             if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
             if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
             {
             {
                 g_QueueFamily = i;
                 g_QueueFamily = i;
                 break;
                 break;
             }
             }
-        }
         free(queues);
         free(queues);
+        IM_ASSERT(g_QueueFamily != -1);
     }
     }
 
 
     // Check for WSI support
     // Check for WSI support
     {
     {
         VkBool32 res;
         VkBool32 res;
-        vkGetPhysicalDeviceSurfaceSupportKHR(g_Gpu, g_QueueFamily, g_Surface, &res);
+        vkGetPhysicalDeviceSurfaceSupportKHR(g_PhysicalDevice, g_QueueFamily, g_Surface, &res);
         if (res != VK_TRUE)
         if (res != VK_TRUE)
         {
         {
             fprintf(stderr, "Error no WSI support on physical device 0\n");
             fprintf(stderr, "Error no WSI support on physical device 0\n");
@@ -299,95 +299,35 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e
         }
         }
     }
     }
 
 
+
     // Get Surface Format
     // Get Surface Format
     {
     {
-        // Per Spec Format and View Format are expected to be the same unless VK_IMAGE_CREATE_MUTABLE_BIT was set at image creation
-        // Assuming that the default behavior is without setting this bit, there is no need for separate Spawchain image and image view format
-        // additionally several new color spaces were introduced with Vulkan Spec v1.0.40
-        // hence we must make sure that a format with the mostly available color space, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, is found and used
-        uint32_t count;
-        vkGetPhysicalDeviceSurfaceFormatsKHR(g_Gpu, g_Surface, &count, NULL);
-        VkSurfaceFormatKHR *formats = (VkSurfaceFormatKHR*)malloc(sizeof(VkSurfaceFormatKHR) * count);
-        vkGetPhysicalDeviceSurfaceFormatsKHR(g_Gpu, g_Surface, &count, formats);
-
-        // first check if only one format, VK_FORMAT_UNDEFINED, is available, which would imply that any format is available
-        if (count == 1)
-        {
-            if (formats[0].format == VK_FORMAT_UNDEFINED)
-            {
-                g_SurfaceFormat.format = VK_FORMAT_B8G8R8A8_UNORM;
-                g_SurfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
-            }
-            else
-            {   // no point in searching another format
-                g_SurfaceFormat = formats[0];
-            }
-        }
-        else
-        {
-            // request several formats, the first found will be used 
-            VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
-            VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
-            bool requestedFound = false;
-            for (size_t i = 0; i < sizeof(requestSurfaceImageFormat) / sizeof(requestSurfaceImageFormat[0]); i++)
-            {
-                if (requestedFound)
-                    break;
-                for (uint32_t j = 0; j < count; j++)
-                {
-                    if (formats[j].format == requestSurfaceImageFormat[i] && formats[j].colorSpace == requestSurfaceColorSpace)
-                    {
-                        g_SurfaceFormat = formats[j];
-                        requestedFound = true;
-                    }
-                }
-            }
-
-            // if none of the requested image formats could be found, use the first available
-            if (!requestedFound)
-                g_SurfaceFormat = formats[0];
-        }
-        free(formats);
+        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;
+        g_SurfaceFormat = ImGui_ImplVulkan_SelectSurfaceFormat(g_PhysicalDevice, g_Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace);
     }
     }
 
 
 
 
     // Get Present Mode
     // Get Present Mode
     {
     {
-        // Requst a certain mode and confirm that it is available. If not use VK_PRESENT_MODE_FIFO_KHR which is mandatory
 #ifdef IMGUI_UNLIMITED_FRAME_RATE
 #ifdef IMGUI_UNLIMITED_FRAME_RATE
-        g_PresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
+        VkPresentModeKHR present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR;
 #else
 #else
-        g_PresentMode = VK_PRESENT_MODE_FIFO_KHR;
+        VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR;
 #endif
 #endif
-        uint32_t count = 0;
-        vkGetPhysicalDeviceSurfacePresentModesKHR(g_Gpu, g_Surface, &count, NULL);
-        VkPresentModeKHR* presentModes = (VkPresentModeKHR*)malloc(sizeof(VkQueueFamilyProperties) * count);
-        vkGetPhysicalDeviceSurfacePresentModesKHR(g_Gpu, g_Surface, &count, presentModes);
-        bool presentModeAvailable = false;
-        for (size_t i = 0; i < count; i++) 
-        {
-            if (presentModes[i] == g_PresentMode)
-            {
-                presentModeAvailable = true;
-                break;
-            }
-        }
-        if (!presentModeAvailable)
-            g_PresentMode = VK_PRESENT_MODE_FIFO_KHR;   // always available
+        g_PresentMode = ImGui_ImplVulkan_SelectPresentMode(g_PhysicalDevice, g_Surface, &present_mode, 1);
     }
     }
 
 
 
 
-    // Create Logical Device
+    // Create Logical Device (with 1 queue)
     {
     {
         int device_extension_count = 1;
         int device_extension_count = 1;
         const char* device_extensions[] = { "VK_KHR_swapchain" };
         const char* device_extensions[] = { "VK_KHR_swapchain" };
-        const uint32_t queue_index = 0;
-        const uint32_t queue_count = 1;
         const float queue_priority[] = { 1.0f };
         const float queue_priority[] = { 1.0f };
         VkDeviceQueueCreateInfo queue_info[1] = {};
         VkDeviceQueueCreateInfo queue_info[1] = {};
         queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
         queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
         queue_info[0].queueFamilyIndex = g_QueueFamily;
         queue_info[0].queueFamilyIndex = g_QueueFamily;
-        queue_info[0].queueCount = queue_count;
+        queue_info[0].queueCount = 1;
         queue_info[0].pQueuePriorities = queue_priority;
         queue_info[0].pQueuePriorities = queue_priority;
         VkDeviceCreateInfo create_info = {};
         VkDeviceCreateInfo create_info = {};
         create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
         create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
@@ -395,19 +335,21 @@ static void setup_vulkan(GLFWwindow* window, const char** extensions, uint32_t e
         create_info.pQueueCreateInfos = queue_info;
         create_info.pQueueCreateInfos = queue_info;
         create_info.enabledExtensionCount = device_extension_count;
         create_info.enabledExtensionCount = device_extension_count;
         create_info.ppEnabledExtensionNames = device_extensions;
         create_info.ppEnabledExtensionNames = device_extensions;
-        err = vkCreateDevice(g_Gpu, &create_info, g_Allocator, &g_Device);
+        err = vkCreateDevice(g_PhysicalDevice, &create_info, g_Allocator, &g_Device);
         check_vk_result(err);
         check_vk_result(err);
-        vkGetDeviceQueue(g_Device, g_QueueFamily, queue_index, &g_Queue);
+        vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue);
     }
     }
 
 
+
     // Create Framebuffers
     // Create Framebuffers
     {
     {
         int w, h;
         int w, h;
         glfwGetFramebufferSize(window, &w, &h);
         glfwGetFramebufferSize(window, &w, &h);
-        resize_vulkan(window, w, h);
-        glfwSetFramebufferSizeCallback(window, resize_vulkan);
+        CreateOrResizeSwapChainAndFrameBuffer(w, h);
+        glfwSetFramebufferSizeCallback(window, GlfwResizeCallback);
     }
     }
 
 
+
     // Create Command Buffers
     // Create Command Buffers
     for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++)
     for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++)
     {
     {
@@ -493,9 +435,9 @@ static void cleanup_vulkan()
     vkDestroySurfaceKHR(g_Instance, g_Surface, g_Allocator);
     vkDestroySurfaceKHR(g_Instance, g_Surface, g_Allocator);
 
 
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
 #ifdef IMGUI_VULKAN_DEBUG_REPORT
-    // get the proc address of the function pointer, required for used extensions
+    // Remove the debug report callback
     auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT");
     auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT");
-    vkDestroyDebugReportCallbackEXT(g_Instance, g_Debug_Report, g_Allocator);
+    vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator);
 #endif // IMGUI_VULKAN_DEBUG_REPORT
 #endif // IMGUI_VULKAN_DEBUG_REPORT
 
 
     vkDestroyDevice(g_Device, g_Allocator);
     vkDestroyDevice(g_Device, g_Allocator);
@@ -616,18 +558,19 @@ int main(int, char**)
     // Setup ImGui binding
     // Setup ImGui binding
     ImGui::CreateContext();
     ImGui::CreateContext();
 
 
-    ImGui_ImplVulkan_InitData init_data = {};
-    init_data.allocator = g_Allocator;
-    init_data.gpu = g_Gpu;
-    init_data.device = g_Device;
-    init_data.render_pass = g_RenderPass;
-    init_data.pipeline_cache = g_PipelineCache;
-    init_data.descriptor_pool = g_DescriptorPool;
-    init_data.check_vk_result = check_vk_result;
+    ImGui_ImplVulkan_InitInfo init_info = {};
+    init_info.Allocator = g_Allocator;
+    init_info.PhysicalDevice = g_PhysicalDevice;
+    init_info.Device = g_Device;
+    init_info.RenderPass = g_RenderPass;
+    init_info.PipelineCache = g_PipelineCache;
+    init_info.DescriptorPool = g_DescriptorPool;
+    init_info.CheckVkResultFn = check_vk_result;
 
 
     ImGuiIO& io = ImGui::GetIO(); (void)io;
     ImGuiIO& io = ImGui::GetIO(); (void)io;
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls
-    ImGui_ImplVulkan_Init(&init_data);
+
+    ImGui_ImplVulkan_Init(&init_info);
     ImGui_ImplGlfw_Init(window, true);
     ImGui_ImplGlfw_Init(window, true);
 
 
     // Setup style
     // Setup style