Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[vulkan] Support for custom Vulkan function/symbol loader #3759

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 78 additions & 1 deletion backends/imgui_impl_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,75 @@
// 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.

#include "imgui.h"
#include "imgui_impl_vulkan.h"
#include <stdio.h>

#ifdef IMGUI_IMPL_VULKAN_NO_PROTOTYPES
#define IMGUI_VULKAN_FUNCTIONS_DEF(func) static PFN_##func func;
#define IMGUI_VULKAN_FUNCTIONS_MAP(IMGUI_VULKAN_FUNCTIONS_MAP_MACRO) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkAllocateCommandBuffers) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkAllocateDescriptorSets) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkAllocateMemory) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkBindBufferMemory) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkBindImageMemory) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCmdBindDescriptorSets) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCmdBindIndexBuffer) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCmdBindPipeline) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCmdBindVertexBuffers) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCmdCopyBufferToImage) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCmdDrawIndexed) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCmdPipelineBarrier) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCmdPushConstants) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCmdSetScissor) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCmdSetViewport) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCreateBuffer) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCreateCommandPool) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCreateDescriptorSetLayout) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCreateFence) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCreateFramebuffer) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCreateGraphicsPipelines) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCreateImage) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCreateImageView) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCreatePipelineLayout) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCreateRenderPass) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCreateSampler) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCreateSemaphore) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCreateShaderModule) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkCreateSwapchainKHR) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkDestroyBuffer) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkDestroyCommandPool) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkDestroyDescriptorSetLayout) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkDestroyFence) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkDestroyFramebuffer) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkDestroyImage) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkDestroyImageView) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkDestroyPipeline) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkDestroyPipelineLayout) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkDestroyRenderPass) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkDestroySampler) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkDestroySemaphore) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkDestroyShaderModule) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkDestroySurfaceKHR) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkDestroySwapchainKHR) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkDeviceWaitIdle) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkFlushMappedMemoryRanges) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkFreeCommandBuffers) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkFreeMemory) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkGetBufferMemoryRequirements) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkGetImageMemoryRequirements) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkGetPhysicalDeviceMemoryProperties) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkGetPhysicalDeviceSurfaceFormatsKHR) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkGetPhysicalDeviceSurfacePresentModesKHR) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkGetSwapchainImagesKHR) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkMapMemory) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkUnmapMemory) \
IMGUI_VULKAN_FUNCTIONS_MAP_MACRO(vkUpdateDescriptorSets)

IMGUI_VULKAN_FUNCTIONS_MAP(IMGUI_VULKAN_FUNCTIONS_DEF)
#undef IMGUI_VULKAN_FUNCTIONS_DEF
#endif

// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplVulkan_RenderDrawData()
// [Please zero-clear before use!]
struct ImGui_ImplVulkanH_FrameRenderBuffers
Expand Down Expand Up @@ -888,6 +953,18 @@ void ImGui_ImplVulkan_DestroyDeviceObjects()

bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass)
{

#ifdef IMGUI_IMPL_VULKAN_NO_PROTOTYPES
IM_ASSERT(info->GetVulkanProcAddressFn != NULL);
#define IMGUI_VULKAN_FUNCTIONS_LOAD(func) \
func = reinterpret_cast<decltype(func)>(info->GetVulkanProcAddressFn(info->user_data, #func)); \
if(NULL == func) { \
return false; \
}
IMGUI_VULKAN_FUNCTIONS_MAP(IMGUI_VULKAN_FUNCTIONS_LOAD)
#undef IMGUI_VULKAN_FUNCTIONS_LOAD
#endif

// Setup backend capabilities flags
ImGuiIO& io = ImGui::GetIO();
io.BackendRendererName = "imgui_impl_vulkan";
Expand Down
45 changes: 32 additions & 13 deletions backends/imgui_impl_vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,44 @@

#pragma once
#include "imgui.h" // IMGUI_IMPL_API

// In order to be able to use a customized Vulkan loader instead of the default one, you can uncomment the
// underlying definition in here (not in your code) or define it as a compilation flag in your build system.
// After enabling this, the user has to provide 'GetVulkanProcAddressFn' (and 'user_data' if it was needed) in
// the 'ImGui_ImplVulkan_InitInfo' so the implementation can resolve function addresses with that.
// If you have no idea what it is, leave it alone!
//#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES

#ifdef IMGUI_IMPL_VULKAN_NO_PROTOTYPES
#define VK_NO_PROTOTYPES 1
#endif
#include <vulkan/vulkan.h>

// Initialization data, for ImGui_ImplVulkan_Init()
// [Please zero-clear before use!]
struct ImGui_ImplVulkan_InitInfo
{
VkInstance Instance;
VkPhysicalDevice PhysicalDevice;
VkDevice Device;
uint32_t QueueFamily;
VkQueue Queue;
VkPipelineCache PipelineCache;
VkDescriptorPool DescriptorPool;
uint32_t Subpass;
uint32_t MinImageCount; // >= 2
uint32_t ImageCount; // >= MinImageCount
VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT
const VkAllocationCallbacks* Allocator;
void (*CheckVkResultFn)(VkResult err);
VkInstance Instance;
VkPhysicalDevice PhysicalDevice;
VkDevice Device;
uint32_t QueueFamily;
VkQueue Queue;
VkPipelineCache PipelineCache;
VkDescriptorPool DescriptorPool;
uint32_t Subpass;
uint32_t MinImageCount; // >= 2
uint32_t ImageCount; // >= MinImageCount
VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT
const VkAllocationCallbacks* Allocator;
void (*CheckVkResultFn)(VkResult err);
#ifdef IMGUI_IMPL_VULKAN_NO_PROTOTYPES
// This function pointer is needed when the default Vulkan loader is disabled(not applicable).
// For more information look at comments before '#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES'
PFN_vkVoidFunction (*GetVulkanProcAddressFn)(void *user_data, const char* pName);
// This pointer is going to be fed to the 'GetVulkanProcAddressFn', you can use it for
// accessing contex/object that is maybe needed for the function call.
void *user_data;
#endif
};

// Called by user code
Expand Down