Skip to content

Commit b720c0f

Browse files
committed
Backends: Vulkan: Added convenience support for Volk via IMGUI_IMPL_VULKAN_USE_VOLK define. (#6582, #4854)
1 parent 07e8ff9 commit b720c0f

File tree

5 files changed

+55
-22
lines changed

5 files changed

+55
-22
lines changed

backends/imgui_impl_vulkan.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
// CHANGELOG
3535
// (minor and older changes stripped away, please see git history for details)
36+
// 2024-04-19: Vulkan: Added convenience support for Volk via IMGUI_IMPL_VULKAN_USE_VOLK define (you can also use IMGUI_IMPL_VULKAN_NO_PROTOTYPES + wrap Volk via ImGui_ImplVulkan_LoadFunctions().)
3637
// 2024-02-14: *BREAKING CHANGE*: Moved RenderPass parameter from ImGui_ImplVulkan_Init() function to ImGui_ImplVulkan_InitInfo structure. Not required when using dynamic rendering.
3738
// 2024-02-12: *BREAKING CHANGE*: Dynamic rendering now require filling PipelineRenderingCreateInfo structure.
3839
// 2024-01-19: Vulkan: Fixed vkAcquireNextImageKHR() validation errors in VulkanSDK 1.3.275 by allocating one extra semaphore than in-flight frames. (#7236)
@@ -108,12 +109,13 @@ void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_devi
108109

109110
// Vulkan prototypes for use with custom loaders
110111
// (see description of IMGUI_IMPL_VULKAN_NO_PROTOTYPES in imgui_impl_vulkan.h
111-
#ifdef VK_NO_PROTOTYPES
112+
#if defined(VK_NO_PROTOTYPES) && !defined(VOLK_H_)
113+
#define IMGUI_IMPL_VULKAN_USE_LOADER
112114
static bool g_FunctionsLoaded = false;
113115
#else
114116
static bool g_FunctionsLoaded = true;
115117
#endif
116-
#ifdef VK_NO_PROTOTYPES
118+
#ifdef IMGUI_IMPL_VULKAN_USE_LOADER
117119
#define IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_MAP_MACRO) \
118120
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateCommandBuffers) \
119121
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateDescriptorSets) \
@@ -184,7 +186,7 @@ static bool g_FunctionsLoaded = true;
184186
#define IMGUI_VULKAN_FUNC_DEF(func) static PFN_##func func;
185187
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_DEF)
186188
#undef IMGUI_VULKAN_FUNC_DEF
187-
#endif // VK_NO_PROTOTYPES
189+
#endif // IMGUI_IMPL_VULKAN_USE_LOADER
188190

189191
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
190192
static PFN_vkCmdBeginRenderingKHR ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR;
@@ -1048,8 +1050,8 @@ bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const ch
10481050
// Load function pointers
10491051
// You can use the default Vulkan loader using:
10501052
// ImGui_ImplVulkan_LoadFunctions([](const char* function_name, void*) { return vkGetInstanceProcAddr(your_vk_isntance, function_name); });
1051-
// But this would be equivalent to not setting VK_NO_PROTOTYPES.
1052-
#ifdef VK_NO_PROTOTYPES
1053+
// But this would be roughly equivalent to not setting VK_NO_PROTOTYPES.
1054+
#ifdef IMGUI_IMPL_VULKAN_USE_LOADER
10531055
#define IMGUI_VULKAN_FUNC_LOAD(func) \
10541056
func = reinterpret_cast<decltype(func)>(loader_func(#func, user_data)); \
10551057
if (func == nullptr) \
@@ -1078,7 +1080,7 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
10781080
if (info->UseDynamicRendering)
10791081
{
10801082
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
1081-
#ifndef VK_NO_PROTOTYPES
1083+
#ifndef IMGUI_IMPL_VULKAN_USE_LOADER
10821084
ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast<PFN_vkCmdBeginRenderingKHR>(vkGetInstanceProcAddr(info->Instance, "vkCmdBeginRenderingKHR"));
10831085
ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast<PFN_vkCmdEndRenderingKHR>(vkGetInstanceProcAddr(info->Instance, "vkCmdEndRenderingKHR"));
10841086
#endif

backends/imgui_impl_vulkan.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,20 @@
4242
// If you have no idea what this is, leave it alone!
4343
//#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES
4444

45-
// Vulkan includes
45+
// Convenience support for Volk
46+
// (you can also technically use IMGUI_IMPL_VULKAN_NO_PROTOTYPES + wrap Volk via ImGui_ImplVulkan_LoadFunctions().)
47+
//#define IMGUI_IMPL_VULKAN_USE_VOLK
48+
4649
#if defined(IMGUI_IMPL_VULKAN_NO_PROTOTYPES) && !defined(VK_NO_PROTOTYPES)
4750
#define VK_NO_PROTOTYPES
4851
#endif
4952
#if defined(VK_USE_PLATFORM_WIN32_KHR) && !defined(NOMINMAX)
5053
#define NOMINMAX
51-
#include <vulkan/vulkan.h>
54+
#endif
55+
56+
// Vulkan includes
57+
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
58+
#include <Volk/volk.h>
5259
#else
5360
#include <vulkan/vulkan.h>
5461
#endif

docs/CHANGELOG.txt

+4
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,12 @@ Other changes:
6666
mitigitate issues with reading vertex indexing limits with 16-bit indices. (#7496, #5720)
6767
- Backends: OpenGL: Detect ES3 contexts on desktop based on version string,
6868
to e.g. avoid calling glPolygonMode() on them. (#7447) [@afraidofdark, @ocornut]
69+
- Backends: Vulkan: Added convenience support for Volk via IMGUI_IMPL_VULKAN_USE_VOLK define.
70+
(you could always use IMGUI_IMPL_VULKAN_NO_PROTOTYPES + ImGui_ImplVulkan_LoadFunctions() as well).
71+
(#6582, #4854) [@adalsteinnh, @kennyalive, @ocornut]
6972
- Backends: SDL3: Fixed text inputs. Re-enable calling SDL_StartTextInput()/SDL_StopTextInput()
7073
as SDL3 no longer enables it by default. (#7452, #6306, #6071, #1953) [@Green-Sky]
74+
- Examples: GLFW+Vulkan, SDL+Vulkan: Added optional support for Volk. (#6582, #4854)
7175
- Examples: GLFW+WebGPU: Added support for WebGPU-native/Dawn (#7435, #7132) [@eliasdaler, @Zelif]
7276
- Examples: GLFW+WebGPU: Renamed example_emscripten_wgpu/ to example_glfw_wgpu/. (#7435, #7132)
7377

examples/example_glfw_vulkan/main.cpp

+17-7
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@
2121
#define GLFW_INCLUDE_NONE
2222
#define GLFW_INCLUDE_VULKAN
2323
#include <GLFW/glfw3.h>
24-
#include <vulkan/vulkan.h>
25-
//#include <vulkan/vulkan_beta.h>
24+
25+
// Volk headers
26+
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
27+
#define VOLK_IMPLEMENTATION
28+
#include <Volk/volk.h>
29+
#endif
2630

2731
// [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers.
2832
// To link with VS2010-era libraries, VS2015+ requires linking with legacy_stdio_definitions.lib, which we do using this pragma.
@@ -113,6 +117,9 @@ static VkPhysicalDevice SetupVulkan_SelectPhysicalDevice()
113117
static void SetupVulkan(ImVector<const char*> instance_extensions)
114118
{
115119
VkResult err;
120+
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
121+
volkInitialize();
122+
#endif
116123

117124
// Create Vulkan Instance
118125
{
@@ -151,17 +158,20 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
151158
create_info.ppEnabledExtensionNames = instance_extensions.Data;
152159
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
153160
check_vk_result(err);
161+
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
162+
volkLoadInstance(g_Instance);
163+
#endif
154164

155165
// Setup the debug report callback
156166
#ifdef APP_USE_VULKAN_DEBUG_REPORT
157-
auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
158-
IM_ASSERT(vkCreateDebugReportCallbackEXT != nullptr);
167+
auto f_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
168+
IM_ASSERT(f_vkCreateDebugReportCallbackEXT != nullptr);
159169
VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
160170
debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
161171
debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
162172
debug_report_ci.pfnCallback = debug_report;
163173
debug_report_ci.pUserData = nullptr;
164-
err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport);
174+
err = f_vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport);
165175
check_vk_result(err);
166176
#endif
167177
}
@@ -277,8 +287,8 @@ static void CleanupVulkan()
277287

278288
#ifdef APP_USE_VULKAN_DEBUG_REPORT
279289
// Remove the debug report callback
280-
auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT");
281-
vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator);
290+
auto f_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT");
291+
f_vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator);
282292
#endif // APP_USE_VULKAN_DEBUG_REPORT
283293

284294
vkDestroyDevice(g_Device, g_Allocator);

examples/example_sdl2_vulkan/main.cpp

+17-7
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,12 @@
2020
#include <stdlib.h> // abort
2121
#include <SDL.h>
2222
#include <SDL_vulkan.h>
23-
#include <vulkan/vulkan.h>
24-
//#include <vulkan/vulkan_beta.h>
23+
24+
// Volk headers
25+
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
26+
#define VOLK_IMPLEMENTATION
27+
#include <Volk/volk.h>
28+
#endif
2529

2630
//#define APP_USE_UNLIMITED_FRAME_RATE
2731
#ifdef _DEBUG
@@ -101,6 +105,9 @@ static VkPhysicalDevice SetupVulkan_SelectPhysicalDevice()
101105
static void SetupVulkan(ImVector<const char*> instance_extensions)
102106
{
103107
VkResult err;
108+
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
109+
volkInitialize();
110+
#endif
104111

105112
// Create Vulkan Instance
106113
{
@@ -139,17 +146,20 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
139146
create_info.ppEnabledExtensionNames = instance_extensions.Data;
140147
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
141148
check_vk_result(err);
149+
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
150+
volkLoadInstance(g_Instance);
151+
#endif
142152

143153
// Setup the debug report callback
144154
#ifdef APP_USE_VULKAN_DEBUG_REPORT
145-
auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
146-
IM_ASSERT(vkCreateDebugReportCallbackEXT != nullptr);
155+
auto f_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
156+
IM_ASSERT(f_vkCreateDebugReportCallbackEXT != nullptr);
147157
VkDebugReportCallbackCreateInfoEXT debug_report_ci = {};
148158
debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
149159
debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
150160
debug_report_ci.pfnCallback = debug_report;
151161
debug_report_ci.pUserData = nullptr;
152-
err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport);
162+
err = f_vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport);
153163
check_vk_result(err);
154164
#endif
155165
}
@@ -265,8 +275,8 @@ static void CleanupVulkan()
265275

266276
#ifdef APP_USE_VULKAN_DEBUG_REPORT
267277
// Remove the debug report callback
268-
auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT");
269-
vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator);
278+
auto f_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT");
279+
f_vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator);
270280
#endif // APP_USE_VULKAN_DEBUG_REPORT
271281

272282
vkDestroyDevice(g_Device, g_Allocator);

0 commit comments

Comments
 (0)