2018-02-22 06:05:17 +08:00
// ImGui Renderer for: Vulkan
// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..)
2018-02-06 03:34:11 +08:00
// Missing features:
// [ ] User texture binding. Changes of ImTextureID aren't supported by this binding! See https://github.com/ocornut/imgui/pull/914
2016-11-13 00:49:59 +08:00
2016-03-09 23:39:54 +08:00
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
// If you use this binding you'll need to call 5 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXX_CreateFontsTexture(), ImGui_ImplXXXX_NewFrame(), ImGui_ImplXXXX_Render() and ImGui_ImplXXXX_Shutdown().
// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp.
// https://github.com/ocornut/imgui
2018-02-17 00:20:18 +08:00
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
2018-03-02 04:11:22 +08:00
// 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-17 05:50:19 +08:00
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback, ImGui_ImplVulkan_Render() calls ImGui_ImplVulkan_RenderDrawData() itself.
2018-02-17 00:20:18 +08:00
// 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.
// 2016-11-13: Vulkan: Fix validation layer warnings and errors and redeclare gl_PerVertex.
// 2016-10-18: Vulkan: Add location decorators & change to use structs as in/out in glsl, update embedded spv (produced with glslangValidator -x). Null the released resources.
// 2016-08-27: Vulkan: Fix Vulkan example for use when a depth buffer is active.
2018-01-29 21:38:46 +08:00
# include "imgui.h"
2018-02-17 05:50:19 +08:00
# include "imgui_impl_vulkan.h"
2016-03-09 23:39:54 +08:00
2018-02-20 21:18:02 +08:00
// Vulkan data
2018-03-02 04:11:22 +08:00
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 ;
2016-03-09 23:39:54 +08:00
static VkCommandBuffer g_CommandBuffer = VK_NULL_HANDLE ;
2018-01-29 03:03:41 +08:00
static VkDeviceSize g_BufferMemoryAlignment = 256 ;
2016-03-09 23:39:54 +08:00
static VkPipelineCreateFlags g_PipelineCreateFlags = 0 ;
static int g_FrameIndex = 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 ;
static VkSampler g_FontSampler = VK_NULL_HANDLE ;
static VkDeviceMemory g_FontMemory = VK_NULL_HANDLE ;
static VkImage g_FontImage = VK_NULL_HANDLE ;
static VkImageView g_FontView = VK_NULL_HANDLE ;
static VkDeviceMemory g_VertexBufferMemory [ IMGUI_VK_QUEUED_FRAMES ] = { } ;
static VkDeviceMemory g_IndexBufferMemory [ IMGUI_VK_QUEUED_FRAMES ] = { } ;
2018-01-29 03:03:41 +08:00
static VkDeviceSize g_VertexBufferSize [ IMGUI_VK_QUEUED_FRAMES ] = { } ;
static VkDeviceSize g_IndexBufferSize [ IMGUI_VK_QUEUED_FRAMES ] = { } ;
2016-03-09 23:39:54 +08:00
static VkBuffer g_VertexBuffer [ IMGUI_VK_QUEUED_FRAMES ] = { } ;
static VkBuffer g_IndexBuffer [ IMGUI_VK_QUEUED_FRAMES ] = { } ;
static VkDeviceMemory g_UploadBufferMemory = VK_NULL_HANDLE ;
static VkBuffer g_UploadBuffer = VK_NULL_HANDLE ;
2016-11-13 10:00:36 +08:00
static uint32_t __glsl_shader_vert_spv [ ] =
2016-04-03 23:32:53 +08:00
{
2016-11-13 10:00:36 +08:00
0x07230203 , 0x00010000 , 0x00080001 , 0x0000002e , 0x00000000 , 0x00020011 , 0x00000001 , 0x0006000b ,
2016-10-19 04:40:58 +08:00
0x00000001 , 0x4c534c47 , 0x6474732e , 0x3035342e , 0x00000000 , 0x0003000e , 0x00000000 , 0x00000001 ,
0x000a000f , 0x00000000 , 0x00000004 , 0x6e69616d , 0x00000000 , 0x0000000b , 0x0000000f , 0x00000015 ,
2016-11-13 10:00:36 +08:00
0x0000001b , 0x0000001c , 0x00030003 , 0x00000002 , 0x000001c2 , 0x00040005 , 0x00000004 , 0x6e69616d ,
2016-10-19 04:40:58 +08:00
0x00000000 , 0x00030005 , 0x00000009 , 0x00000000 , 0x00050006 , 0x00000009 , 0x00000000 , 0x6f6c6f43 ,
0x00000072 , 0x00040006 , 0x00000009 , 0x00000001 , 0x00005655 , 0x00030005 , 0x0000000b , 0x0074754f ,
0x00040005 , 0x0000000f , 0x6c6f4361 , 0x0000726f , 0x00030005 , 0x00000015 , 0x00565561 , 0x00060005 ,
2016-11-13 10:00:36 +08:00
0x00000019 , 0x505f6c67 , 0x65567265 , 0x78657472 , 0x00000000 , 0x00060006 , 0x00000019 , 0x00000000 ,
0x505f6c67 , 0x7469736f , 0x006e6f69 , 0x00030005 , 0x0000001b , 0x00000000 , 0x00040005 , 0x0000001c ,
0x736f5061 , 0x00000000 , 0x00060005 , 0x0000001e , 0x73755075 , 0x6e6f4368 , 0x6e617473 , 0x00000074 ,
0x00050006 , 0x0000001e , 0x00000000 , 0x61635375 , 0x0000656c , 0x00060006 , 0x0000001e , 0x00000001 ,
0x61725475 , 0x616c736e , 0x00006574 , 0x00030005 , 0x00000020 , 0x00006370 , 0x00040047 , 0x0000000b ,
0x0000001e , 0x00000000 , 0x00040047 , 0x0000000f , 0x0000001e , 0x00000002 , 0x00040047 , 0x00000015 ,
0x0000001e , 0x00000001 , 0x00050048 , 0x00000019 , 0x00000000 , 0x0000000b , 0x00000000 , 0x00030047 ,
0x00000019 , 0x00000002 , 0x00040047 , 0x0000001c , 0x0000001e , 0x00000000 , 0x00050048 , 0x0000001e ,
0x00000000 , 0x00000023 , 0x00000000 , 0x00050048 , 0x0000001e , 0x00000001 , 0x00000023 , 0x00000008 ,
0x00030047 , 0x0000001e , 0x00000002 , 0x00020013 , 0x00000002 , 0x00030021 , 0x00000003 , 0x00000002 ,
0x00030016 , 0x00000006 , 0x00000020 , 0x00040017 , 0x00000007 , 0x00000006 , 0x00000004 , 0x00040017 ,
0x00000008 , 0x00000006 , 0x00000002 , 0x0004001e , 0x00000009 , 0x00000007 , 0x00000008 , 0x00040020 ,
0x0000000a , 0x00000003 , 0x00000009 , 0x0004003b , 0x0000000a , 0x0000000b , 0x00000003 , 0x00040015 ,
0x0000000c , 0x00000020 , 0x00000001 , 0x0004002b , 0x0000000c , 0x0000000d , 0x00000000 , 0x00040020 ,
0x0000000e , 0x00000001 , 0x00000007 , 0x0004003b , 0x0000000e , 0x0000000f , 0x00000001 , 0x00040020 ,
0x00000011 , 0x00000003 , 0x00000007 , 0x0004002b , 0x0000000c , 0x00000013 , 0x00000001 , 0x00040020 ,
0x00000014 , 0x00000001 , 0x00000008 , 0x0004003b , 0x00000014 , 0x00000015 , 0x00000001 , 0x00040020 ,
0x00000017 , 0x00000003 , 0x00000008 , 0x0003001e , 0x00000019 , 0x00000007 , 0x00040020 , 0x0000001a ,
0x00000003 , 0x00000019 , 0x0004003b , 0x0000001a , 0x0000001b , 0x00000003 , 0x0004003b , 0x00000014 ,
0x0000001c , 0x00000001 , 0x0004001e , 0x0000001e , 0x00000008 , 0x00000008 , 0x00040020 , 0x0000001f ,
0x00000009 , 0x0000001e , 0x0004003b , 0x0000001f , 0x00000020 , 0x00000009 , 0x00040020 , 0x00000021 ,
0x00000009 , 0x00000008 , 0x0004002b , 0x00000006 , 0x00000028 , 0x00000000 , 0x0004002b , 0x00000006 ,
0x00000029 , 0x3f800000 , 0x00050036 , 0x00000002 , 0x00000004 , 0x00000000 , 0x00000003 , 0x000200f8 ,
0x00000005 , 0x0004003d , 0x00000007 , 0x00000010 , 0x0000000f , 0x00050041 , 0x00000011 , 0x00000012 ,
0x0000000b , 0x0000000d , 0x0003003e , 0x00000012 , 0x00000010 , 0x0004003d , 0x00000008 , 0x00000016 ,
0x00000015 , 0x00050041 , 0x00000017 , 0x00000018 , 0x0000000b , 0x00000013 , 0x0003003e , 0x00000018 ,
0x00000016 , 0x0004003d , 0x00000008 , 0x0000001d , 0x0000001c , 0x00050041 , 0x00000021 , 0x00000022 ,
0x00000020 , 0x0000000d , 0x0004003d , 0x00000008 , 0x00000023 , 0x00000022 , 0x00050085 , 0x00000008 ,
0x00000024 , 0x0000001d , 0x00000023 , 0x00050041 , 0x00000021 , 0x00000025 , 0x00000020 , 0x00000013 ,
0x0004003d , 0x00000008 , 0x00000026 , 0x00000025 , 0x00050081 , 0x00000008 , 0x00000027 , 0x00000024 ,
0x00000026 , 0x00050051 , 0x00000006 , 0x0000002a , 0x00000027 , 0x00000000 , 0x00050051 , 0x00000006 ,
0x0000002b , 0x00000027 , 0x00000001 , 0x00070050 , 0x00000007 , 0x0000002c , 0x0000002a , 0x0000002b ,
0x00000028 , 0x00000029 , 0x00050041 , 0x00000011 , 0x0000002d , 0x0000001b , 0x0000000d , 0x0003003e ,
0x0000002d , 0x0000002c , 0x000100fd , 0x00010038
2016-03-09 23:39:54 +08:00
} ;
2016-11-13 10:00:36 +08:00
static uint32_t __glsl_shader_frag_spv [ ] =
2016-04-03 23:32:53 +08:00
{
2016-10-19 04:40:58 +08:00
0x07230203 , 0x00010000 , 0x00080001 , 0x0000001e , 0x00000000 , 0x00020011 , 0x00000001 , 0x0006000b ,
0x00000001 , 0x4c534c47 , 0x6474732e , 0x3035342e , 0x00000000 , 0x0003000e , 0x00000000 , 0x00000001 ,
0x0007000f , 0x00000004 , 0x00000004 , 0x6e69616d , 0x00000000 , 0x00000009 , 0x0000000d , 0x00030010 ,
0x00000004 , 0x00000007 , 0x00030003 , 0x00000002 , 0x000001c2 , 0x00040005 , 0x00000004 , 0x6e69616d ,
0x00000000 , 0x00040005 , 0x00000009 , 0x6c6f4366 , 0x0000726f , 0x00030005 , 0x0000000b , 0x00000000 ,
0x00050006 , 0x0000000b , 0x00000000 , 0x6f6c6f43 , 0x00000072 , 0x00040006 , 0x0000000b , 0x00000001 ,
0x00005655 , 0x00030005 , 0x0000000d , 0x00006e49 , 0x00050005 , 0x00000016 , 0x78655473 , 0x65727574 ,
0x00000000 , 0x00040047 , 0x00000009 , 0x0000001e , 0x00000000 , 0x00040047 , 0x0000000d , 0x0000001e ,
0x00000000 , 0x00040047 , 0x00000016 , 0x00000022 , 0x00000000 , 0x00040047 , 0x00000016 , 0x00000021 ,
0x00000000 , 0x00020013 , 0x00000002 , 0x00030021 , 0x00000003 , 0x00000002 , 0x00030016 , 0x00000006 ,
0x00000020 , 0x00040017 , 0x00000007 , 0x00000006 , 0x00000004 , 0x00040020 , 0x00000008 , 0x00000003 ,
0x00000007 , 0x0004003b , 0x00000008 , 0x00000009 , 0x00000003 , 0x00040017 , 0x0000000a , 0x00000006 ,
0x00000002 , 0x0004001e , 0x0000000b , 0x00000007 , 0x0000000a , 0x00040020 , 0x0000000c , 0x00000001 ,
0x0000000b , 0x0004003b , 0x0000000c , 0x0000000d , 0x00000001 , 0x00040015 , 0x0000000e , 0x00000020 ,
0x00000001 , 0x0004002b , 0x0000000e , 0x0000000f , 0x00000000 , 0x00040020 , 0x00000010 , 0x00000001 ,
0x00000007 , 0x00090019 , 0x00000013 , 0x00000006 , 0x00000001 , 0x00000000 , 0x00000000 , 0x00000000 ,
0x00000001 , 0x00000000 , 0x0003001b , 0x00000014 , 0x00000013 , 0x00040020 , 0x00000015 , 0x00000000 ,
0x00000014 , 0x0004003b , 0x00000015 , 0x00000016 , 0x00000000 , 0x0004002b , 0x0000000e , 0x00000018 ,
0x00000001 , 0x00040020 , 0x00000019 , 0x00000001 , 0x0000000a , 0x00050036 , 0x00000002 , 0x00000004 ,
0x00000000 , 0x00000003 , 0x000200f8 , 0x00000005 , 0x00050041 , 0x00000010 , 0x00000011 , 0x0000000d ,
0x0000000f , 0x0004003d , 0x00000007 , 0x00000012 , 0x00000011 , 0x0004003d , 0x00000014 , 0x00000017 ,
0x00000016 , 0x00050041 , 0x00000019 , 0x0000001a , 0x0000000d , 0x00000018 , 0x0004003d , 0x0000000a ,
0x0000001b , 0x0000001a , 0x00050057 , 0x00000007 , 0x0000001c , 0x00000017 , 0x0000001b , 0x00050085 ,
0x00000007 , 0x0000001d , 0x00000012 , 0x0000001c , 0x0003003e , 0x00000009 , 0x0000001d , 0x000100fd ,
0x00010038
2016-03-09 23:39:54 +08:00
} ;
2018-02-17 05:50:19 +08:00
static uint32_t ImGui_ImplVulkan_MemoryType ( VkMemoryPropertyFlags properties , uint32_t type_bits )
2016-03-09 23:39:54 +08:00
{
VkPhysicalDeviceMemoryProperties prop ;
2018-03-02 04:11:22 +08:00
vkGetPhysicalDeviceMemoryProperties ( g_PhysicalDevice , & prop ) ;
2016-04-03 23:32:53 +08:00
for ( uint32_t i = 0 ; i < prop . memoryTypeCount ; i + + )
if ( ( prop . memoryTypes [ i ] . propertyFlags & properties ) = = properties & & type_bits & ( 1 < < i ) )
2016-03-09 23:39:54 +08:00
return i ;
2016-03-10 19:30:38 +08:00
return 0xffffffff ; // Unable to find memoryType
2016-03-09 23:39:54 +08:00
}
2016-04-03 23:32:53 +08:00
2018-02-17 05:50:19 +08:00
static void ImGui_ImplVulkan_VkResult ( VkResult err )
2016-03-09 23:39:54 +08:00
{
2016-04-03 23:32:53 +08:00
if ( g_CheckVkResult )
2016-03-09 23:39:54 +08:00
g_CheckVkResult ( err ) ;
}
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
2018-02-17 05:50:19 +08:00
void ImGui_ImplVulkan_RenderDrawData ( ImDrawData * draw_data )
2016-03-09 23:39:54 +08:00
{
VkResult err ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
2018-02-17 05:28:52 +08:00
if ( draw_data - > TotalVtxCount = = 0 )
return ;
2016-03-09 23:39:54 +08:00
// Create the Vertex Buffer:
size_t vertex_size = draw_data - > TotalVtxCount * sizeof ( ImDrawVert ) ;
2016-04-03 23:32:53 +08:00
if ( ! g_VertexBuffer [ g_FrameIndex ] | | g_VertexBufferSize [ g_FrameIndex ] < vertex_size )
{
if ( g_VertexBuffer [ g_FrameIndex ] )
2016-03-09 23:39:54 +08:00
vkDestroyBuffer ( g_Device , g_VertexBuffer [ g_FrameIndex ] , g_Allocator ) ;
2016-04-03 23:32:53 +08:00
if ( g_VertexBufferMemory [ g_FrameIndex ] )
2016-03-09 23:39:54 +08:00
vkFreeMemory ( g_Device , g_VertexBufferMemory [ g_FrameIndex ] , g_Allocator ) ;
2018-01-29 03:03:41 +08:00
VkDeviceSize vertex_buffer_size = ( ( vertex_size - 1 ) / g_BufferMemoryAlignment + 1 ) * g_BufferMemoryAlignment ;
2016-03-09 23:39:54 +08:00
VkBufferCreateInfo buffer_info = { } ;
buffer_info . sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO ;
buffer_info . size = vertex_buffer_size ;
buffer_info . usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT ;
buffer_info . sharingMode = VK_SHARING_MODE_EXCLUSIVE ;
2016-04-03 23:32:53 +08:00
err = vkCreateBuffer ( g_Device , & buffer_info , g_Allocator , & g_VertexBuffer [ g_FrameIndex ] ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
VkMemoryRequirements req ;
vkGetBufferMemoryRequirements ( g_Device , g_VertexBuffer [ g_FrameIndex ] , & 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 ;
2018-02-17 05:50:19 +08:00
alloc_info . memoryTypeIndex = ImGui_ImplVulkan_MemoryType ( VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT , req . memoryTypeBits ) ;
2016-04-03 23:32:53 +08:00
err = vkAllocateMemory ( g_Device , & alloc_info , g_Allocator , & g_VertexBufferMemory [ g_FrameIndex ] ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-04-03 23:32:53 +08:00
err = vkBindBufferMemory ( g_Device , g_VertexBuffer [ g_FrameIndex ] , g_VertexBufferMemory [ g_FrameIndex ] , 0 ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
g_VertexBufferSize [ g_FrameIndex ] = vertex_buffer_size ;
}
2016-04-03 23:32:53 +08:00
2016-03-09 23:39:54 +08:00
// Create the Index Buffer:
size_t index_size = draw_data - > TotalIdxCount * sizeof ( ImDrawIdx ) ;
2016-04-03 23:32:53 +08:00
if ( ! g_IndexBuffer [ g_FrameIndex ] | | g_IndexBufferSize [ g_FrameIndex ] < index_size )
{
if ( g_IndexBuffer [ g_FrameIndex ] )
2016-03-09 23:39:54 +08:00
vkDestroyBuffer ( g_Device , g_IndexBuffer [ g_FrameIndex ] , g_Allocator ) ;
2016-04-03 23:32:53 +08:00
if ( g_IndexBufferMemory [ g_FrameIndex ] )
2016-03-09 23:39:54 +08:00
vkFreeMemory ( g_Device , g_IndexBufferMemory [ g_FrameIndex ] , g_Allocator ) ;
2018-01-29 03:03:41 +08:00
VkDeviceSize index_buffer_size = ( ( index_size - 1 ) / g_BufferMemoryAlignment + 1 ) * g_BufferMemoryAlignment ;
2016-03-09 23:39:54 +08:00
VkBufferCreateInfo buffer_info = { } ;
buffer_info . sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO ;
buffer_info . size = index_buffer_size ;
buffer_info . usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT ;
buffer_info . sharingMode = VK_SHARING_MODE_EXCLUSIVE ;
2016-04-03 23:32:53 +08:00
err = vkCreateBuffer ( g_Device , & buffer_info , g_Allocator , & g_IndexBuffer [ g_FrameIndex ] ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
VkMemoryRequirements req ;
vkGetBufferMemoryRequirements ( g_Device , g_IndexBuffer [ g_FrameIndex ] , & 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 ;
2018-02-17 05:50:19 +08:00
alloc_info . memoryTypeIndex = ImGui_ImplVulkan_MemoryType ( VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT , req . memoryTypeBits ) ;
2016-04-03 23:32:53 +08:00
err = vkAllocateMemory ( g_Device , & alloc_info , g_Allocator , & g_IndexBufferMemory [ g_FrameIndex ] ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-04-03 23:32:53 +08:00
err = vkBindBufferMemory ( g_Device , g_IndexBuffer [ g_FrameIndex ] , g_IndexBufferMemory [ g_FrameIndex ] , 0 ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
g_IndexBufferSize [ g_FrameIndex ] = index_buffer_size ;
}
2016-04-03 23:32:53 +08:00
2016-03-09 23:39:54 +08:00
// Upload Vertex and index Data:
{
ImDrawVert * vtx_dst ;
ImDrawIdx * idx_dst ;
2016-04-03 23:32:53 +08:00
err = vkMapMemory ( g_Device , g_VertexBufferMemory [ g_FrameIndex ] , 0 , vertex_size , 0 , ( void * * ) ( & vtx_dst ) ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-04-03 23:32:53 +08:00
err = vkMapMemory ( g_Device , g_IndexBufferMemory [ g_FrameIndex ] , 0 , index_size , 0 , ( void * * ) ( & idx_dst ) ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-04-03 23:32:53 +08:00
for ( int n = 0 ; n < draw_data - > CmdListsCount ; n + + )
{
2016-03-09 23:39:54 +08:00
const ImDrawList * cmd_list = draw_data - > CmdLists [ n ] ;
2016-09-04 01:24:57 +08:00
memcpy ( vtx_dst , cmd_list - > VtxBuffer . Data , cmd_list - > VtxBuffer . Size * sizeof ( ImDrawVert ) ) ;
memcpy ( idx_dst , cmd_list - > IdxBuffer . Data , cmd_list - > IdxBuffer . Size * sizeof ( ImDrawIdx ) ) ;
vtx_dst + = cmd_list - > VtxBuffer . Size ;
idx_dst + = cmd_list - > IdxBuffer . Size ;
2016-03-09 23:39:54 +08:00
}
VkMappedMemoryRange range [ 2 ] = { } ;
range [ 0 ] . sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE ;
range [ 0 ] . memory = g_VertexBufferMemory [ g_FrameIndex ] ;
2017-02-11 19:08:59 +08:00
range [ 0 ] . size = VK_WHOLE_SIZE ;
2016-03-09 23:39:54 +08:00
range [ 1 ] . sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE ;
range [ 1 ] . memory = g_IndexBufferMemory [ g_FrameIndex ] ;
2017-02-11 19:08:59 +08:00
range [ 1 ] . size = VK_WHOLE_SIZE ;
2016-03-09 23:39:54 +08:00
err = vkFlushMappedMemoryRanges ( g_Device , 2 , range ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
vkUnmapMemory ( g_Device , g_VertexBufferMemory [ g_FrameIndex ] ) ;
vkUnmapMemory ( g_Device , g_IndexBufferMemory [ g_FrameIndex ] ) ;
}
2016-04-03 23:32:53 +08:00
2016-03-09 23:39:54 +08:00
// Bind pipeline and descriptor sets:
{
2016-04-03 23:32:53 +08:00
vkCmdBindPipeline ( g_CommandBuffer , VK_PIPELINE_BIND_POINT_GRAPHICS , g_Pipeline ) ;
2016-03-09 23:39:54 +08:00
VkDescriptorSet desc_set [ 1 ] = { g_DescriptorSet } ;
2016-04-03 23:32:53 +08:00
vkCmdBindDescriptorSets ( g_CommandBuffer , VK_PIPELINE_BIND_POINT_GRAPHICS , g_PipelineLayout , 0 , 1 , desc_set , 0 , NULL ) ;
2016-03-09 23:39:54 +08:00
}
2016-04-03 23:32:53 +08:00
2016-03-09 23:39:54 +08:00
// Bind Vertex And Index Buffer:
{
VkBuffer vertex_buffers [ 1 ] = { g_VertexBuffer [ g_FrameIndex ] } ;
VkDeviceSize vertex_offset [ 1 ] = { 0 } ;
2016-04-03 23:32:53 +08:00
vkCmdBindVertexBuffers ( g_CommandBuffer , 0 , 1 , vertex_buffers , vertex_offset ) ;
vkCmdBindIndexBuffer ( g_CommandBuffer , g_IndexBuffer [ g_FrameIndex ] , 0 , VK_INDEX_TYPE_UINT16 ) ;
2016-03-09 23:39:54 +08:00
}
2016-04-03 23:32:53 +08:00
2016-03-09 23:39:54 +08:00
// Setup viewport:
{
VkViewport viewport ;
viewport . x = 0 ;
viewport . y = 0 ;
2018-02-19 04:15:51 +08:00
viewport . width = io . DisplaySize . x ;
viewport . height = io . DisplaySize . y ;
2016-03-09 23:39:54 +08:00
viewport . minDepth = 0.0f ;
viewport . maxDepth = 1.0f ;
vkCmdSetViewport ( g_CommandBuffer , 0 , 1 , & viewport ) ;
}
2016-04-03 23:32:53 +08:00
2016-03-09 23:39:54 +08:00
// Setup scale and translation:
2018-02-19 04:15:51 +08:00
// (Our visible imgui space lies from io.DisplayPos (top left) to io.DisplayPos+io.DisplaySize (bottom right). io.DisplayPos is typically (0,0) for single viewport applications.)
2016-03-09 23:39:54 +08:00
{
float scale [ 2 ] ;
2018-02-19 04:15:51 +08:00
scale [ 0 ] = 2.0f / io . DisplaySize . x ;
scale [ 1 ] = 2.0f / io . DisplaySize . y ;
2016-03-09 23:39:54 +08:00
float translate [ 2 ] ;
2018-02-19 04:15:51 +08:00
translate [ 0 ] = - 1.0f - io . DisplayPos . x * scale [ 0 ] ;
translate [ 1 ] = - 1.0f - io . DisplayPos . y * scale [ 1 ] ;
2016-04-03 23:32:53 +08:00
vkCmdPushConstants ( g_CommandBuffer , g_PipelineLayout , VK_SHADER_STAGE_VERTEX_BIT , sizeof ( float ) * 0 , sizeof ( float ) * 2 , scale ) ;
vkCmdPushConstants ( g_CommandBuffer , g_PipelineLayout , VK_SHADER_STAGE_VERTEX_BIT , sizeof ( float ) * 2 , sizeof ( float ) * 2 , translate ) ;
2016-03-09 23:39:54 +08:00
}
2016-04-03 23:32:53 +08:00
2016-03-09 23:39:54 +08:00
// Render the command lists:
int vtx_offset = 0 ;
int idx_offset = 0 ;
2016-04-03 23:32:53 +08:00
for ( int n = 0 ; n < draw_data - > CmdListsCount ; n + + )
{
2016-03-09 23:39:54 +08:00
const ImDrawList * cmd_list = draw_data - > CmdLists [ n ] ;
2016-09-04 01:24:57 +08:00
for ( int cmd_i = 0 ; cmd_i < cmd_list - > CmdBuffer . Size ; cmd_i + + )
2016-04-03 23:32:53 +08:00
{
2016-03-09 23:39:54 +08:00
const ImDrawCmd * pcmd = & cmd_list - > CmdBuffer [ cmd_i ] ;
2016-04-03 23:32:53 +08:00
if ( pcmd - > UserCallback )
{
2016-03-09 23:39:54 +08:00
pcmd - > UserCallback ( cmd_list , pcmd ) ;
}
2016-04-03 23:32:53 +08:00
else
{
2018-02-19 04:15:51 +08:00
// Apply scissor/clipping rectangle
// FIXME: We could clamp width/height based on clamped min/max values.
2016-03-09 23:39:54 +08:00
VkRect2D scissor ;
2018-02-19 04:15:51 +08:00
scissor . offset . x = ( int32_t ) ( pcmd - > ClipRect . x - io . DisplayPos . x ) > 0 ? ( int32_t ) ( pcmd - > ClipRect . x - io . DisplayPos . y ) : 0 ;
scissor . offset . y = ( int32_t ) ( pcmd - > ClipRect . y - io . DisplayPos . y ) > 0 ? ( int32_t ) ( pcmd - > ClipRect . y - io . DisplayPos . y ) : 0 ;
2016-08-28 01:08:24 +08:00
scissor . extent . width = ( uint32_t ) ( pcmd - > ClipRect . z - pcmd - > ClipRect . x ) ;
2017-05-01 21:26:29 +08:00
scissor . extent . height = ( uint32_t ) ( pcmd - > ClipRect . w - pcmd - > ClipRect . y + 1 ) ; // FIXME: Why +1 here?
2016-03-09 23:39:54 +08:00
vkCmdSetScissor ( g_CommandBuffer , 0 , 1 , & scissor ) ;
2018-02-19 04:15:51 +08:00
// Draw
2016-04-03 23:32:53 +08:00
vkCmdDrawIndexed ( g_CommandBuffer , pcmd - > ElemCount , 1 , idx_offset , vtx_offset , 0 ) ;
2016-03-09 23:39:54 +08:00
}
idx_offset + = pcmd - > ElemCount ;
}
2016-09-04 01:24:57 +08:00
vtx_offset + = cmd_list - > VtxBuffer . Size ;
2016-03-09 23:39:54 +08:00
}
}
2018-02-17 05:50:19 +08:00
bool ImGui_ImplVulkan_CreateFontsTexture ( VkCommandBuffer command_buffer )
2016-03-09 23:39:54 +08:00
{
ImGuiIO & io = ImGui : : GetIO ( ) ;
unsigned char * pixels ;
int width , height ;
io . Fonts - > GetTexDataAsRGBA32 ( & pixels , & width , & height ) ;
size_t upload_size = width * height * 4 * sizeof ( char ) ;
VkResult err ;
2016-04-03 23:32:53 +08:00
2016-03-09 23:39:54 +08:00
// Create the Image:
{
VkImageCreateInfo info = { } ;
info . sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO ;
info . imageType = VK_IMAGE_TYPE_2D ;
info . format = VK_FORMAT_R8G8B8A8_UNORM ;
info . extent . width = width ;
info . extent . height = height ;
info . extent . depth = 1 ;
info . mipLevels = 1 ;
info . arrayLayers = 1 ;
info . samples = VK_SAMPLE_COUNT_1_BIT ;
info . tiling = VK_IMAGE_TILING_OPTIMAL ;
2016-04-03 23:32:53 +08:00
info . usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT ;
2016-03-09 23:39:54 +08:00
info . sharingMode = VK_SHARING_MODE_EXCLUSIVE ;
info . initialLayout = VK_IMAGE_LAYOUT_UNDEFINED ;
2016-04-03 23:32:53 +08:00
err = vkCreateImage ( g_Device , & info , g_Allocator , & g_FontImage ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
VkMemoryRequirements req ;
vkGetImageMemoryRequirements ( g_Device , g_FontImage , & req ) ;
VkMemoryAllocateInfo alloc_info = { } ;
alloc_info . sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO ;
alloc_info . allocationSize = req . size ;
2018-02-17 05:50:19 +08:00
alloc_info . memoryTypeIndex = ImGui_ImplVulkan_MemoryType ( VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT , req . memoryTypeBits ) ;
2016-04-03 23:32:53 +08:00
err = vkAllocateMemory ( g_Device , & alloc_info , g_Allocator , & g_FontMemory ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
err = vkBindImageMemory ( g_Device , g_FontImage , g_FontMemory , 0 ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
}
2016-04-03 23:32:53 +08:00
2016-03-09 23:39:54 +08:00
// Create the Image View:
{
VkImageViewCreateInfo info = { } ;
info . sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO ;
info . image = g_FontImage ;
info . viewType = VK_IMAGE_VIEW_TYPE_2D ;
info . format = VK_FORMAT_R8G8B8A8_UNORM ;
info . subresourceRange . aspectMask = VK_IMAGE_ASPECT_COLOR_BIT ;
info . subresourceRange . levelCount = 1 ;
info . subresourceRange . layerCount = 1 ;
2016-04-03 23:32:53 +08:00
err = vkCreateImageView ( g_Device , & info , g_Allocator , & g_FontView ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
}
2016-04-03 23:32:53 +08:00
2016-03-09 23:39:54 +08:00
// Update the Descriptor Set:
{
VkDescriptorImageInfo desc_image [ 1 ] = { } ;
desc_image [ 0 ] . sampler = g_FontSampler ;
desc_image [ 0 ] . imageView = g_FontView ;
desc_image [ 0 ] . imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ;
VkWriteDescriptorSet write_desc [ 1 ] = { } ;
write_desc [ 0 ] . sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET ;
write_desc [ 0 ] . dstSet = g_DescriptorSet ;
write_desc [ 0 ] . descriptorCount = 1 ;
write_desc [ 0 ] . descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ;
write_desc [ 0 ] . pImageInfo = desc_image ;
2016-04-03 23:32:53 +08:00
vkUpdateDescriptorSets ( g_Device , 1 , write_desc , 0 , NULL ) ;
2016-03-09 23:39:54 +08:00
}
2016-04-03 23:32:53 +08:00
2016-03-09 23:39:54 +08:00
// Create the Upload Buffer:
{
VkBufferCreateInfo buffer_info = { } ;
buffer_info . sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO ;
buffer_info . size = upload_size ;
buffer_info . usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT ;
buffer_info . sharingMode = VK_SHARING_MODE_EXCLUSIVE ;
2016-04-03 23:32:53 +08:00
err = vkCreateBuffer ( g_Device , & buffer_info , g_Allocator , & g_UploadBuffer ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
VkMemoryRequirements req ;
vkGetBufferMemoryRequirements ( g_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 ;
2018-02-17 05:50:19 +08:00
alloc_info . memoryTypeIndex = ImGui_ImplVulkan_MemoryType ( VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT , req . memoryTypeBits ) ;
2016-04-03 23:32:53 +08:00
err = vkAllocateMemory ( g_Device , & alloc_info , g_Allocator , & g_UploadBufferMemory ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
err = vkBindBufferMemory ( g_Device , g_UploadBuffer , g_UploadBufferMemory , 0 ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
}
2016-04-03 23:32:53 +08:00
2016-03-09 23:39:54 +08:00
// Upload to Buffer:
{
2016-04-03 23:32:53 +08:00
char * map = NULL ;
err = vkMapMemory ( g_Device , g_UploadBufferMemory , 0 , upload_size , 0 , ( void * * ) ( & map ) ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
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 ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
vkUnmapMemory ( g_Device , g_UploadBufferMemory ) ;
}
2018-02-19 04:15:51 +08:00
2016-03-10 19:30:38 +08:00
// Copy to Image:
2016-03-09 23:39:54 +08:00
{
2016-03-10 19:30:38 +08:00
VkImageMemoryBarrier copy_barrier [ 1 ] = { } ;
copy_barrier [ 0 ] . sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER ;
copy_barrier [ 0 ] . dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT ;
copy_barrier [ 0 ] . oldLayout = VK_IMAGE_LAYOUT_UNDEFINED ;
copy_barrier [ 0 ] . newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ;
copy_barrier [ 0 ] . srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ;
copy_barrier [ 0 ] . dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ;
copy_barrier [ 0 ] . image = g_FontImage ;
copy_barrier [ 0 ] . subresourceRange . aspectMask = VK_IMAGE_ASPECT_COLOR_BIT ;
copy_barrier [ 0 ] . subresourceRange . levelCount = 1 ;
copy_barrier [ 0 ] . subresourceRange . layerCount = 1 ;
2016-04-03 23:32:53 +08:00
vkCmdPipelineBarrier ( command_buffer , VK_PIPELINE_STAGE_HOST_BIT , VK_PIPELINE_STAGE_TRANSFER_BIT , 0 , 0 , NULL , 0 , NULL , 1 , copy_barrier ) ;
2016-03-09 23:39:54 +08:00
VkBufferImageCopy region = { } ;
region . imageSubresource . aspectMask = VK_IMAGE_ASPECT_COLOR_BIT ;
region . imageSubresource . layerCount = 1 ;
region . imageExtent . width = width ;
region . imageExtent . height = height ;
2017-03-27 01:38:05 +08:00
region . imageExtent . depth = 1 ;
2016-04-03 23:32:53 +08:00
vkCmdCopyBufferToImage ( command_buffer , g_UploadBuffer , g_FontImage , VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL , 1 , & region ) ;
2016-03-10 19:30:38 +08:00
VkImageMemoryBarrier use_barrier [ 1 ] = { } ;
use_barrier [ 0 ] . sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER ;
use_barrier [ 0 ] . srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT ;
use_barrier [ 0 ] . dstAccessMask = VK_ACCESS_SHADER_READ_BIT ;
use_barrier [ 0 ] . oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ;
use_barrier [ 0 ] . newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ;
use_barrier [ 0 ] . srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ;
use_barrier [ 0 ] . dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ;
use_barrier [ 0 ] . image = g_FontImage ;
use_barrier [ 0 ] . subresourceRange . aspectMask = VK_IMAGE_ASPECT_COLOR_BIT ;
use_barrier [ 0 ] . subresourceRange . levelCount = 1 ;
use_barrier [ 0 ] . subresourceRange . layerCount = 1 ;
2016-04-03 23:32:53 +08:00
vkCmdPipelineBarrier ( command_buffer , VK_PIPELINE_STAGE_TRANSFER_BIT , VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT , 0 , 0 , NULL , 0 , NULL , 1 , use_barrier ) ;
2016-03-09 23:39:54 +08:00
}
2016-04-03 23:32:53 +08:00
// Store our identifier
io . Fonts - > TexID = ( void * ) ( intptr_t ) g_FontImage ;
2016-03-09 23:39:54 +08:00
return true ;
}
2018-02-17 05:50:19 +08:00
bool ImGui_ImplVulkan_CreateDeviceObjects ( )
2016-03-09 23:39:54 +08:00
{
VkResult err ;
VkShaderModule vert_module ;
VkShaderModule frag_module ;
// Create The Shader Modules:
{
VkShaderModuleCreateInfo vert_info = { } ;
vert_info . sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO ;
2016-10-19 04:40:58 +08:00
vert_info . codeSize = sizeof ( __glsl_shader_vert_spv ) ;
2016-03-09 23:39:54 +08:00
vert_info . pCode = ( uint32_t * ) __glsl_shader_vert_spv ;
err = vkCreateShaderModule ( g_Device , & vert_info , g_Allocator , & vert_module ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
VkShaderModuleCreateInfo frag_info = { } ;
frag_info . sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO ;
2016-10-19 04:40:58 +08:00
frag_info . codeSize = sizeof ( __glsl_shader_frag_spv ) ;
2016-03-09 23:39:54 +08:00
frag_info . pCode = ( uint32_t * ) __glsl_shader_frag_spv ;
err = vkCreateShaderModule ( g_Device , & frag_info , g_Allocator , & frag_module ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
}
2016-04-03 23:32:53 +08:00
if ( ! g_FontSampler )
{
2016-03-09 23:39:54 +08:00
VkSamplerCreateInfo info = { } ;
info . sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO ;
info . magFilter = VK_FILTER_LINEAR ;
info . minFilter = VK_FILTER_LINEAR ;
info . mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR ;
info . addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT ;
info . addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT ;
info . addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT ;
info . minLod = - 1000 ;
info . maxLod = 1000 ;
2017-05-01 23:07:53 +08:00
info . maxAnisotropy = 1.0f ;
2016-04-03 23:32:53 +08:00
err = vkCreateSampler ( g_Device , & info , g_Allocator , & g_FontSampler ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
}
2016-04-03 23:32:53 +08:00
if ( ! g_DescriptorSetLayout )
{
2016-03-09 23:39:54 +08:00
VkSampler sampler [ 1 ] = { g_FontSampler } ;
VkDescriptorSetLayoutBinding binding [ 1 ] = { } ;
binding [ 0 ] . descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ;
binding [ 0 ] . descriptorCount = 1 ;
binding [ 0 ] . stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT ;
binding [ 0 ] . pImmutableSamplers = sampler ;
VkDescriptorSetLayoutCreateInfo info = { } ;
info . sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO ;
info . bindingCount = 1 ;
info . pBindings = binding ;
2016-04-03 23:32:53 +08:00
err = vkCreateDescriptorSetLayout ( g_Device , & info , g_Allocator , & g_DescriptorSetLayout ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
}
2016-04-03 23:32:53 +08:00
2016-03-10 19:30:38 +08:00
// Create Descriptor Set:
2016-03-09 23:39:54 +08:00
{
VkDescriptorSetAllocateInfo alloc_info = { } ;
alloc_info . sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO ;
alloc_info . descriptorPool = g_DescriptorPool ;
alloc_info . descriptorSetCount = 1 ;
alloc_info . pSetLayouts = & g_DescriptorSetLayout ;
err = vkAllocateDescriptorSets ( g_Device , & alloc_info , & g_DescriptorSet ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
}
2016-04-03 23:32:53 +08:00
if ( ! g_PipelineLayout )
{
2016-08-20 19:08:34 +08:00
VkPushConstantRange push_constants [ 1 ] = { } ;
2016-03-09 23:39:54 +08:00
push_constants [ 0 ] . stageFlags = VK_SHADER_STAGE_VERTEX_BIT ;
push_constants [ 0 ] . offset = sizeof ( float ) * 0 ;
2016-08-20 19:08:34 +08:00
push_constants [ 0 ] . size = sizeof ( float ) * 4 ;
2016-03-09 23:39:54 +08:00
VkDescriptorSetLayout set_layout [ 1 ] = { g_DescriptorSetLayout } ;
VkPipelineLayoutCreateInfo layout_info = { } ;
layout_info . sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO ;
layout_info . setLayoutCount = 1 ;
layout_info . pSetLayouts = set_layout ;
2016-08-20 19:08:34 +08:00
layout_info . pushConstantRangeCount = 1 ;
2016-03-09 23:39:54 +08:00
layout_info . pPushConstantRanges = push_constants ;
2016-04-03 23:32:53 +08:00
err = vkCreatePipelineLayout ( g_Device , & layout_info , g_Allocator , & g_PipelineLayout ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
}
VkPipelineShaderStageCreateInfo stage [ 2 ] = { } ;
stage [ 0 ] . sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO ;
stage [ 0 ] . stage = VK_SHADER_STAGE_VERTEX_BIT ;
stage [ 0 ] . module = vert_module ;
stage [ 0 ] . pName = " main " ;
stage [ 1 ] . sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO ;
stage [ 1 ] . stage = VK_SHADER_STAGE_FRAGMENT_BIT ;
stage [ 1 ] . module = frag_module ;
stage [ 1 ] . pName = " main " ;
VkVertexInputBindingDescription binding_desc [ 1 ] = { } ;
binding_desc [ 0 ] . stride = sizeof ( ImDrawVert ) ;
binding_desc [ 0 ] . inputRate = VK_VERTEX_INPUT_RATE_VERTEX ;
VkVertexInputAttributeDescription attribute_desc [ 3 ] = { } ;
attribute_desc [ 0 ] . location = 0 ;
attribute_desc [ 0 ] . binding = binding_desc [ 0 ] . binding ;
attribute_desc [ 0 ] . format = VK_FORMAT_R32G32_SFLOAT ;
attribute_desc [ 0 ] . offset = ( size_t ) ( & ( ( ImDrawVert * ) 0 ) - > pos ) ;
attribute_desc [ 1 ] . location = 1 ;
attribute_desc [ 1 ] . binding = binding_desc [ 0 ] . binding ;
attribute_desc [ 1 ] . format = VK_FORMAT_R32G32_SFLOAT ;
attribute_desc [ 1 ] . offset = ( size_t ) ( & ( ( ImDrawVert * ) 0 ) - > uv ) ;
attribute_desc [ 2 ] . location = 2 ;
attribute_desc [ 2 ] . binding = binding_desc [ 0 ] . binding ;
attribute_desc [ 2 ] . format = VK_FORMAT_R8G8B8A8_UNORM ;
attribute_desc [ 2 ] . offset = ( size_t ) ( & ( ( ImDrawVert * ) 0 ) - > col ) ;
VkPipelineVertexInputStateCreateInfo vertex_info = { } ;
vertex_info . sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO ;
vertex_info . vertexBindingDescriptionCount = 1 ;
vertex_info . pVertexBindingDescriptions = binding_desc ;
vertex_info . vertexAttributeDescriptionCount = 3 ;
vertex_info . pVertexAttributeDescriptions = attribute_desc ;
VkPipelineInputAssemblyStateCreateInfo ia_info = { } ;
ia_info . sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO ;
ia_info . topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST ;
VkPipelineViewportStateCreateInfo viewport_info = { } ;
viewport_info . sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO ;
viewport_info . viewportCount = 1 ;
viewport_info . scissorCount = 1 ;
VkPipelineRasterizationStateCreateInfo raster_info = { } ;
raster_info . sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO ;
raster_info . polygonMode = VK_POLYGON_MODE_FILL ;
raster_info . cullMode = VK_CULL_MODE_NONE ;
raster_info . frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE ;
2016-08-28 01:08:24 +08:00
raster_info . lineWidth = 1.0f ;
2016-03-09 23:39:54 +08:00
VkPipelineMultisampleStateCreateInfo ms_info = { } ;
ms_info . sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO ;
ms_info . rasterizationSamples = VK_SAMPLE_COUNT_1_BIT ;
VkPipelineColorBlendAttachmentState color_attachment [ 1 ] = { } ;
color_attachment [ 0 ] . blendEnable = VK_TRUE ;
color_attachment [ 0 ] . srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA ;
color_attachment [ 0 ] . dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA ;
color_attachment [ 0 ] . colorBlendOp = VK_BLEND_OP_ADD ;
color_attachment [ 0 ] . srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA ;
color_attachment [ 0 ] . dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO ;
color_attachment [ 0 ] . alphaBlendOp = VK_BLEND_OP_ADD ;
2016-04-03 23:32:53 +08:00
color_attachment [ 0 ] . colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT ;
2016-03-09 23:39:54 +08:00
2016-08-28 01:08:24 +08:00
VkPipelineDepthStencilStateCreateInfo depth_info = { } ;
depth_info . sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO ;
2016-03-09 23:39:54 +08:00
VkPipelineColorBlendStateCreateInfo blend_info = { } ;
blend_info . sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO ;
blend_info . attachmentCount = 1 ;
blend_info . pAttachments = color_attachment ;
2016-04-03 23:32:53 +08:00
VkDynamicState dynamic_states [ 2 ] = { VK_DYNAMIC_STATE_VIEWPORT , VK_DYNAMIC_STATE_SCISSOR } ;
2016-03-09 23:39:54 +08:00
VkPipelineDynamicStateCreateInfo dynamic_state = { } ;
2016-08-20 19:27:03 +08:00
dynamic_state . sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO ;
dynamic_state . dynamicStateCount = 2 ;
2016-03-09 23:39:54 +08:00
dynamic_state . pDynamicStates = dynamic_states ;
VkGraphicsPipelineCreateInfo info = { } ;
info . sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO ;
info . flags = g_PipelineCreateFlags ;
info . stageCount = 2 ;
info . pStages = stage ;
info . pVertexInputState = & vertex_info ;
info . pInputAssemblyState = & ia_info ;
info . pViewportState = & viewport_info ;
info . pRasterizationState = & raster_info ;
info . pMultisampleState = & ms_info ;
2016-08-28 01:08:24 +08:00
info . pDepthStencilState = & depth_info ;
2016-03-09 23:39:54 +08:00
info . pColorBlendState = & blend_info ;
info . pDynamicState = & dynamic_state ;
info . layout = g_PipelineLayout ;
info . renderPass = g_RenderPass ;
2016-04-03 23:32:53 +08:00
err = vkCreateGraphicsPipelines ( g_Device , g_PipelineCache , 1 , & info , g_Allocator , & g_Pipeline ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_VkResult ( err ) ;
2016-03-09 23:39:54 +08:00
vkDestroyShaderModule ( g_Device , vert_module , g_Allocator ) ;
vkDestroyShaderModule ( g_Device , frag_module , g_Allocator ) ;
return true ;
}
2018-02-17 05:50:19 +08:00
void ImGui_ImplVulkan_InvalidateFontUploadObjects ( )
2016-03-09 23:39:54 +08:00
{
2016-04-03 23:32:53 +08:00
if ( g_UploadBuffer )
{
2016-03-09 23:39:54 +08:00
vkDestroyBuffer ( g_Device , g_UploadBuffer , g_Allocator ) ;
g_UploadBuffer = VK_NULL_HANDLE ;
}
2016-04-03 23:32:53 +08:00
if ( g_UploadBufferMemory )
{
2016-03-09 23:39:54 +08:00
vkFreeMemory ( g_Device , g_UploadBufferMemory , g_Allocator ) ;
g_UploadBufferMemory = VK_NULL_HANDLE ;
}
}
2016-04-03 23:32:53 +08:00
2018-02-17 05:50:19 +08:00
void ImGui_ImplVulkan_InvalidateDeviceObjects ( )
2016-03-09 23:39:54 +08:00
{
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_InvalidateFontUploadObjects ( ) ;
2016-11-13 00:49:59 +08:00
for ( int i = 0 ; i < IMGUI_VK_QUEUED_FRAMES ; i + + )
2016-04-03 23:32:53 +08:00
{
2016-11-13 00:49:59 +08:00
if ( g_VertexBuffer [ i ] ) { vkDestroyBuffer ( g_Device , g_VertexBuffer [ i ] , g_Allocator ) ; g_VertexBuffer [ i ] = VK_NULL_HANDLE ; }
if ( g_VertexBufferMemory [ i ] ) { vkFreeMemory ( g_Device , g_VertexBufferMemory [ i ] , g_Allocator ) ; g_VertexBufferMemory [ i ] = VK_NULL_HANDLE ; }
if ( g_IndexBuffer [ i ] ) { vkDestroyBuffer ( g_Device , g_IndexBuffer [ i ] , g_Allocator ) ; g_IndexBuffer [ i ] = VK_NULL_HANDLE ; }
if ( g_IndexBufferMemory [ i ] ) { vkFreeMemory ( g_Device , g_IndexBufferMemory [ i ] , g_Allocator ) ; g_IndexBufferMemory [ i ] = VK_NULL_HANDLE ; }
2016-03-09 23:39:54 +08:00
}
2016-11-13 00:49:59 +08:00
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 ; }
2016-03-09 23:39:54 +08:00
}
2018-03-02 04:11:22 +08:00
bool ImGui_ImplVulkan_Init ( ImGui_ImplVulkan_InitInfo * init_data )
2016-03-09 23:39:54 +08:00
{
2018-03-02 04:11:22 +08:00
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 ;
2016-03-09 23:39:54 +08:00
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_CreateDeviceObjects ( ) ;
2016-03-09 23:39:54 +08:00
return true ;
}
2018-02-17 05:50:19 +08:00
void ImGui_ImplVulkan_Shutdown ( )
2016-03-09 23:39:54 +08:00
{
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_InvalidateDeviceObjects ( ) ;
2016-03-09 23:39:54 +08:00
}
2018-02-17 05:50:19 +08:00
void ImGui_ImplVulkan_NewFrame ( )
2016-03-09 23:39:54 +08:00
{
}
2016-11-13 00:49:59 +08:00
2018-02-17 05:50:19 +08:00
void ImGui_ImplVulkan_Render ( VkCommandBuffer command_buffer )
2016-03-09 23:39:54 +08:00
{
g_CommandBuffer = command_buffer ;
ImGui : : Render ( ) ;
2018-02-17 05:50:19 +08:00
ImGui_ImplVulkan_RenderDrawData ( ImGui : : GetDrawData ( ) ) ;
2016-03-09 23:39:54 +08:00
g_CommandBuffer = VK_NULL_HANDLE ;
2016-04-03 23:32:53 +08:00
g_FrameIndex = ( g_FrameIndex + 1 ) % IMGUI_VK_QUEUED_FRAMES ;
2016-03-09 23:39:54 +08:00
}
2018-03-02 05:16:51 +08:00
//-------------------------------------------------------------------------
// 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
}