@ -12,8 +12,18 @@
// 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_XXXX 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_XXXX 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 extra parameter to ImGui_ImplVulkan_RenderDrawData(). Engine/app is in charge of owning/storing 1 ImGui_ImplVulkan_FrameRenderBuffers per in-flight rendering frame. (The demo helper ImGui_ImplVulkanH_Window structure carries them.)
// 2019-XX-XX: *BREAKING CHANGE*: Vulkan: Added MinImageCount field in ImGui_ImplVulkan_InitInfo, required for initialization (was previously a hard #define IMGUI_VK_QUEUED_FRAMES 2). Added ImGui_ImplVulkan_SetSwapChainMinImageCount().
// 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.
@ -36,38 +46,15 @@
# 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 ImGui_ImplVulkan_InitInfo g_VulkanInitInfo = { } ;
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 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 ;
// Frame data
struct FrameDataForRender
{
VkDeviceMemory VertexBufferMemory ;
VkDeviceMemory IndexBufferMemory ;
VkDeviceSize VertexBufferSize ;
VkDeviceSize IndexBufferSize ;
VkBuffer VertexBuffer ;
VkBuffer IndexBuffer ;
} ;
static int g_FrameIndex = 0 ;
static FrameDataForRender g_FramesDataBuffers [ IMGUI_VK_QUEUED_FRAMES ] = { } ;
// Font data
static VkSampler g_FontSampler = VK_NULL_HANDLE ;
static VkDeviceMemory g_FontMemory = VK_NULL_HANDLE ;
@ -76,6 +63,15 @@ static VkImageView g_FontView = VK_NULL_HANDLE;
static VkDeviceMemory g_UploadBufferMemory = VK_NULL_HANDLE ;
static VkBuffer g_UploadBuffer = VK_NULL_HANDLE ;
// Forward Declarations
void ImGui_ImplVulkanH_DestroyFrame ( VkInstance instance , VkDevice device , ImGui_ImplVulkanH_Frame * fd , const VkAllocationCallbacks * allocator ) ;
void ImGui_ImplVulkanH_CreateWindowSwapChain ( VkInstance instance , 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 ( VkInstance instance , VkPhysicalDevice physical_device , VkDevice device , ImGui_ImplVulkanH_Window * wd , uint32_t queue_family , const VkAllocationCallbacks * allocator ) ;
//-----------------------------------------------------------------------------
// SHADERS
//-----------------------------------------------------------------------------
// Forward Declarations
static void ImGui_ImplVulkan_InitPlatformInterface ( ) ;
static void ImGui_ImplVulkan_ShutdownPlatformInterface ( ) ;
@ -185,10 +181,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 ;
@ -197,17 +198,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) ;
vkDestroyBuffer ( v- > Device , buffer , v - > Allocator) ;
if ( buffer_memory )
vkFreeMemory ( g_Device, buffer_memory , g_ Allocator) ;
vkFreeMemory ( v- > Device , buffer_memory , v - > Allocator) ;
VkDeviceSize vertex_buffer_size_aligned = ( ( new_size - 1 ) / g_BufferMemoryAlignment + 1 ) * g_BufferMemoryAlignment ;
VkBufferCreateInfo buffer_info = { } ;
@ -215,27 +218,27 @@ 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 ;
}
// Render function
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplVulkan_RenderDrawData ( ImDrawData * draw_data , VkCommandBuffer command_buffer )
void ImGui_ImplVulkan_RenderDrawData ( ImDrawData * draw_data , VkCommandBuffer command_buffer , ImGui_ImplVulkan_FrameRenderBuffers * fd )
{
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
int fb_width = ( int ) ( draw_data - > DisplaySize . x * draw_data - > FramebufferScale . x ) ;
@ -243,9 +246,8 @@ 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 ;
VkResult err ;
FrameDataForRender * fd = & g_FramesDataBuffers [ g_FrameIndex ] ;
g_FrameIndex = ( g_FrameIndex + 1 ) % IM_ARRAYSIZE ( g_FramesDataBuffers ) ;
// Create the Vertex and Index buffers:
size_t vertex_size = draw_data - > TotalVtxCount * sizeof ( ImDrawVert ) ;
@ -259,9 +261,9 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
{
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, fd - > 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, fd - > IndexBufferMemory , 0 , index_size , 0 , ( void * * ) ( & idx_dst ) ) ;
check_vk_result ( err ) ;
for ( int n = 0 ; n < draw_data - > CmdListsCount ; n + + )
{
@ -278,10 +280,10 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
range [ 1 ] . sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE ;
range [ 1 ] . memory = fd - > 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, fd - > VertexBufferMemory ) ;
vkUnmapMemory ( v- > Device, fd - > IndexBufferMemory ) ;
}
// Bind pipeline and descriptor sets:
@ -379,6 +381,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 ;
@ -404,17 +407,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 ) ;
}
@ -428,7 +431,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 ) ;
}
@ -444,7 +447,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:
@ -454,34 +457,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:
@ -530,6 +533,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 ;
@ -540,13 +544,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 ) ;
}
@ -563,7 +567,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 ) ;
}
@ -579,7 +583,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 ) ;
}
@ -587,10 +591,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 ) ;
}
@ -608,7 +612,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 ) ;
}
@ -706,49 +710,42 @@ 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 ;
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 ; }
ImGui_ImplVulkan_DestroyFontUploadObjects ( ) ;
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 )
@ -763,19 +760,11 @@ 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 ( 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 ( ) ;
if ( io . ConfigFlags & ImGuiConfigFlags_ViewportsEnable )
@ -787,16 +776,37 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
void ImGui_ImplVulkan_Shutdown ( )
{
ImGui_ImplVulkan_ShutdownPlatformInterface ( ) ;
ImGui_ImplVulkan_ Invalidate DeviceObjects( ) ;
ImGui_ImplVulkan_ Destroy DeviceObjects( ) ;
}
void ImGui_ImplVulkan_NewFrame ( )
{
}
// Note: this has no effect in the 'master' branch, but multi-viewports needs this to recreate swap-chains.
void ImGui_ImplVulkan_SetSwapChainMinImageCount ( int min_image_count )
{
IM_ASSERT ( min_image_count > = 2 ) ;
g_VulkanInitInfo . MinImageCount = min_image_count ;
}
// This is a public function because we require the user to pass a ImGui_ImplVulkan_FrameRenderBuffers
// structure to ImGui_ImplVulkan_RenderDrawData.
void ImGui_ImplVulkan_DestroyFrameRenderBuffers ( VkInstance instance , VkDevice device , ImGui_ImplVulkan_FrameRenderBuffers * buffers , const VkAllocationCallbacks * allocator )
{
( void ) instance ;
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 ;
}
//-------------------------------------------------------------------------
// 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:
@ -804,40 +814,14 @@ 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 ) ;
@ -904,17 +888,18 @@ 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( VkInstance instance , 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 ) ;
IM_ASSERT ( instance ! = VK_NULL_HANDLE & & physical_device ! = VK_NULL_HANDLE & & device ! = VK_NULL_HANDLE ) ;
( void ) instance ;
( void ) physical_device ;
( void ) allocator ;
// Create Command Buffers
VkResult err ;
for ( int i = 0 ; i < IM_ARRAYSIZE( wd - > Frames ) ; i + + )
for ( u int32_ t i = 0 ; i < wd- > FramesQueueSize ; i + + )
{
ImGui_ImplVulkanH_Frame Data * fd = & wd - > Frames [ i ] ;
ImGui_ImplVulkanH_Frame * fd = & wd - > Frames [ i ] ;
{
VkCommandPoolCreateInfo info = { } ;
info . sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO ;
@ -962,24 +947,21 @@ 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 ( VkInstance instance , 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 - > BackBufferCount ; i + + )
{
if ( wd - > BackBufferView [ i ] )
vkDestroyImageView ( device , wd - > BackBufferView [ i ] , allocator ) ;
if ( wd - > Framebuffer [ i ] )
vkDestroyFramebuffer ( device , wd - > Framebuffer [ i ] , allocator ) ;
}
wd - > BackBufferCount = 0 ;
for ( uint32_t i = 0 ; i < wd - > FramesQueueSize ; i + + )
ImGui_ImplVulkanH_DestroyFrame ( instance , device , & wd - > Frames [ i ] , allocator ) ;
delete [ ] wd - > Frames ;
wd - > Frames = NULL ;
wd - > FramesQueueSize = 0 ;
if ( wd - > RenderPass )
vkDestroyRenderPass ( device , wd - > RenderPass , allocator ) ;
@ -1023,10 +1005,19 @@ void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice
}
err = vkCreateSwapchainKHR ( device , & info , allocator , & wd - > Swapchain ) ;
check_vk_result ( err ) ;
err = vkGetSwapchainImagesKHR ( device , wd - > Swapchain , & wd - > BackBufferCount , NULL ) ;
err = vkGetSwapchainImagesKHR ( device , wd - > Swapchain , & wd - > FramesQueueSize , NULL ) ;
check_vk_result ( err ) ;
err = vkGetSwapchainImagesKHR ( device , wd - > Swapchain , & wd - > BackBufferCount , wd - > BackBuffer ) ;
VkImage backbuffers [ 16 ] = { } ;
IM_ASSERT ( wd - > FramesQueueSize > = min_image_count ) ;
IM_ASSERT ( wd - > FramesQueueSize < IM_ARRAYSIZE ( backbuffers ) ) ;
err = vkGetSwapchainImagesKHR ( device , wd - > Swapchain , & wd - > FramesQueueSize , backbuffers ) ;
check_vk_result ( err ) ;
IM_ASSERT ( wd - > Frames = = NULL ) ;
wd - > Frames = new ImGui_ImplVulkanH_Frame [ wd - > FramesQueueSize ] ;
memset ( wd - > Frames , 0 , sizeof ( wd - > Frames [ 0 ] ) * wd - > FramesQueueSize ) ;
for ( uint32_t i = 0 ; i < wd - > FramesQueueSize ; i + + )
wd - > Frames [ i ] . Backbuffer = backbuffers [ i ] ;
}
if ( old_swapchain )
vkDestroySwapchainKHR ( device , old_swapchain , allocator ) ;
@ -1080,10 +1071,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 - > BackBufferCount ; i + + )
for ( uint32_t i = 0 ; i < wd - > FramesQueueSize ; 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 ) ;
}
}
@ -1099,39 +1091,57 @@ void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice
info . width = wd - > Width ;
info . height = wd - > Height ;
info . layers = 1 ;
for ( uint32_t i = 0 ; i < wd - > BackBufferCount ; i + + )
for ( uint32_t i = 0 ; i < wd - > FramesQueueSize ; 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 )
{
ImGui_ImplVulkanH_CreateWindowSwapChain ( instance , physical_device , device , wd , allocator , width , height , min_image_count ) ;
ImGui_ImplVulkanH_CreateWindowCommandBuffers ( instance , 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 - > FramesQueueSize ; i + + )
ImGui_ImplVulkanH_DestroyFrame ( instance , device , & wd - > Frames [ i ] , allocator ) ;
delete [ ] wd - > Frames ;
wd - > Frames = NULL ;
vkDestroyRenderPass ( device , wd - > RenderPass , allocator ) ;
vkDestroySwapchainKHR ( device , wd - > Swapchain , allocator ) ;
vkDestroySurfaceKHR ( instance , wd - > Surface , allocator ) ;
* wd = ImGui_ImplVulkanH_Window ( ) ;
}
void ImGui_ImplVulkanH_DestroyFrame ( VkInstance instance , VkDevice device , ImGui_ImplVulkanH_Frame * fd , const VkAllocationCallbacks * allocator )
{
ImGui_ImplVulkanH_FrameData * fd = & wd - > Frames [ i ] ;
( void ) instance ;
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 ;
fd - > ImageAcquiredSemaphore = fd - > RenderCompleteSemaphore = VK_NULL_HANDLE ;
vkDestroyImageView ( device , fd - > BackbufferView , allocator ) ;
vkDestroyFramebuffer ( device , fd - > Framebuffer , allocator ) ;
ImGui_ImplVulkan_DestroyFrameRenderBuffers ( instance , device , & fd - > RenderBuffers , allocator ) ;
}
for ( uint32_t i = 0 ; i < wd - > BackBufferCount ; i + + )
{
vkDestroyImageView ( device , wd - > BackBufferView [ i ] , allocator ) ;
vkDestroyFramebuffer ( device , wd - > Framebuffer [ i ] , allocator ) ;
}
vkDestroyRenderPass ( device , wd - > RenderPass , allocator ) ;
vkDestroySwapchainKHR ( device , wd - > Swapchain , allocator ) ;
vkDestroySurfaceKHR ( instance , wd - > Surface , allocator ) ;
* wd = ImGui_ImplVulkanH_WindowData ( ) ;
}
//--------------------------------------------------------------------------------------------------------
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
@ -1143,7 +1153,7 @@ void ImGui_ImplVulkanH_DestroyWindowData(VkInstance instance, VkDevice device, I
struct ImGuiViewportDataVulkan
{
ImGui_ImplVulkanH_Window Data Window Data ;
ImGui_ImplVulkanH_Window Window ;
ImGuiViewportDataVulkan ( ) { }
~ ImGuiViewportDataVulkan ( ) { }
@ -1153,16 +1163,17 @@ static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport)
{
ImGuiViewportDataVulkan * data = IM_NEW ( ImGuiViewportDataVulkan ) ( ) ;
viewport - > RendererUserData = data ;
ImGui_ImplVulkanH_WindowData * wd = & data - > WindowData ;
ImGui_ImplVulkanH_Window * wd = & data - > Window ;
ImGui_ImplVulkan_InitInfo * v = & g_VulkanInitInfo ;
// Create surface
ImGuiPlatformIO & platform_io = ImGui : : GetPlatformIO ( ) ;
VkResult err = ( VkResult ) platform_io . Platform_CreateVkSurface ( viewport , ( ImU64 ) g_Instance, ( const void * ) g_ Allocator, ( ImU64 * ) & wd - > Surface ) ;
VkResult err = ( VkResult ) platform_io . Platform_CreateVkSurface ( viewport , ( ImU64 ) v- > Instance , ( const void * ) v - > Allocator, ( ImU64 * ) & wd - > Surface ) ;
check_vk_result ( err ) ;
// Check for WSI support
VkBool32 res ;
vkGetPhysicalDeviceSurfaceSupportKHR ( g_PhysicalDevice, g_ QueueFamily, wd - > Surface , & res ) ;
vkGetPhysicalDeviceSurfaceSupportKHR ( v- > PhysicalDevice , v - > QueueFamily, wd - > Surface , & res ) ;
if ( res ! = VK_TRUE )
{
fprintf ( stderr , " Error no WSI support on physical device 0 \n " ) ;
@ -1172,18 +1183,17 @@ static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport)
// Select Surface Format
const VkFormat requestSurfaceImageFormat [ ] = { VK_FORMAT_B8G8R8A8_UNORM , VK_FORMAT_R8G8B8A8_UNORM , VK_FORMAT_B8G8R8_UNORM , VK_FORMAT_R8G8B8_UNORM } ;
const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR ;
wd - > SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat ( g_ PhysicalDevice, wd - > Surface , requestSurfaceImageFormat , ( size_t ) IM_ARRAYSIZE ( requestSurfaceImageFormat ) , requestSurfaceColorSpace ) ;
wd - > SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat ( v- > PhysicalDevice, wd - > Surface , requestSurfaceImageFormat , ( size_t ) IM_ARRAYSIZE ( requestSurfaceImageFormat ) , requestSurfaceColorSpace ) ;
// Select Present Mode
// FIXME-VULKAN: Even thought mailbox seems to get us maximum framerate with a single window, it halves framerate with a second window etc. (w/ Nvidia and SDK 1.82.1)
VkPresentModeKHR present_modes [ ] = { VK_PRESENT_MODE_MAILBOX_KHR , VK_PRESENT_MODE_IMMEDIATE_KHR , VK_PRESENT_MODE_FIFO_KHR } ;
wd - > PresentMode = ImGui_ImplVulkanH_SelectPresentMode ( g_ PhysicalDevice, wd - > Surface , & present_modes [ 0 ] , IM_ARRAYSIZE ( present_modes ) ) ;
wd - > PresentMode = ImGui_ImplVulkanH_SelectPresentMode ( v- > PhysicalDevice, wd - > Surface , & present_modes [ 0 ] , IM_ARRAYSIZE ( present_modes ) ) ;
//printf("[vulkan] Secondary window selected PresentMode = %d\n", wd->PresentMode);
// Create SwapChain, RenderPass, Framebuffer, etc.
wd - > ClearEnable = ( viewport - > Flags & ImGuiViewportFlags_NoRendererClear ) ? false : true ;
ImGui_ImplVulkanH_CreateWindowDataCommandBuffers ( g_PhysicalDevice , g_Device , g_QueueFamily , wd , g_Allocator ) ;
ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer ( g_PhysicalDevice , g_Device , wd , g_Allocator , ( int ) viewport - > Size . x , ( int ) viewport - > Size . y ) ;
ImGui_ImplVulkanH_CreateWindow ( v - > Instance , v - > PhysicalDevice , v - > Device , wd , v - > QueueFamily , v - > Allocator , ( int ) viewport - > Size . x , ( int ) viewport - > Size . y , v - > MinImageCount ) ;
}
static void ImGui_ImplVulkan_DestroyWindow ( ImGuiViewport * viewport )
@ -1191,7 +1201,8 @@ static void ImGui_ImplVulkan_DestroyWindow(ImGuiViewport* viewport)
// The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it.
if ( ImGuiViewportDataVulkan * data = ( ImGuiViewportDataVulkan * ) viewport - > RendererUserData )
{
ImGui_ImplVulkanH_DestroyWindowData ( g_Instance , g_Device , & data - > WindowData , g_Allocator ) ;
ImGui_ImplVulkan_InitInfo * v = & g_VulkanInitInfo ;
ImGui_ImplVulkanH_DestroyWindow ( v - > Instance , v - > Device , & data - > Window , v - > Allocator ) ;
IM_DELETE ( data ) ;
}
viewport - > RendererUserData = NULL ;
@ -1202,31 +1213,34 @@ static void ImGui_ImplVulkan_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
ImGuiViewportDataVulkan * data = ( ImGuiViewportDataVulkan * ) viewport - > RendererUserData ;
if ( data = = NULL ) // This is NULL for the main viewport (which is left to the user/app to handle)
return ;
data - > WindowData . ClearEnable = ( viewport - > Flags & ImGuiViewportFlags_NoRendererClear ) ? false : true ;
ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer ( g_PhysicalDevice , g_Device , & data - > WindowData , g_Allocator , ( int ) size . x , ( int ) size . y ) ;
ImGui_ImplVulkan_InitInfo * v = & g_VulkanInitInfo ;
data - > Window . ClearEnable = ( viewport - > Flags & ImGuiViewportFlags_NoRendererClear ) ? false : true ;
ImGui_ImplVulkanH_CreateWindowSwapChain ( v - > Instance , v - > PhysicalDevice , v - > Device , & data - > Window , v - > Allocator , ( int ) size . x , ( int ) size . y , v - > MinImageCount ) ;
}
static void ImGui_ImplVulkan_RenderWindow ( ImGuiViewport * viewport , void * )
{
ImGuiViewportDataVulkan * data = ( ImGuiViewportDataVulkan * ) viewport - > RendererUserData ;
ImGui_ImplVulkanH_WindowData * wd = & data - > WindowData ;
ImGui_ImplVulkanH_Window * wd = & data - > Window ;
ImGui_ImplVulkan_InitInfo * v = & g_VulkanInitInfo ;
VkResult err ;
{
ImGui_ImplVulkanH_Frame Data * fd = & wd - > Frames [ wd - > FrameIndex ] ;
ImGui_ImplVulkanH_Frame * fd = & wd - > Frames [ wd - > FrameIndex ] ;
for ( ; ; )
{
err = vkWaitForFences ( g_ Device, 1 , & fd - > Fence , VK_TRUE , 100 ) ;
err = vkWaitForFences ( v- > Device, 1 , & fd - > Fence , VK_TRUE , 100 ) ;
if ( err = = VK_SUCCESS ) break ;
if ( err = = VK_TIMEOUT ) continue ;
check_vk_result ( err ) ;
}
{
err = vkAcquireNextImageKHR ( g_ Device, wd - > Swapchain , UINT64_MAX , fd - > ImageAcquiredSemaphore , VK_NULL_HANDLE , & fd - > Backbuffer Index) ;
err = vkAcquireNextImageKHR ( v- > Device, wd - > Swapchain , UINT64_MAX , fd - > ImageAcquiredSemaphore , VK_NULL_HANDLE , & fd - > Backbuffer Current Index) ;
check_vk_result ( err ) ;
}
IM_ASSERT ( wd - > FrameIndex = = fd - > BackbufferCurrentIndex ) ; // FIXME
{
err = vkResetCommandPool ( g_ Device, fd - > CommandPool , 0 ) ;
err = vkResetCommandPool ( v- > Device, fd - > CommandPool , 0 ) ;
check_vk_result ( err ) ;
VkCommandBufferBeginInfo info = { } ;
info . sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO ;
@ -1241,7 +1255,7 @@ static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*)
VkRenderPassBeginInfo info = { } ;
info . sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO ;
info . renderPass = wd - > RenderPass ;
info . framebuffer = wd - > Frame buffer [ fd - > Backbuffer Index] ;
info . framebuffer = wd - > Frame s [ fd - > Backbuffer Current Index] . Framebuffer ;
info . renderArea . extent . width = wd - > Width ;
info . renderArea . extent . height = wd - > Height ;
info . clearValueCount = ( viewport - > Flags & ImGuiViewportFlags_NoRendererClear ) ? 0 : 1 ;
@ -1250,10 +1264,10 @@ static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*)
}
}
ImGui_ImplVulkan_RenderDrawData ( viewport - > DrawData , wd - > Frames [ wd - > FrameIndex ] . CommandBuffer ) ;
ImGui_ImplVulkanH_Frame * fd = & wd - > Frames [ wd - > FrameIndex ] ;
ImGui_ImplVulkan_RenderDrawData ( viewport - > DrawData , fd - > CommandBuffer , & fd - > RenderBuffers ) ;
{
ImGui_ImplVulkanH_FrameData * fd = & wd - > Frames [ wd - > FrameIndex ] ;
vkCmdEndRenderPass ( fd - > CommandBuffer ) ;
{
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT ;
@ -1269,9 +1283,9 @@ static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*)
err = vkEndCommandBuffer ( fd - > CommandBuffer ) ;
check_vk_result ( err ) ;
err = vkResetFences ( g_ Device, 1 , & fd - > Fence ) ;
err = vkResetFences ( v- > Device, 1 , & fd - > Fence ) ;
check_vk_result ( err ) ;
err = vkQueueSubmit ( g_ Queue, 1 , & info , fd - > Fence ) ;
err = vkQueueSubmit ( v- > Queue, 1 , & info , fd - > Fence ) ;
check_vk_result ( err ) ;
}
}
@ -1280,22 +1294,23 @@ static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*)
static void ImGui_ImplVulkan_SwapBuffers ( ImGuiViewport * viewport , void * )
{
ImGuiViewportDataVulkan * data = ( ImGuiViewportDataVulkan * ) viewport - > RendererUserData ;
ImGui_ImplVulkanH_WindowData * wd = & data - > WindowData ;
ImGui_ImplVulkanH_Window * wd = & data - > Window ;
ImGui_ImplVulkan_InitInfo * v = & g_VulkanInitInfo ;
VkResult err ;
uint32_t PresentIndex = wd - > FrameIndex ;
ImGui_ImplVulkanH_Frame Data * fd = & wd - > Frames [ PresentIndex ] ;
ImGui_ImplVulkanH_Frame * fd = & wd - > Frames [ PresentIndex ] ;
VkPresentInfoKHR info = { } ;
info . sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR ;
info . waitSemaphoreCount = 1 ;
info . pWaitSemaphores = & fd - > RenderCompleteSemaphore ;
info . swapchainCount = 1 ;
info . pSwapchains = & wd - > Swapchain ;
info . pImageIndices = & fd - > Backbuffer Index;
err = vkQueuePresentKHR ( g_ Queue, & info ) ;
info . pImageIndices = & fd - > Backbuffer Current Index;
err = vkQueuePresentKHR ( v- > Queue, & info ) ;
check_vk_result ( err ) ;
wd - > FrameIndex = ( wd - > FrameIndex + 1 ) % IMGUI_VK_QUEUED_FRAMES ;
wd - > FrameIndex = ( wd - > FrameIndex + 1 ) % wd- > FramesQueueSize ;
}
void ImGui_ImplVulkan_InitPlatformInterface ( )