@ -11,8 +11,17 @@
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app.
// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h.
// You will use those if you want to use this rendering back-end in your engine/app.
// - Helper ImGui_ImplVulkanH_XXX functions and structures are only used by this example (main.cpp) and by
// the back-end itself (imgui_impl_vulkan.cpp), but should PROBABLY NOT be used by your own engine/app code.
// Read comments in imgui_impl_vulkan.h.
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2019-XX-XX: *BREAKING CHANGE*: Vulkan: Added ImageCount/MinImageCount fields in ImGui_ImplVulkan_InitInfo, required for initialization (was previously a hard #define IMGUI_VK_QUEUED_FRAMES 2). Added ImGui_ImplVulkan_SetMinImageCount().
// 2019-XX-XX: Vulkan: Added VkInstance argument to ImGui_ImplVulkanH_CreateWindow() optional helper.
// 2019-04-04: Vulkan: Avoid passing negative coordinates to vkCmdSetScissor, which debug validation layers do not like.
// 2019-04-01: Vulkan: Support for 32-bit index buffer (#define ImDrawIdx unsigned int).
// 2019-02-16: Vulkan: Viewport and clipping rectangles correctly using draw_data->FramebufferScale to allow retina display.
@ -34,28 +43,9 @@
# include "imgui_impl_vulkan.h"
# include <stdio.h>
// Vulkan data
static const VkAllocationCallbacks * g_Allocator = NULL ;
static VkPhysicalDevice g_PhysicalDevice = VK_NULL_HANDLE ;
static VkInstance g_Instance = VK_NULL_HANDLE ;
static VkDevice g_Device = VK_NULL_HANDLE ;
static uint32_t g_QueueFamily = ( uint32_t ) - 1 ;
static VkQueue g_Queue = VK_NULL_HANDLE ;
static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE ;
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE ;
static VkRenderPass g_RenderPass = VK_NULL_HANDLE ;
static void ( * g_CheckVkResultFn ) ( VkResult err ) = NULL ;
static VkDeviceSize g_BufferMemoryAlignment = 256 ;
static VkPipelineCreateFlags g_PipelineCreateFlags = 0 ;
static VkDescriptorSetLayout g_DescriptorSetLayout = VK_NULL_HANDLE ;
static VkPipelineLayout g_PipelineLayout = VK_NULL_HANDLE ;
static VkDescriptorSet g_DescriptorSet = VK_NULL_HANDLE ;
static VkPipeline g_Pipeline = VK_NULL_HANDLE ;
// Frame data
struct FrameDataForRender
// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplVulkan_RenderDrawData()
// [Please zero-clear before use!]
struct ImGui_ImplVulkanH_FrameRenderBuffers
{
VkDeviceMemory VertexBufferMemory ;
VkDeviceMemory IndexBufferMemory ;
@ -64,8 +54,25 @@ struct FrameDataForRender
VkBuffer VertexBuffer ;
VkBuffer IndexBuffer ;
} ;
static int g_FrameIndex = 0 ;
static FrameDataForRender g_FramesDataBuffers [ IMGUI_VK_QUEUED_FRAMES ] = { } ;
// Each viewport will hold 1 ImGui_ImplVulkanH_WindowRenderBuffers
// [Please zero-clear before use!]
struct ImGui_ImplVulkanH_WindowRenderBuffers
{
uint32_t Index ;
uint32_t Count ;
ImGui_ImplVulkanH_FrameRenderBuffers * FrameRenderBuffers ;
} ;
// Vulkan data
static ImGui_ImplVulkan_InitInfo g_VulkanInitInfo = { } ;
static VkRenderPass g_RenderPass = VK_NULL_HANDLE ;
static VkDeviceSize g_BufferMemoryAlignment = 256 ;
static VkPipelineCreateFlags g_PipelineCreateFlags = 0x00 ;
static VkDescriptorSetLayout g_DescriptorSetLayout = VK_NULL_HANDLE ;
static VkPipelineLayout g_PipelineLayout = VK_NULL_HANDLE ;
static VkDescriptorSet g_DescriptorSet = VK_NULL_HANDLE ;
static VkPipeline g_Pipeline = VK_NULL_HANDLE ;
// Font data
static VkSampler g_FontSampler = VK_NULL_HANDLE ;
@ -75,6 +82,23 @@ static VkImageView g_FontView = VK_NULL_HANDLE;
static VkDeviceMemory g_UploadBufferMemory = VK_NULL_HANDLE ;
static VkBuffer g_UploadBuffer = VK_NULL_HANDLE ;
// Render buffers
static ImGui_ImplVulkanH_WindowRenderBuffers g_MainWindowRenderBuffers ;
// Forward Declarations
bool ImGui_ImplVulkan_CreateDeviceObjects ( ) ;
void ImGui_ImplVulkan_DestroyDeviceObjects ( ) ;
void ImGui_ImplVulkanH_DestroyFrame ( VkDevice device , ImGui_ImplVulkanH_Frame * fd , const VkAllocationCallbacks * allocator ) ;
void ImGui_ImplVulkanH_DestroyFrameSemaphores ( VkDevice device , ImGui_ImplVulkanH_FrameSemaphores * fsd , const VkAllocationCallbacks * allocator ) ;
void ImGui_ImplVulkanH_DestroyFrameRenderBuffers ( VkDevice device , ImGui_ImplVulkanH_FrameRenderBuffers * buffers , const VkAllocationCallbacks * allocator ) ;
void ImGui_ImplVulkanH_DestroyWindowRenderBuffers ( VkDevice device , ImGui_ImplVulkanH_WindowRenderBuffers * buffers , const VkAllocationCallbacks * allocator ) ;
void ImGui_ImplVulkanH_CreateWindowSwapChain ( VkPhysicalDevice physical_device , VkDevice device , ImGui_ImplVulkanH_Window * wd , const VkAllocationCallbacks * allocator , int w , int h , uint32_t min_image_count ) ;
void ImGui_ImplVulkanH_CreateWindowCommandBuffers ( VkPhysicalDevice physical_device , VkDevice device , ImGui_ImplVulkanH_Window * wd , uint32_t queue_family , const VkAllocationCallbacks * allocator ) ;
//-----------------------------------------------------------------------------
// SHADERS
//-----------------------------------------------------------------------------
// glsl_shader.vert, compiled with:
// # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert
/*
@ -180,10 +204,15 @@ static uint32_t __glsl_shader_frag_spv[] =
0x00010038
} ;
//-----------------------------------------------------------------------------
// FUNCTIONS
//-----------------------------------------------------------------------------
static uint32_t ImGui_ImplVulkan_MemoryType ( VkMemoryPropertyFlags properties , uint32_t type_bits )
{
ImGui_ImplVulkan_InitInfo * v = & g_VulkanInitInfo ;
VkPhysicalDeviceMemoryProperties prop ;
vkGetPhysicalDeviceMemoryProperties ( g_PhysicalDevice , & prop ) ;
vkGetPhysicalDeviceMemoryProperties ( v- > PhysicalDevice, & prop ) ;
for ( uint32_t i = 0 ; i < prop . memoryTypeCount ; i + + )
if ( ( prop . memoryTypes [ i ] . propertyFlags & properties ) = = properties & & type_bits & ( 1 < < i ) )
return i ;
@ -192,17 +221,19 @@ static uint32_t ImGui_ImplVulkan_MemoryType(VkMemoryPropertyFlags properties, ui
static void check_vk_result ( VkResult err )
{
if ( g_CheckVkResultFn )
g_CheckVkResultFn ( err ) ;
ImGui_ImplVulkan_InitInfo * v = & g_VulkanInitInfo ;
if ( v - > CheckVkResultFn )
v - > CheckVkResultFn ( err ) ;
}
static void CreateOrResizeBuffer ( VkBuffer & buffer , VkDeviceMemory & buffer_memory , VkDeviceSize & p_buffer_size , size_t new_size , VkBufferUsageFlagBits usage )
{
ImGui_ImplVulkan_InitInfo * v = & g_VulkanInitInfo ;
VkResult err ;
if ( buffer ! = VK_NULL_HANDLE )
vkDestroyBuffer ( g_Device, buffer , g_ Allocator) ;
if ( buffer_memory )
vkFreeMemory ( g_Device, buffer_memory , g_ Allocator) ;
vkDestroyBuffer ( v- > Device , buffer , v - > Allocator) ;
if ( buffer_memory ! = VK_NULL_HANDLE )
vkFreeMemory ( v- > Device , buffer_memory , v - > Allocator) ;
VkDeviceSize vertex_buffer_size_aligned = ( ( new_size - 1 ) / g_BufferMemoryAlignment + 1 ) * g_BufferMemoryAlignment ;
VkBufferCreateInfo buffer_info = { } ;
@ -210,20 +241,20 @@ static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory
buffer_info . size = vertex_buffer_size_aligned ;
buffer_info . usage = usage ;
buffer_info . sharingMode = VK_SHARING_MODE_EXCLUSIVE ;
err = vkCreateBuffer ( g_Device, & buffer_info , g_ Allocator, & buffer ) ;
err = vkCreateBuffer ( v- > Device , & buffer_info , v - > Allocator, & buffer ) ;
check_vk_result ( err ) ;
VkMemoryRequirements req ;
vkGetBufferMemoryRequirements ( g_ Device, buffer , & req ) ;
vkGetBufferMemoryRequirements ( v- > Device, buffer , & req ) ;
g_BufferMemoryAlignment = ( g_BufferMemoryAlignment > req . alignment ) ? g_BufferMemoryAlignment : req . alignment ;
VkMemoryAllocateInfo alloc_info = { } ;
alloc_info . sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO ;
alloc_info . allocationSize = req . size ;
alloc_info . memoryTypeIndex = ImGui_ImplVulkan_MemoryType ( VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT , req . memoryTypeBits ) ;
err = vkAllocateMemory ( g_Device, & alloc_info , g_ Allocator, & buffer_memory ) ;
err = vkAllocateMemory ( v- > Device , & alloc_info , v - > Allocator, & buffer_memory ) ;
check_vk_result ( err ) ;
err = vkBindBufferMemory ( g_ Device, buffer , buffer_memory , 0 ) ;
err = vkBindBufferMemory ( v- > Device, buffer , buffer_memory , 0 ) ;
check_vk_result ( err ) ;
p_buffer_size = new_size ;
}
@ -238,25 +269,38 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
if ( fb_width < = 0 | | fb_height < = 0 | | draw_data - > TotalVtxCount = = 0 )
return ;
ImGui_ImplVulkan_InitInfo * v = & g_VulkanInitInfo ;
// Allocate array to store enough vertex/index buffers
ImGui_ImplVulkanH_WindowRenderBuffers * wrb = & g_MainWindowRenderBuffers ;
if ( wrb - > FrameRenderBuffers = = NULL )
{
wrb - > Index = 0 ;
wrb - > Count = v - > ImageCount ;
wrb - > FrameRenderBuffers = ( ImGui_ImplVulkanH_FrameRenderBuffers * ) IM_ALLOC ( sizeof ( ImGui_ImplVulkanH_FrameRenderBuffers ) * wrb - > Count ) ;
memset ( wrb - > FrameRenderBuffers , 0 , sizeof ( ImGui_ImplVulkanH_FrameRenderBuffers ) * wrb - > Count ) ;
}
IM_ASSERT ( wrb - > Count = = v - > ImageCount ) ;
wrb - > Index = ( wrb - > Index + 1 ) % wrb - > Count ;
ImGui_ImplVulkanH_FrameRenderBuffers * rb = & wrb - > FrameRenderBuffers [ wrb - > Index ] ;
VkResult err ;
FrameDataForRender * fd = & g_FramesDataBuffers [ g_FrameIndex ] ;
g_FrameIndex = ( g_FrameIndex + 1 ) % IM_ARRAYSIZE ( g_FramesDataBuffers ) ;
// Create the Vertex and Index buffers:
// Create or resize the vertex/index buffers
size_t vertex_size = draw_data - > TotalVtxCount * sizeof ( ImDrawVert ) ;
size_t index_size = draw_data - > TotalIdxCount * sizeof ( ImDrawIdx ) ;
if ( fd - > VertexBuffer = = VK_NULL_HANDLE | | fd - > VertexBufferSize < vertex_size )
CreateOrResizeBuffer ( fd - > VertexBuffer , fd - > VertexBufferMemory , fd - > VertexBufferSize , vertex_size , VK_BUFFER_USAGE_VERTEX_BUFFER_BIT ) ;
if ( fd - > IndexBuffer = = VK_NULL_HANDLE | | fd - > IndexBufferSize < index_size )
CreateOrResizeBuffer ( fd - > IndexBuffer , fd - > IndexBufferMemory , fd - > IndexBufferSize , index_size , VK_BUFFER_USAGE_INDEX_BUFFER_BIT ) ;
if ( rb - > VertexBuffer = = VK_NULL_HANDLE | | rb - > VertexBufferSize < vertex_size )
CreateOrResizeBuffer ( rb- > VertexBuffer , rb - > VertexBufferMemory , rb - > VertexBufferSize , vertex_size , VK_BUFFER_USAGE_VERTEX_BUFFER_BIT ) ;
if ( rb - > IndexBuffer = = VK_NULL_HANDLE | | rb - > IndexBufferSize < index_size )
CreateOrResizeBuffer ( rb- > IndexBuffer , rb - > IndexBufferMemory , rb - > IndexBufferSize , index_size , VK_BUFFER_USAGE_INDEX_BUFFER_BIT ) ;
// Upload vertex/index data into a single contiguous GPU buffer
{
ImDrawVert * vtx_dst = NULL ;
ImDrawIdx * idx_dst = NULL ;
err = vkMapMemory ( g_Device, fd - > VertexBufferMemory , 0 , vertex_size , 0 , ( void * * ) ( & vtx_dst ) ) ;
err = vkMapMemory ( v- > Device , rb - > VertexBufferMemory , 0 , vertex_size , 0 , ( void * * ) ( & vtx_dst ) ) ;
check_vk_result ( err ) ;
err = vkMapMemory ( g_Device, fd - > IndexBufferMemory , 0 , index_size , 0 , ( void * * ) ( & idx_dst ) ) ;
err = vkMapMemory ( v- > Device , rb - > IndexBufferMemory , 0 , index_size , 0 , ( void * * ) ( & idx_dst ) ) ;
check_vk_result ( err ) ;
for ( int n = 0 ; n < draw_data - > CmdListsCount ; n + + )
{
@ -268,15 +312,15 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
}
VkMappedMemoryRange range [ 2 ] = { } ;
range [ 0 ] . sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE ;
range [ 0 ] . memory = fd - > VertexBufferMemory ;
range [ 0 ] . memory = rb - > VertexBufferMemory ;
range [ 0 ] . size = VK_WHOLE_SIZE ;
range [ 1 ] . sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE ;
range [ 1 ] . memory = fd - > IndexBufferMemory ;
range [ 1 ] . memory = rb - > IndexBufferMemory ;
range [ 1 ] . size = VK_WHOLE_SIZE ;
err = vkFlushMappedMemoryRanges ( g_ Device, 2 , range ) ;
err = vkFlushMappedMemoryRanges ( v- > Device, 2 , range ) ;
check_vk_result ( err ) ;
vkUnmapMemory ( g_Device, fd - > VertexBufferMemory ) ;
vkUnmapMemory ( g_Device, fd - > IndexBufferMemory ) ;
vkUnmapMemory ( v- > Device , rb - > VertexBufferMemory ) ;
vkUnmapMemory ( v- > Device , rb - > IndexBufferMemory ) ;
}
// Bind pipeline and descriptor sets:
@ -288,10 +332,10 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
// Bind Vertex And Index Buffer:
{
VkBuffer vertex_buffers [ 1 ] = { fd - > VertexBuffer } ;
VkBuffer vertex_buffers [ 1 ] = { rb - > VertexBuffer } ;
VkDeviceSize vertex_offset [ 1 ] = { 0 } ;
vkCmdBindVertexBuffers ( command_buffer , 0 , 1 , vertex_buffers , vertex_offset ) ;
vkCmdBindIndexBuffer ( command_buffer , fd - > IndexBuffer , 0 , sizeof ( ImDrawIdx ) = = 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32 ) ;
vkCmdBindIndexBuffer ( command_buffer , rb - > IndexBuffer , 0 , sizeof ( ImDrawIdx ) = = 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32 ) ;
}
// Setup viewport:
@ -374,6 +418,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
bool ImGui_ImplVulkan_CreateFontsTexture ( VkCommandBuffer command_buffer )
{
ImGui_ImplVulkan_InitInfo * v = & g_VulkanInitInfo ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
unsigned char * pixels ;
@ -399,17 +444,17 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
info . usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT ;
info . sharingMode = VK_SHARING_MODE_EXCLUSIVE ;
info . initialLayout = VK_IMAGE_LAYOUT_UNDEFINED ;
err = vkCreateImage ( g_Device, & info , g_ Allocator, & g_FontImage ) ;
err = vkCreateImage ( v- > Device , & info , v - > Allocator, & g_FontImage ) ;
check_vk_result ( err ) ;
VkMemoryRequirements req ;
vkGetImageMemoryRequirements ( g_ Device, g_FontImage , & req ) ;
vkGetImageMemoryRequirements ( v- > Device, g_FontImage , & req ) ;
VkMemoryAllocateInfo alloc_info = { } ;
alloc_info . sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO ;
alloc_info . allocationSize = req . size ;
alloc_info . memoryTypeIndex = ImGui_ImplVulkan_MemoryType ( VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT , req . memoryTypeBits ) ;
err = vkAllocateMemory ( g_Device, & alloc_info , g_ Allocator, & g_FontMemory ) ;
err = vkAllocateMemory ( v- > Device , & alloc_info , v - > Allocator, & g_FontMemory ) ;
check_vk_result ( err ) ;
err = vkBindImageMemory ( g_ Device, g_FontImage , g_FontMemory , 0 ) ;
err = vkBindImageMemory ( v- > Device, g_FontImage , g_FontMemory , 0 ) ;
check_vk_result ( err ) ;
}
@ -423,7 +468,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
info . subresourceRange . aspectMask = VK_IMAGE_ASPECT_COLOR_BIT ;
info . subresourceRange . levelCount = 1 ;
info . subresourceRange . layerCount = 1 ;
err = vkCreateImageView ( g_Device, & info , g_ Allocator, & g_FontView ) ;
err = vkCreateImageView ( v- > Device , & info , v - > Allocator, & g_FontView ) ;
check_vk_result ( err ) ;
}
@ -439,7 +484,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
write_desc [ 0 ] . descriptorCount = 1 ;
write_desc [ 0 ] . descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ;
write_desc [ 0 ] . pImageInfo = desc_image ;
vkUpdateDescriptorSets ( g_ Device, 1 , write_desc , 0 , NULL ) ;
vkUpdateDescriptorSets ( v- > Device, 1 , write_desc , 0 , NULL ) ;
}
// Create the Upload Buffer:
@ -449,34 +494,34 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
buffer_info . size = upload_size ;
buffer_info . usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT ;
buffer_info . sharingMode = VK_SHARING_MODE_EXCLUSIVE ;
err = vkCreateBuffer ( g_Device, & buffer_info , g_ Allocator, & g_UploadBuffer ) ;
err = vkCreateBuffer ( v- > Device , & buffer_info , v - > Allocator, & g_UploadBuffer ) ;
check_vk_result ( err ) ;
VkMemoryRequirements req ;
vkGetBufferMemoryRequirements ( g_ Device, g_UploadBuffer , & req ) ;
vkGetBufferMemoryRequirements ( v- > Device, g_UploadBuffer , & req ) ;
g_BufferMemoryAlignment = ( g_BufferMemoryAlignment > req . alignment ) ? g_BufferMemoryAlignment : req . alignment ;
VkMemoryAllocateInfo alloc_info = { } ;
alloc_info . sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO ;
alloc_info . allocationSize = req . size ;
alloc_info . memoryTypeIndex = ImGui_ImplVulkan_MemoryType ( VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT , req . memoryTypeBits ) ;
err = vkAllocateMemory ( g_Device, & alloc_info , g_ Allocator, & g_UploadBufferMemory ) ;
err = vkAllocateMemory ( v- > Device , & alloc_info , v - > Allocator, & g_UploadBufferMemory ) ;
check_vk_result ( err ) ;
err = vkBindBufferMemory ( g_ Device, g_UploadBuffer , g_UploadBufferMemory , 0 ) ;
err = vkBindBufferMemory ( v- > Device, g_UploadBuffer , g_UploadBufferMemory , 0 ) ;
check_vk_result ( err ) ;
}
// Upload to Buffer:
{
char * map = NULL ;
err = vkMapMemory ( g_ Device, g_UploadBufferMemory , 0 , upload_size , 0 , ( void * * ) ( & map ) ) ;
err = vkMapMemory ( v- > Device, g_UploadBufferMemory , 0 , upload_size , 0 , ( void * * ) ( & map ) ) ;
check_vk_result ( err ) ;
memcpy ( map , pixels , upload_size ) ;
VkMappedMemoryRange range [ 1 ] = { } ;
range [ 0 ] . sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE ;
range [ 0 ] . memory = g_UploadBufferMemory ;
range [ 0 ] . size = upload_size ;
err = vkFlushMappedMemoryRanges ( g_ Device, 1 , range ) ;
err = vkFlushMappedMemoryRanges ( v- > Device, 1 , range ) ;
check_vk_result ( err ) ;
vkUnmapMemory ( g_ Device, g_UploadBufferMemory ) ;
vkUnmapMemory ( v- > Device, g_UploadBufferMemory ) ;
}
// Copy to Image:
@ -525,6 +570,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
bool ImGui_ImplVulkan_CreateDeviceObjects ( )
{
ImGui_ImplVulkan_InitInfo * v = & g_VulkanInitInfo ;
VkResult err ;
VkShaderModule vert_module ;
VkShaderModule frag_module ;
@ -535,13 +581,13 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
vert_info . sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO ;
vert_info . codeSize = sizeof ( __glsl_shader_vert_spv ) ;
vert_info . pCode = ( uint32_t * ) __glsl_shader_vert_spv ;
err = vkCreateShaderModule ( g_Device, & vert_info , g_ Allocator, & vert_module ) ;
err = vkCreateShaderModule ( v- > Device , & vert_info , v - > Allocator, & vert_module ) ;
check_vk_result ( err ) ;
VkShaderModuleCreateInfo frag_info = { } ;
frag_info . sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO ;
frag_info . codeSize = sizeof ( __glsl_shader_frag_spv ) ;
frag_info . pCode = ( uint32_t * ) __glsl_shader_frag_spv ;
err = vkCreateShaderModule ( g_Device, & frag_info , g_ Allocator, & frag_module ) ;
err = vkCreateShaderModule ( v- > Device , & frag_info , v - > Allocator, & frag_module ) ;
check_vk_result ( err ) ;
}
@ -558,7 +604,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
info . minLod = - 1000 ;
info . maxLod = 1000 ;
info . maxAnisotropy = 1.0f ;
err = vkCreateSampler ( g_Device, & info , g_ Allocator, & g_FontSampler ) ;
err = vkCreateSampler ( v- > Device , & info , v - > Allocator, & g_FontSampler ) ;
check_vk_result ( err ) ;
}
@ -574,7 +620,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
info . sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO ;
info . bindingCount = 1 ;
info . pBindings = binding ;
err = vkCreateDescriptorSetLayout ( g_Device, & info , g_ Allocator, & g_DescriptorSetLayout ) ;
err = vkCreateDescriptorSetLayout ( v- > Device , & info , v - > Allocator, & g_DescriptorSetLayout ) ;
check_vk_result ( err ) ;
}
@ -582,10 +628,10 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
{
VkDescriptorSetAllocateInfo alloc_info = { } ;
alloc_info . sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO ;
alloc_info . descriptorPool = g_ DescriptorPool;
alloc_info . descriptorPool = v- > DescriptorPool;
alloc_info . descriptorSetCount = 1 ;
alloc_info . pSetLayouts = & g_DescriptorSetLayout ;
err = vkAllocateDescriptorSets ( g_ Device, & alloc_info , & g_DescriptorSet ) ;
err = vkAllocateDescriptorSets ( v- > Device, & alloc_info , & g_DescriptorSet ) ;
check_vk_result ( err ) ;
}
@ -603,7 +649,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
layout_info . pSetLayouts = set_layout ;
layout_info . pushConstantRangeCount = 1 ;
layout_info . pPushConstantRanges = push_constants ;
err = vkCreatePipelineLayout ( g_Device, & layout_info , g_ Allocator, & g_PipelineLayout ) ;
err = vkCreatePipelineLayout ( v- > Device , & layout_info , v - > Allocator, & g_PipelineLayout ) ;
check_vk_result ( err ) ;
}
@ -701,49 +747,43 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
info . pDynamicState = & dynamic_state ;
info . layout = g_PipelineLayout ;
info . renderPass = g_RenderPass ;
err = vkCreateGraphicsPipelines ( g_Device, g_PipelineCache , 1 , & info , g_ Allocator, & g_Pipeline ) ;
err = vkCreateGraphicsPipelines ( v- > Device , v - > PipelineCache , 1 , & info , v - > Allocator, & g_Pipeline ) ;
check_vk_result ( err ) ;
vkDestroyShaderModule ( g_Device, vert_module , g_ Allocator) ;
vkDestroyShaderModule ( g_Device, frag_module , g_ Allocator) ;
vkDestroyShaderModule ( v- > Device , vert_module , v - > Allocator) ;
vkDestroyShaderModule ( v- > Device , frag_module , v - > Allocator) ;
return true ;
}
void ImGui_ImplVulkan_ Invalidate FontUploadObjects( )
void ImGui_ImplVulkan_ Destroy FontUploadObjects( )
{
ImGui_ImplVulkan_InitInfo * v = & g_VulkanInitInfo ;
if ( g_UploadBuffer )
{
vkDestroyBuffer ( g_Device, g_UploadBuffer , g_ Allocator) ;
vkDestroyBuffer ( v- > Device , g_UploadBuffer , v - > Allocator) ;
g_UploadBuffer = VK_NULL_HANDLE ;
}
if ( g_UploadBufferMemory )
{
vkFreeMemory ( g_Device, g_UploadBufferMemory , g_ Allocator) ;
vkFreeMemory ( v- > Device , g_UploadBufferMemory , v - > Allocator) ;
g_UploadBufferMemory = VK_NULL_HANDLE ;
}
}
void ImGui_ImplVulkan_InvalidateDeviceObjects ( )
{
ImGui_ImplVulkan_InvalidateFontUploadObjects ( ) ;
for ( int i = 0 ; i < IM_ARRAYSIZE ( g_FramesDataBuffers ) ; i + + )
void ImGui_ImplVulkan_DestroyDeviceObjects ( )
{
FrameDataForRender * fd = & g_FramesDataBuffers [ i ] ;
if ( fd - > VertexBuffer ) { vkDestroyBuffer ( g_Device , fd - > VertexBuffer , g_Allocator ) ; fd - > VertexBuffer = VK_NULL_HANDLE ; }
if ( fd - > VertexBufferMemory ) { vkFreeMemory ( g_Device , fd - > VertexBufferMemory , g_Allocator ) ; fd - > VertexBufferMemory = VK_NULL_HANDLE ; }
if ( fd - > IndexBuffer ) { vkDestroyBuffer ( g_Device , fd - > IndexBuffer , g_Allocator ) ; fd - > IndexBuffer = VK_NULL_HANDLE ; }
if ( fd - > IndexBufferMemory ) { vkFreeMemory ( g_Device , fd - > IndexBufferMemory , g_Allocator ) ; fd - > IndexBufferMemory = VK_NULL_HANDLE ; }
}
ImGui_ImplVulkan_InitInfo * v = & g_VulkanInitInfo ;
ImGui_ImplVulkanH_DestroyWindowRenderBuffers ( v - > Device , & g_MainWindowRenderBuffers , v - > Allocator ) ;
ImGui_ImplVulkan_DestroyFontUploadObjects ( ) ;
if ( g_FontView ) { vkDestroyImageView ( g_Device, g_FontView , g_ Allocator) ; g_FontView = VK_NULL_HANDLE ; }
if ( g_FontImage ) { vkDestroyImage ( g_Device, g_FontImage , g_ Allocator) ; g_FontImage = VK_NULL_HANDLE ; }
if ( g_FontMemory ) { vkFreeMemory ( g_Device, g_FontMemory , g_ Allocator) ; g_FontMemory = VK_NULL_HANDLE ; }
if ( g_FontSampler ) { vkDestroySampler ( g_Device, g_FontSampler , g_ Allocator) ; g_FontSampler = VK_NULL_HANDLE ; }
if ( g_DescriptorSetLayout ) { vkDestroyDescriptorSetLayout ( g_Device, g_DescriptorSetLayout , g_ Allocator) ; g_DescriptorSetLayout = VK_NULL_HANDLE ; }
if ( g_PipelineLayout ) { vkDestroyPipelineLayout ( g_Device, g_PipelineLayout , g_ Allocator) ; g_PipelineLayout = VK_NULL_HANDLE ; }
if ( g_Pipeline ) { vkDestroyPipeline ( g_Device, g_Pipeline , g_ Allocator) ; g_Pipeline = VK_NULL_HANDLE ; }
if ( g_FontView ) { vkDestroyImageView ( v - > Device , g_FontView , v - > Allocator ) ; g_FontView = VK_NULL_HANDLE ; }
if ( g_FontImage ) { vkDestroyImage ( v - > Device , g_FontImage , v - > Allocator ) ; g_FontImage = VK_NULL_HANDLE ; }
if ( g_FontMemory ) { vkFreeMemory ( v- > Device , g_FontMemory , v - > Allocator) ; g_FontMemory = VK_NULL_HANDLE ; }
if ( g_FontSampler ) { vkDestroySampler ( v- > Device , g_FontSampler , v - > Allocator) ; g_FontSampler = VK_NULL_HANDLE ; }
if ( g_DescriptorSetLayout ) { vkDestroyDescriptorSetLayout ( v- > Device , g_DescriptorSetLayout , v - > Allocator) ; g_DescriptorSetLayout = VK_NULL_HANDLE ; }
if ( g_PipelineLayout ) { vkDestroyPipelineLayout ( v- > Device , g_PipelineLayout , v - > Allocator) ; g_PipelineLayout = VK_NULL_HANDLE ; }
if ( g_Pipeline ) { vkDestroyPipeline ( v- > Device , g_Pipeline , v - > Allocator) ; g_Pipeline = VK_NULL_HANDLE ; }
}
bool ImGui_ImplVulkan_Init ( ImGui_ImplVulkan_InitInfo * info , VkRenderPass render_pass )
@ -756,19 +796,12 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
IM_ASSERT ( info - > Device ! = VK_NULL_HANDLE ) ;
IM_ASSERT ( info - > Queue ! = VK_NULL_HANDLE ) ;
IM_ASSERT ( info - > DescriptorPool ! = VK_NULL_HANDLE ) ;
IM_ASSERT ( info - > MinImageCount > = 2 ) ;
IM_ASSERT ( info - > ImageCount > = info - > MinImageCount ) ;
IM_ASSERT ( render_pass ! = VK_NULL_HANDLE ) ;
g_Instance = info - > Instance ;
g_PhysicalDevice = info - > PhysicalDevice ;
g_Device = info - > Device ;
g_QueueFamily = info - > QueueFamily ;
g_Queue = info - > Queue ;
g_VulkanInitInfo = * info ;
g_RenderPass = render_pass ;
g_PipelineCache = info - > PipelineCache ;
g_DescriptorPool = info - > DescriptorPool ;
g_Allocator = info - > Allocator ;
g_CheckVkResultFn = info - > CheckVkResultFn ;
ImGui_ImplVulkan_CreateDeviceObjects ( ) ;
return true ;
@ -776,16 +809,30 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
void ImGui_ImplVulkan_Shutdown ( )
{
ImGui_ImplVulkan_ Invalidate DeviceObjects( ) ;
ImGui_ImplVulkan_ Destroy DeviceObjects( ) ;
}
void ImGui_ImplVulkan_NewFrame ( )
{
}
void ImGui_ImplVulkan_SetMinImageCount ( uint32_t min_image_count )
{
IM_ASSERT ( min_image_count > = 2 ) ;
if ( g_VulkanInitInfo . MinImageCount = = min_image_count )
return ;
ImGui_ImplVulkan_InitInfo * v = & g_VulkanInitInfo ;
VkResult err = vkDeviceWaitIdle ( v - > Device ) ;
check_vk_result ( err ) ;
ImGui_ImplVulkanH_DestroyWindowRenderBuffers ( v - > Device , & g_MainWindowRenderBuffers , v - > Allocator ) ;
g_VulkanInitInfo . MinImageCount = min_image_count ;
}
//-------------------------------------------------------------------------
// Internal / Miscellaneous Vulkan Helpers
// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own app.)
//-------------------------------------------------------------------------
// You probably do NOT need to use or care about those functions.
// Those functions only exist because:
@ -793,40 +840,12 @@ void ImGui_ImplVulkan_NewFrame()
// 2) the upcoming multi-viewport feature will need them internally.
// Generally we avoid exposing any kind of superfluous high-level helpers in the bindings,
// but it is too much code to duplicate everywhere so we exceptionally expose them.
// Your application/engine will likely already have code to setup all that stuff (swap chain, render pass, frame buffers, etc.).
//
// Your engine/app will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.).
// You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work.
// ( those functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions)
// ( The ImGui_ImplVulkanH_XXX functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions)
//-------------------------------------------------------------------------
# include <stdlib.h> // malloc
ImGui_ImplVulkanH_FrameData : : ImGui_ImplVulkanH_FrameData ( )
{
BackbufferIndex = 0 ;
CommandPool = VK_NULL_HANDLE ;
CommandBuffer = VK_NULL_HANDLE ;
Fence = VK_NULL_HANDLE ;
ImageAcquiredSemaphore = VK_NULL_HANDLE ;
RenderCompleteSemaphore = VK_NULL_HANDLE ;
}
ImGui_ImplVulkanH_WindowData : : ImGui_ImplVulkanH_WindowData ( )
{
Width = Height = 0 ;
Swapchain = VK_NULL_HANDLE ;
Surface = VK_NULL_HANDLE ;
memset ( & SurfaceFormat , 0 , sizeof ( SurfaceFormat ) ) ;
PresentMode = VK_PRESENT_MODE_MAX_ENUM_KHR ;
RenderPass = VK_NULL_HANDLE ;
ClearEnable = true ;
memset ( & ClearValue , 0 , sizeof ( ClearValue ) ) ;
BackBufferCount = 0 ;
memset ( & BackBuffer , 0 , sizeof ( BackBuffer ) ) ;
memset ( & BackBufferView , 0 , sizeof ( BackBufferView ) ) ;
memset ( & Framebuffer , 0 , sizeof ( Framebuffer ) ) ;
FrameIndex = 0 ;
}
VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat ( VkPhysicalDevice physical_device , VkSurfaceKHR surface , const VkFormat * request_formats , int request_formats_count , VkColorSpaceKHR request_color_space )
{
IM_ASSERT ( request_formats ! = NULL ) ;
@ -893,7 +912,7 @@ VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_d
return VK_PRESENT_MODE_FIFO_KHR ; // Always available
}
void ImGui_ImplVulkanH_CreateWindow Data CommandBuffers( VkPhysicalDevice physical_device , VkDevice device , uint32_t queue_family , ImGui_ImplVulkanH_Window Data * wd , const VkAllocationCallbacks * allocator )
void ImGui_ImplVulkanH_CreateWindow CommandBuffers( VkPhysicalDevice physical_device , VkDevice device , ImGui_ImplVulkanH_Window * wd , uint32_t queue_family , const VkAllocationCallbacks * allocator )
{
IM_ASSERT ( physical_device ! = VK_NULL_HANDLE & & device ! = VK_NULL_HANDLE ) ;
( void ) physical_device ;
@ -901,9 +920,10 @@ void ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(VkPhysicalDevice physical_
// Create Command Buffers
VkResult err ;
for ( int i = 0 ; i < IM_ARRAYSIZE( wd - > Frames ) ; i + + )
for ( u int32_ t i = 0 ; i < wd- > ImageCount ; i + + )
{
ImGui_ImplVulkanH_FrameData * fd = & wd - > Frames [ i ] ;
ImGui_ImplVulkanH_Frame * fd = & wd - > Frames [ i ] ;
ImGui_ImplVulkanH_FrameSemaphores * fsd = & wd - > FrameSemaphores [ i ] ;
{
VkCommandPoolCreateInfo info = { } ;
info . sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO ;
@ -931,9 +951,9 @@ void ImGui_ImplVulkanH_CreateWindowDataCommandBuffers(VkPhysicalDevice physical_
{
VkSemaphoreCreateInfo info = { } ;
info . sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO ;
err = vkCreateSemaphore ( device , & info , allocator , & f d- > ImageAcquiredSemaphore ) ;
err = vkCreateSemaphore ( device , & info , allocator , & f s d- > ImageAcquiredSemaphore ) ;
check_vk_result ( err ) ;
err = vkCreateSemaphore ( device , & info , allocator , & f d- > RenderCompleteSemaphore ) ;
err = vkCreateSemaphore ( device , & info , allocator , & f s d- > RenderCompleteSemaphore ) ;
check_vk_result ( err ) ;
}
}
@ -951,24 +971,26 @@ int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_m
return 1 ;
}
void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer ( VkPhysicalDevice physical_device , VkDevice device , ImGui_ImplVulkanH_WindowData * wd , const VkAllocationCallbacks * allocator , int w , int h )
// Also destroy old swap chain and in-flight frames data, if any.
void ImGui_ImplVulkanH_CreateWindowSwapChain ( VkPhysicalDevice physical_device , VkDevice device , ImGui_ImplVulkanH_Window * wd , const VkAllocationCallbacks * allocator , int w , int h , uint32_t min_image_count )
{
uint32_t min_image_count = 2 ; // FIXME: this should become a function parameter
VkResult err ;
VkSwapchainKHR old_swapchain = wd - > Swapchain ;
err = vkDeviceWaitIdle ( device ) ;
check_vk_result ( err ) ;
// We don't use ImGui_ImplVulkanH_DestroyWindow() because we want to preserve the old swapchain to create the new one.
// Destroy old Framebuffer
for ( uint32_t i = 0 ; i < wd - > BackBuffer Count; i + + )
for ( uint32_t i = 0 ; i < wd - > Image Count; i + + )
{
if ( wd - > BackBufferView [ i ] )
vkDestroyImageView ( device , wd - > BackBufferView [ i ] , allocator ) ;
if ( wd - > Framebuffer [ i ] )
vkDestroyFramebuffer ( device , wd - > Framebuffer [ i ] , allocator ) ;
ImGui_ImplVulkanH_DestroyFrame ( device , & wd - > Frames [ i ] , allocator ) ;
ImGui_ImplVulkanH_DestroyFrameSemaphores ( device , & wd - > FrameSemaphores [ i ] , allocator ) ;
}
wd - > BackBufferCount = 0 ;
IM_FREE ( wd - > Frames ) ;
IM_FREE ( wd - > FrameSemaphores ) ;
wd - > Frames = NULL ;
wd - > FrameSemaphores = NULL ;
wd - > ImageCount = 0 ;
if ( wd - > RenderPass )
vkDestroyRenderPass ( device , wd - > RenderPass , allocator ) ;
@ -1012,10 +1034,21 @@ void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice
}
err = vkCreateSwapchainKHR ( device , & info , allocator , & wd - > Swapchain ) ;
check_vk_result ( err ) ;
err = vkGetSwapchainImagesKHR ( device , wd - > Swapchain , & wd - > BackBuffer Count, NULL ) ;
err = vkGetSwapchainImagesKHR ( device , wd - > Swapchain , & wd - > Image Count, NULL ) ;
check_vk_result ( err ) ;
err = vkGetSwapchainImagesKHR ( device , wd - > Swapchain , & wd - > BackBufferCount , wd - > BackBuffer ) ;
VkImage backbuffers [ 16 ] = { } ;
IM_ASSERT ( wd - > ImageCount > = min_image_count ) ;
IM_ASSERT ( wd - > ImageCount < IM_ARRAYSIZE ( backbuffers ) ) ;
err = vkGetSwapchainImagesKHR ( device , wd - > Swapchain , & wd - > ImageCount , backbuffers ) ;
check_vk_result ( err ) ;
IM_ASSERT ( wd - > Frames = = NULL ) ;
wd - > Frames = ( ImGui_ImplVulkanH_Frame * ) IM_ALLOC ( sizeof ( ImGui_ImplVulkanH_Frame ) * wd - > ImageCount ) ;
wd - > FrameSemaphores = ( ImGui_ImplVulkanH_FrameSemaphores * ) IM_ALLOC ( sizeof ( ImGui_ImplVulkanH_FrameSemaphores ) * wd - > ImageCount ) ;
memset ( wd - > Frames , 0 , sizeof ( wd - > Frames [ 0 ] ) * wd - > ImageCount ) ;
memset ( wd - > FrameSemaphores , 0 , sizeof ( wd - > FrameSemaphores [ 0 ] ) * wd - > ImageCount ) ;
for ( uint32_t i = 0 ; i < wd - > ImageCount ; i + + )
wd - > Frames [ i ] . Backbuffer = backbuffers [ i ] ;
}
if ( old_swapchain )
vkDestroySwapchainKHR ( device , old_swapchain , allocator ) ;
@ -1069,10 +1102,11 @@ void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice
info . components . a = VK_COMPONENT_SWIZZLE_A ;
VkImageSubresourceRange image_range = { VK_IMAGE_ASPECT_COLOR_BIT , 0 , 1 , 0 , 1 } ;
info . subresourceRange = image_range ;
for ( uint32_t i = 0 ; i < wd - > BackBuffer Count; i + + )
for ( uint32_t i = 0 ; i < wd - > Image Count; i + + )
{
info . image = wd - > BackBuffer [ i ] ;
err = vkCreateImageView ( device , & info , allocator , & wd - > BackBufferView [ i ] ) ;
ImGui_ImplVulkanH_Frame * fd = & wd - > Frames [ i ] ;
info . image = fd - > Backbuffer ;
err = vkCreateImageView ( device , & info , allocator , & fd - > BackbufferView ) ;
check_vk_result ( err ) ;
}
}
@ -1088,36 +1122,80 @@ void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice
info . width = wd - > Width ;
info . height = wd - > Height ;
info . layers = 1 ;
for ( uint32_t i = 0 ; i < wd - > BackBuffer Count; i + + )
for ( uint32_t i = 0 ; i < wd - > Image Count; i + + )
{
attachment [ 0 ] = wd - > BackBufferView [ i ] ;
err = vkCreateFramebuffer ( device , & info , allocator , & wd - > Framebuffer [ i ] ) ;
ImGui_ImplVulkanH_Frame * fd = & wd - > Frames [ i ] ;
attachment [ 0 ] = fd - > BackbufferView ;
err = vkCreateFramebuffer ( device , & info , allocator , & fd - > Framebuffer ) ;
check_vk_result ( err ) ;
}
}
}
void ImGui_ImplVulkanH_DestroyWindowData ( VkInstance instance , VkDevice device , ImGui_ImplVulkanH_WindowData * wd , const VkAllocationCallbacks * allocator )
void ImGui_ImplVulkanH_CreateWindow ( VkInstance instance , VkPhysicalDevice physical_device , VkDevice device , ImGui_ImplVulkanH_Window * wd , uint32_t queue_family , const VkAllocationCallbacks * allocator , int width , int height , uint32_t min_image_count )
{
( void ) instance ;
ImGui_ImplVulkanH_CreateWindowSwapChain ( physical_device , device , wd , allocator , width , height , min_image_count ) ;
ImGui_ImplVulkanH_CreateWindowCommandBuffers ( physical_device , device , wd , queue_family , allocator ) ;
}
void ImGui_ImplVulkanH_DestroyWindow ( VkInstance instance , VkDevice device , ImGui_ImplVulkanH_Window * wd , const VkAllocationCallbacks * allocator )
{
vkDeviceWaitIdle ( device ) ; // FIXME: We could wait on the Queue if we had the queue in wd-> (otherwise VulkanH functions can't use globals)
//vkQueueWaitIdle(g_Queue);
for ( int i = 0 ; i < IM_ARRAYSIZE ( wd - > Frames ) ; i + + )
for ( uint32_t i = 0 ; i < wd - > ImageCount ; i + + )
{
ImGui_ImplVulkanH_DestroyFrame ( device , & wd - > Frames [ i ] , allocator ) ;
ImGui_ImplVulkanH_DestroyFrameSemaphores ( device , & wd - > FrameSemaphores [ i ] , allocator ) ;
}
IM_FREE ( wd - > Frames ) ;
IM_FREE ( wd - > FrameSemaphores ) ;
wd - > Frames = NULL ;
wd - > FrameSemaphores = NULL ;
vkDestroyRenderPass ( device , wd - > RenderPass , allocator ) ;
vkDestroySwapchainKHR ( device , wd - > Swapchain , allocator ) ;
vkDestroySurfaceKHR ( instance , wd - > Surface , allocator ) ;
* wd = ImGui_ImplVulkanH_Window ( ) ;
}
void ImGui_ImplVulkanH_DestroyFrame ( VkDevice device , ImGui_ImplVulkanH_Frame * fd , const VkAllocationCallbacks * allocator )
{
ImGui_ImplVulkanH_FrameData * fd = & wd - > Frames [ i ] ;
vkDestroyFence ( device , fd - > Fence , allocator ) ;
vkFreeCommandBuffers ( device , fd - > CommandPool , 1 , & fd - > CommandBuffer ) ;
vkDestroyCommandPool ( device , fd - > CommandPool , allocator ) ;
vkDestroySemaphore ( device , fd - > ImageAcquiredSemaphore , allocator ) ;
vkDestroySemaphore ( device , fd - > RenderCompleteSemaphore , allocator ) ;
fd - > Fence = VK_NULL_HANDLE ;
fd - > CommandBuffer = VK_NULL_HANDLE ;
fd - > CommandPool = VK_NULL_HANDLE ;
vkDestroyImageView ( device , fd - > BackbufferView , allocator ) ;
vkDestroyFramebuffer ( device , fd - > Framebuffer , allocator ) ;
}
for ( uint32_t i = 0 ; i < wd - > BackBufferCount ; i + + )
void ImGui_ImplVulkanH_DestroyFrameSemaphores ( VkDevice device , ImGui_ImplVulkanH_FrameSemaphores * fsd , const VkAllocationCallbacks * allocator )
{
vkDestroyImageView ( device , wd - > BackBufferView [ i ] , allocator ) ;
vkDestroyFramebuffer ( device , wd - > Framebuffer [ i ] , allocator ) ;
vkDestroySemaphore ( device , fsd - > ImageAcquiredSemaphore , allocator ) ;
vkDestroySemaphore ( device , fsd - > RenderCompleteSemaphore , allocator ) ;
fsd - > ImageAcquiredSemaphore = fsd - > RenderCompleteSemaphore = VK_NULL_HANDLE ;
}
vkDestroyRenderPass ( device , wd - > RenderPass , allocator ) ;
vkDestroySwapchainKHR ( device , wd - > Swapchain , allocator ) ;
vkDestroySurfaceKHR ( instance , wd - > Surface , allocator ) ;
* wd = ImGui_ImplVulkanH_WindowData ( ) ;
void ImGui_ImplVulkanH_DestroyFrameRenderBuffers ( VkDevice device , ImGui_ImplVulkanH_FrameRenderBuffers * buffers , const VkAllocationCallbacks * allocator )
{
if ( buffers - > VertexBuffer ) { vkDestroyBuffer ( device , buffers - > VertexBuffer , allocator ) ; buffers - > VertexBuffer = VK_NULL_HANDLE ; }
if ( buffers - > VertexBufferMemory ) { vkFreeMemory ( device , buffers - > VertexBufferMemory , allocator ) ; buffers - > VertexBufferMemory = VK_NULL_HANDLE ; }
if ( buffers - > IndexBuffer ) { vkDestroyBuffer ( device , buffers - > IndexBuffer , allocator ) ; buffers - > IndexBuffer = VK_NULL_HANDLE ; }
if ( buffers - > IndexBufferMemory ) { vkFreeMemory ( device , buffers - > IndexBufferMemory , allocator ) ; buffers - > IndexBufferMemory = VK_NULL_HANDLE ; }
buffers - > VertexBufferSize = 0 ;
buffers - > IndexBufferSize = 0 ;
}
void ImGui_ImplVulkanH_DestroyWindowRenderBuffers ( VkDevice device , ImGui_ImplVulkanH_WindowRenderBuffers * buffers , const VkAllocationCallbacks * allocator )
{
for ( uint32_t n = 0 ; n < buffers - > Count ; n + + )
ImGui_ImplVulkanH_DestroyFrameRenderBuffers ( device , & buffers - > FrameRenderBuffers [ n ] , allocator ) ;
IM_FREE ( buffers - > FrameRenderBuffers ) ;
buffers - > FrameRenderBuffers = NULL ;
buffers - > Index = 0 ;
buffers - > Count = 0 ;
}