mirror of
https://github.com/ocornut/imgui.git
synced 2026-11-09 07:55:52 +01:00
Support multiple Vulkan contexts with custom loader.
Squashed.
This commit is contained in:
parent
6228c2e1ec
commit
1adfcb5836
@ -176,18 +176,23 @@ static bool g_FunctionsLoaded = true;
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkResetCommandPool) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkUnmapMemory) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkUpdateDescriptorSets)
|
||||
#endif // VK_NO_PROTOTYPES
|
||||
|
||||
struct ImGui_ImplVulkan_Functions
|
||||
{
|
||||
#ifdef VK_NO_PROTOTYPES
|
||||
// Define function pointers
|
||||
#define IMGUI_VULKAN_FUNC_DEF(func) static PFN_##func func;
|
||||
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_DEF)
|
||||
#define IMGUI_VULKAN_FUNC_DEF(func) PFN_##func pfn_##func;
|
||||
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_DEF)
|
||||
#undef IMGUI_VULKAN_FUNC_DEF
|
||||
#endif // VK_NO_PROTOTYPES
|
||||
|
||||
#if defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering)
|
||||
#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
static PFN_vkCmdBeginRenderingKHR ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR;
|
||||
static PFN_vkCmdEndRenderingKHR ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR;
|
||||
PFN_vkCmdBeginRenderingKHR pfn_vkCmdBeginRenderingKHR;
|
||||
PFN_vkCmdEndRenderingKHR pfn_vkCmdEndRenderingKHR;
|
||||
#endif
|
||||
};
|
||||
|
||||
// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplVulkan_RenderDrawData()
|
||||
// [Please zero-clear before use!]
|
||||
@ -236,6 +241,8 @@ struct ImGui_ImplVulkan_Data
|
||||
// Render buffers for main window
|
||||
ImGui_ImplVulkan_WindowRenderBuffers MainWindowRenderBuffers;
|
||||
|
||||
ImGui_ImplVulkan_Functions Functions;
|
||||
|
||||
ImGui_ImplVulkan_Data()
|
||||
{
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
@ -243,6 +250,82 @@ struct ImGui_ImplVulkan_Data
|
||||
}
|
||||
};
|
||||
|
||||
// Globally available function pointers used for initialization of the backend data
|
||||
static ImGui_ImplVulkan_Functions g_Functions;
|
||||
|
||||
// Shortcuts to the dynamically loaded function pointers
|
||||
// imvkFunctions must be a ImGui_ImplVulkan_Functions or an expression that resolves to an instance of this structure
|
||||
#ifdef VK_NO_PROTOTYPES
|
||||
#define vkAllocateCommandBuffers imvkFunctions.pfn_vkAllocateCommandBuffers
|
||||
#define vkAllocateDescriptorSets imvkFunctions.pfn_vkAllocateDescriptorSets
|
||||
#define vkAllocateMemory imvkFunctions.pfn_vkAllocateMemory
|
||||
#define vkBeginCommandBuffer imvkFunctions.pfn_vkBeginCommandBuffer
|
||||
#define vkBindBufferMemory imvkFunctions.pfn_vkBindBufferMemory
|
||||
#define vkBindImageMemory imvkFunctions.pfn_vkBindImageMemory
|
||||
#define vkCmdBindDescriptorSets imvkFunctions.pfn_vkCmdBindDescriptorSets
|
||||
#define vkCmdBindIndexBuffer imvkFunctions.pfn_vkCmdBindIndexBuffer
|
||||
#define vkCmdBindPipeline imvkFunctions.pfn_vkCmdBindPipeline
|
||||
#define vkCmdBindVertexBuffers imvkFunctions.pfn_vkCmdBindVertexBuffers
|
||||
#define vkCmdCopyBufferToImage imvkFunctions.pfn_vkCmdCopyBufferToImage
|
||||
#define vkCmdDrawIndexed imvkFunctions.pfn_vkCmdDrawIndexed
|
||||
#define vkCmdPipelineBarrier imvkFunctions.pfn_vkCmdPipelineBarrier
|
||||
#define vkCmdPushConstants imvkFunctions.pfn_vkCmdPushConstants
|
||||
#define vkCmdSetScissor imvkFunctions.pfn_vkCmdSetScissor
|
||||
#define vkCmdSetViewport imvkFunctions.pfn_vkCmdSetViewport
|
||||
#define vkCreateBuffer imvkFunctions.pfn_vkCreateBuffer
|
||||
#define vkCreateCommandPool imvkFunctions.pfn_vkCreateCommandPool
|
||||
#define vkCreateDescriptorSetLayout imvkFunctions.pfn_vkCreateDescriptorSetLayout
|
||||
#define vkCreateFence imvkFunctions.pfn_vkCreateFence
|
||||
#define vkCreateFramebuffer imvkFunctions.pfn_vkCreateFramebuffer
|
||||
#define vkCreateGraphicsPipelines imvkFunctions.pfn_vkCreateGraphicsPipelines
|
||||
#define vkCreateImage imvkFunctions.pfn_vkCreateImage
|
||||
#define vkCreateImageView imvkFunctions.pfn_vkCreateImageView
|
||||
#define vkCreatePipelineLayout imvkFunctions.pfn_vkCreatePipelineLayout
|
||||
#define vkCreateRenderPass imvkFunctions.pfn_vkCreateRenderPass
|
||||
#define vkCreateSampler imvkFunctions.pfn_vkCreateSampler
|
||||
#define vkCreateSemaphore imvkFunctions.pfn_vkCreateSemaphore
|
||||
#define vkCreateShaderModule imvkFunctions.pfn_vkCreateShaderModule
|
||||
#define vkCreateSwapchainKHR imvkFunctions.pfn_vkCreateSwapchainKHR
|
||||
#define vkDestroyBuffer imvkFunctions.pfn_vkDestroyBuffer
|
||||
#define vkDestroyCommandPool imvkFunctions.pfn_vkDestroyCommandPool
|
||||
#define vkDestroyDescriptorSetLayout imvkFunctions.pfn_vkDestroyDescriptorSetLayout
|
||||
#define vkDestroyFence imvkFunctions.pfn_vkDestroyFence
|
||||
#define vkDestroyFramebuffer imvkFunctions.pfn_vkDestroyFramebuffer
|
||||
#define vkDestroyImage imvkFunctions.pfn_vkDestroyImage
|
||||
#define vkDestroyImageView imvkFunctions.pfn_vkDestroyImageView
|
||||
#define vkDestroyPipeline imvkFunctions.pfn_vkDestroyPipeline
|
||||
#define vkDestroyPipelineLayout imvkFunctions.pfn_vkDestroyPipelineLayout
|
||||
#define vkDestroyRenderPass imvkFunctions.pfn_vkDestroyRenderPass
|
||||
#define vkDestroySampler imvkFunctions.pfn_vkDestroySampler
|
||||
#define vkDestroySemaphore imvkFunctions.pfn_vkDestroySemaphore
|
||||
#define vkDestroyShaderModule imvkFunctions.pfn_vkDestroyShaderModule
|
||||
#define vkDestroySurfaceKHR imvkFunctions.pfn_vkDestroySurfaceKHR
|
||||
#define vkDestroySwapchainKHR imvkFunctions.pfn_vkDestroySwapchainKHR
|
||||
#define vkDeviceWaitIdle imvkFunctions.pfn_vkDeviceWaitIdle
|
||||
#define vkEndCommandBuffer imvkFunctions.pfn_vkEndCommandBuffer
|
||||
#define vkFlushMappedMemoryRanges imvkFunctions.pfn_vkFlushMappedMemoryRanges
|
||||
#define vkFreeCommandBuffers imvkFunctions.pfn_vkFreeCommandBuffers
|
||||
#define vkFreeDescriptorSets imvkFunctions.pfn_vkFreeDescriptorSets
|
||||
#define vkFreeMemory imvkFunctions.pfn_vkFreeMemory
|
||||
#define vkGetBufferMemoryRequirements imvkFunctions.pfn_vkGetBufferMemoryRequirements
|
||||
#define vkGetImageMemoryRequirements imvkFunctions.pfn_vkGetImageMemoryRequirements
|
||||
#define vkGetPhysicalDeviceMemoryProperties imvkFunctions.pfn_vkGetPhysicalDeviceMemoryProperties
|
||||
#define vkGetPhysicalDeviceSurfaceCapabilitiesKHR imvkFunctions.pfn_vkGetPhysicalDeviceSurfaceCapabilitiesKHR
|
||||
#define vkGetPhysicalDeviceSurfaceFormatsKHR imvkFunctions.pfn_vkGetPhysicalDeviceSurfaceFormatsKHR
|
||||
#define vkGetPhysicalDeviceSurfacePresentModesKHR imvkFunctions.pfn_vkGetPhysicalDeviceSurfacePresentModesKHR
|
||||
#define vkGetSwapchainImagesKHR imvkFunctions.pfn_vkGetSwapchainImagesKHR
|
||||
#define vkMapMemory imvkFunctions.pfn_vkMapMemory
|
||||
#define vkQueueSubmit imvkFunctions.pfn_vkQueueSubmit
|
||||
#define vkQueueWaitIdle imvkFunctions.pfn_vkQueueWaitIdle
|
||||
#define vkResetCommandPool imvkFunctions.pfn_vkResetCommandPool
|
||||
#define vkUnmapMemory imvkFunctions.pfn_vkUnmapMemory
|
||||
#define vkUpdateDescriptorSets imvkFunctions.pfn_vkUpdateDescriptorSets
|
||||
#endif // VK_NO_PROTOTYPES
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
#define vkCmdBeginRenderingKHR imvkFunctions.pfn_vkCmdBeginRenderingKHR
|
||||
#define vkCmdEndRenderingKHR imvkFunctions.pfn_vkCmdEndRenderingKHR
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SHADERS
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -356,6 +439,9 @@ static uint32_t __glsl_shader_frag_spv[] =
|
||||
// FUNCTIONS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Always use the current backend's functions in public interface
|
||||
#define imvkFunctions bd->Functions
|
||||
|
||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
// FIXME: multi-context support is not tested and probably dysfunctional in this backend.
|
||||
@ -1053,16 +1139,16 @@ bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const ch
|
||||
// But this would be equivalent to not setting VK_NO_PROTOTYPES.
|
||||
#ifdef VK_NO_PROTOTYPES
|
||||
#define IMGUI_VULKAN_FUNC_LOAD(func) \
|
||||
func = reinterpret_cast<decltype(func)>(loader_func(#func, user_data)); \
|
||||
if (func == nullptr) \
|
||||
g_Functions.pfn_##func = reinterpret_cast<decltype(g_Functions.pfn_##func)>(loader_func(#func, user_data)); \
|
||||
if (g_Functions.pfn_##func == nullptr) \
|
||||
return false;
|
||||
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_LOAD)
|
||||
#undef IMGUI_VULKAN_FUNC_LOAD
|
||||
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
// Manually load those two (see #5446)
|
||||
ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(loader_func("vkCmdBeginRenderingKHR", user_data));
|
||||
ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(loader_func("vkCmdEndRenderingKHR", user_data));
|
||||
g_Functions.pfn_vkCmdBeginRenderingKHR = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(loader_func("vkCmdBeginRenderingKHR", user_data));
|
||||
g_Functions.pfn_vkCmdEndRenderingKHR = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(loader_func("vkCmdEndRenderingKHR", user_data));
|
||||
#endif
|
||||
#else
|
||||
IM_UNUSED(loader_func);
|
||||
@ -1081,11 +1167,11 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
|
||||
{
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(vkGetInstanceProcAddr(info->Instance, "vkCmdBeginRenderingKHR"));
|
||||
ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(vkGetInstanceProcAddr(info->Instance, "vkCmdEndRenderingKHR"));
|
||||
g_Functions.pfn_vkCmdBeginRenderingKHR = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(vkGetInstanceProcAddr(info->Instance, "vkCmdBeginRenderingKHR"));
|
||||
g_Functions.pfn_vkCmdEndRenderingKHR = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(vkGetInstanceProcAddr(info->Instance, "vkCmdEndRenderingKHR"));
|
||||
#endif
|
||||
IM_ASSERT(ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR != nullptr);
|
||||
IM_ASSERT(ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR != nullptr);
|
||||
IM_ASSERT(g_Functions.pfn_vkCmdBeginRenderingKHR != nullptr);
|
||||
IM_ASSERT(g_Functions.pfn_vkCmdEndRenderingKHR != nullptr);
|
||||
#else
|
||||
IM_ASSERT(0 && "Can't use dynamic rendering when neither VK_VERSION_1_3 or VK_KHR_dynamic_rendering is defined.");
|
||||
#endif
|
||||
@ -1113,6 +1199,7 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
|
||||
bd->VulkanInitInfo = *info;
|
||||
bd->RenderPass = render_pass;
|
||||
bd->Subpass = info->Subpass;
|
||||
bd->Functions = g_Functions;
|
||||
|
||||
ImGui_ImplVulkan_CreateDeviceObjects();
|
||||
|
||||
@ -1200,6 +1287,8 @@ void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set)
|
||||
|
||||
void ImGui_ImplVulkan_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkan_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
IM_UNUSED(bd); // May be unused
|
||||
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; }
|
||||
@ -1234,6 +1323,10 @@ void ImGui_ImplVulkan_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulk
|
||||
// (The ImGui_ImplVulkanH_XXX functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions)
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Use global function pointers
|
||||
#undef imvkFunctions
|
||||
#define imvkFunctions g_Functions
|
||||
|
||||
VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space)
|
||||
{
|
||||
IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user