Skip to content

Commit 56dff3a

Browse files
ParticlePeterocornut
authored andcommitted
Vulkan backend: optionally enabling vulkan validation layers and debug report callback
Additional layer, extension and the callback itself are used/created when IMGUI_VULKAN_DEBUG_REPORT is defined. The callback reports seven (potential!) errors which will be fixed with another pull request.
1 parent 55be2f0 commit 56dff3a

File tree

1 file changed

+66
-5
lines changed

1 file changed

+66
-5
lines changed

examples/vulkan_example/main.cpp

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
#include "imgui_impl_glfw_vulkan.h"
1313

1414
#define IMGUI_MAX_POSSIBLE_BACK_BUFFERS 16
15-
#define IMGUI_UNLIMITED_FRAME_RATE
15+
#define IMGUI_UNLIMITED_FRAME_RATE
16+
#define IMGUI_VULKAN_DEBUG_REPORT
1617

1718
static VkAllocationCallbacks* g_Allocator = NULL;
1819
static VkInstance g_Instance = VK_NULL_HANDLE;
@@ -23,6 +24,7 @@ static VkSwapchainKHR g_Swapchain = VK_NULL_HANDLE;
2324
static VkRenderPass g_RenderPass = VK_NULL_HANDLE;
2425
static uint32_t g_QueueFamily = 0;
2526
static VkQueue g_Queue = VK_NULL_HANDLE;
27+
static VkDebugReportCallbackEXT g_Debug_Report = VK_NULL_HANDLE;
2628

2729
static VkFormat g_ImageFormat = VK_FORMAT_B8G8R8A8_UNORM;
2830
static VkFormat g_ViewFormat = VK_FORMAT_B8G8R8A8_UNORM;
@@ -89,7 +91,7 @@ static void resize_vulkan(GLFWwindow* /*window*/, int w, int h)
8991
info.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
9092
#else
9193
info.presentMode = VK_PRESENT_MODE_FIFO_KHR;
92-
#endif
94+
#endif // IMGUI_UNLIMITED_FRAME_RATE
9395
info.clipped = VK_TRUE;
9496
info.oldSwapchain = old_swapchain;
9597
VkSurfaceCapabilitiesKHR cap;
@@ -191,20 +193,71 @@ static void resize_vulkan(GLFWwindow* /*window*/, int w, int h)
191193
}
192194
}
193195

196+
#ifdef IMGUI_VULKAN_DEBUG_REPORT
197+
static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(
198+
VkDebugReportFlagsEXT, //flags,
199+
VkDebugReportObjectTypeEXT objectType,
200+
uint64_t, //object,
201+
size_t, //location,
202+
int32_t, //messageCode,
203+
const char*, //pLayerPrefix,
204+
const char* pMessage,
205+
void*) //pUserData)
206+
{
207+
printf( "ObjectType : %i\nMessage : %s\n\n", objectType, pMessage );
208+
return VK_FALSE;
209+
}
210+
#endif // IMGUI_VULKAN_DEBUG_REPORT
211+
194212
static void setup_vulkan(GLFWwindow* window)
195213
{
196214
VkResult err;
197215

198216
// Create Vulkan Instance
199217
{
200-
uint32_t glfw_extensions_count;
201-
const char** glfw_extensions = glfwGetRequiredInstanceExtensions(&glfw_extensions_count);
218+
uint32_t extensions_count;
219+
const char** glfw_extensions = glfwGetRequiredInstanceExtensions(&extensions_count);
220+
202221
VkInstanceCreateInfo create_info = {};
203222
create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
204-
create_info.enabledExtensionCount = glfw_extensions_count;
223+
#ifdef IMGUI_VULKAN_DEBUG_REPORT
224+
// enabling multiple validation layers grouped as lunarg standard validation
225+
const char* layers[] = {"VK_LAYER_LUNARG_standard_validation"};
226+
create_info.enabledLayerCount = 1;
227+
create_info.ppEnabledLayerNames = layers;
228+
229+
// need additional storage for char pointer to debug report extension
230+
const char** extensions = (const char**)malloc(sizeof(const char*) * (extensions_count + 1));
231+
for(size_t i = 0; i < extensions_count; i++)
232+
extensions[i] = glfw_extensions[i];
233+
extensions[ extensions_count ] = "VK_EXT_debug_report";
234+
create_info.enabledExtensionCount = extensions_count+1;
235+
create_info.ppEnabledExtensionNames = extensions;
236+
#elif
237+
create_info.enabledExtensionCount = extensions_count;
205238
create_info.ppEnabledExtensionNames = glfw_extensions;
239+
#endif // IMGUI_VULKAN_DEBUG_REPORT
240+
206241
err = vkCreateInstance(&create_info, g_Allocator, &g_Instance);
207242
check_vk_result(err);
243+
244+
#ifdef IMGUI_VULKAN_DEBUG_REPORT
245+
free(extensions);
246+
247+
// create the debug report callback
248+
VkDebugReportCallbackCreateInfoEXT debug_report_ci ={};
249+
debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
250+
debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
251+
debug_report_ci.pfnCallback = debug_report;
252+
debug_report_ci.pUserData = NULL;
253+
254+
// get the proc address of the function pointer, required for used extensions
255+
PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT =
256+
(PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT");
257+
258+
err = vkCreateDebugReportCallbackEXT( g_Instance, &debug_report_ci, g_Allocator, &g_Debug_Report );
259+
check_vk_result( err );
260+
#endif // IMGUI_VULKAN_DEBUG_REPORT
208261
}
209262

210263
// Create Window Surface
@@ -381,6 +434,14 @@ static void cleanup_vulkan()
381434
vkDestroyRenderPass(g_Device, g_RenderPass, g_Allocator);
382435
vkDestroySwapchainKHR(g_Device, g_Swapchain, g_Allocator);
383436
vkDestroySurfaceKHR(g_Instance, g_Surface, g_Allocator);
437+
438+
#ifdef IMGUI_VULKAN_DEBUG_REPORT
439+
// get the proc address of the function pointer, required for used extensions
440+
auto vkDestroyDebugReportCallbackEXT =
441+
(PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT");
442+
vkDestroyDebugReportCallbackEXT(g_Instance, g_Debug_Report, g_Allocator);
443+
#endif // IMGUI_VULKAN_DEBUG_REPORT
444+
384445
vkDestroyDevice(g_Device, g_Allocator);
385446
vkDestroyInstance(g_Instance, g_Allocator);
386447
}

0 commit comments

Comments
 (0)