WIP: Vulkan: DebuggingTools : Add messenger utilities #107409

Closed
Kazashi Yoshioka wants to merge 2 commits from (deleted):vk_debug_messenger into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
5 changed files with 396 additions and 5 deletions

View File

@ -530,4 +530,110 @@ VkCullModeFlags to_vk_cull_mode_flags(const eGPUFaceCullTest cull_test)
return VK_CULL_MODE_NONE;
}
const char *to_string(VkObjectType type)
{
#define __STR_VK_CHECK(s) "" #s
switch (type) {
case VK_OBJECT_TYPE_UNKNOWN:
return __STR_VK_CHECK(VK_OBJECT_TYPE_UNKNOWN);
case VK_OBJECT_TYPE_INSTANCE:
return __STR_VK_CHECK(VK_OBJECT_TYPE_INSTANCE);
case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
return __STR_VK_CHECK(VK_OBJECT_TYPE_PHYSICAL_DEVICE);
case VK_OBJECT_TYPE_DEVICE:
return __STR_VK_CHECK(VK_OBJECT_TYPE_DEVICE);
case VK_OBJECT_TYPE_QUEUE:
return __STR_VK_CHECK(VK_OBJECT_TYPE_QUEUE);
case VK_OBJECT_TYPE_SEMAPHORE:
return __STR_VK_CHECK(VK_OBJECT_TYPE_SEMAPHORE);
case VK_OBJECT_TYPE_COMMAND_BUFFER:
return __STR_VK_CHECK(VK_OBJECT_TYPE_COMMAND_BUFFER);
case VK_OBJECT_TYPE_FENCE:
return __STR_VK_CHECK(VK_OBJECT_TYPE_FENCE);
case VK_OBJECT_TYPE_DEVICE_MEMORY:
return __STR_VK_CHECK(VK_OBJECT_TYPE_DEVICE_MEMORY);
case VK_OBJECT_TYPE_BUFFER:
return __STR_VK_CHECK(VK_OBJECT_TYPE_BUFFER);
case VK_OBJECT_TYPE_IMAGE:
return __STR_VK_CHECK(VK_OBJECT_TYPE_IMAGE);
case VK_OBJECT_TYPE_EVENT:
return __STR_VK_CHECK(VK_OBJECT_TYPE_EVENT);
case VK_OBJECT_TYPE_QUERY_POOL:
return __STR_VK_CHECK(VK_OBJECT_TYPE_QUERY_POOL);
case VK_OBJECT_TYPE_BUFFER_VIEW:
return __STR_VK_CHECK(VK_OBJECT_TYPE_BUFFER_VIEW);
case VK_OBJECT_TYPE_IMAGE_VIEW:
return __STR_VK_CHECK(VK_OBJECT_TYPE_IMAGE_VIEW);
case VK_OBJECT_TYPE_SHADER_MODULE:
return __STR_VK_CHECK(VK_OBJECT_TYPE_SHADER_MODULE);
case VK_OBJECT_TYPE_PIPELINE_CACHE:
return __STR_VK_CHECK(VK_OBJECT_TYPE_PIPELINE_CACHE);
case VK_OBJECT_TYPE_PIPELINE_LAYOUT:
return __STR_VK_CHECK(VK_OBJECT_TYPE_PIPELINE_LAYOUT);
case VK_OBJECT_TYPE_RENDER_PASS:
return __STR_VK_CHECK(VK_OBJECT_TYPE_RENDER_PASS);
case VK_OBJECT_TYPE_PIPELINE:
return __STR_VK_CHECK(VK_OBJECT_TYPE_PIPELINE);
case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT:
return __STR_VK_CHECK(VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT);
case VK_OBJECT_TYPE_SAMPLER:
return __STR_VK_CHECK(VK_OBJECT_TYPE_SAMPLER);
case VK_OBJECT_TYPE_DESCRIPTOR_POOL:
return __STR_VK_CHECK(VK_OBJECT_TYPE_DESCRIPTOR_POOL);
case VK_OBJECT_TYPE_DESCRIPTOR_SET:
return __STR_VK_CHECK(VK_OBJECT_TYPE_DESCRIPTOR_SET);
case VK_OBJECT_TYPE_FRAMEBUFFER:
return __STR_VK_CHECK(VK_OBJECT_TYPE_FRAMEBUFFER);
case VK_OBJECT_TYPE_COMMAND_POOL:
return __STR_VK_CHECK(VK_OBJECT_TYPE_COMMAND_POOL);
case VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION:
return __STR_VK_CHECK(VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION);
case VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE:
return __STR_VK_CHECK(VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE);
case VK_OBJECT_TYPE_SURFACE_KHR:
return __STR_VK_CHECK(VK_OBJECT_TYPE_SURFACE_KHR);
case VK_OBJECT_TYPE_SWAPCHAIN_KHR:
return __STR_VK_CHECK(VK_OBJECT_TYPE_SWAPCHAIN_KHR);
case VK_OBJECT_TYPE_DISPLAY_KHR:
return __STR_VK_CHECK(VK_OBJECT_TYPE_DISPLAY_KHR);
case VK_OBJECT_TYPE_DISPLAY_MODE_KHR:
return __STR_VK_CHECK(VK_OBJECT_TYPE_DISPLAY_MODE_KHR);
case VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT:
return __STR_VK_CHECK(VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT);
#ifdef VK_ENABLE_BETA_EXTENSIONS
case VK_OBJECT_TYPE_VIDEO_SESSION_KHR:
return __STR_VK_CHECK(VK_OBJECT_TYPE_VIDEO_SESSION_KHR);
#endif
#ifdef VK_ENABLE_BETA_EXTENSIONS
case VK_OBJECT_TYPE_VIDEO_SESSION_PARAMETERS_KHR:
return __STR_VK_CHECK(VK_OBJECT_TYPE_VIDEO_SESSION_PARAMETERS_KHR);
#endif
case VK_OBJECT_TYPE_CU_MODULE_NVX:
return __STR_VK_CHECK(VK_OBJECT_TYPE_CU_MODULE_NVX);
case VK_OBJECT_TYPE_CU_FUNCTION_NVX:
return __STR_VK_CHECK(VK_OBJECT_TYPE_CU_FUNCTION_NVX);
case VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT:
return __STR_VK_CHECK(VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT);
case VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR:
return __STR_VK_CHECK(VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR);
case VK_OBJECT_TYPE_VALIDATION_CACHE_EXT:
return __STR_VK_CHECK(VK_OBJECT_TYPE_VALIDATION_CACHE_EXT);
case VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV:
return __STR_VK_CHECK(VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV);
case VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL:
return __STR_VK_CHECK(VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL);
case VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR:
return __STR_VK_CHECK(VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR);
case VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV:
return __STR_VK_CHECK(VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV);
case VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT:
return __STR_VK_CHECK(VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT);
case VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA:
return __STR_VK_CHECK(VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA);
default:
BLI_assert_unreachable();
}
return "NotFound";
#undef __STR_VK_CHECK
};
} // namespace blender::gpu

View File

@ -32,6 +32,7 @@ VkClearColorValue to_vk_clear_color_value(const eGPUDataFormat format, const voi
VkIndexType to_vk_index_type(const GPUIndexBufType index_type);
VkPrimitiveTopology to_vk_primitive_topology(const GPUPrimType prim_type);
VkCullModeFlags to_vk_cull_mode_flags(const eGPUFaceCullTest cull_test);
const char *to_string(VkObjectType type);
template<typename T> VkObjectType to_vk_object_type(T /*vk_obj*/)
{
@ -94,5 +95,4 @@ template<typename T> VkObjectType to_vk_object_type(T /*vk_obj*/)
#undef VK_EQ_TYPEID
return VK_OBJECT_TYPE_UNKNOWN;
}
} // namespace blender::gpu

View File

@ -36,7 +36,6 @@ VKContext::VKContext(void *ghost_window, void *ghost_context)
debug::object_label(this, vk_device_, "LogicalDevice");
debug::object_label(this, vk_queue_, "GenericQueue");
/* Initialize the memory allocator. */
VmaAllocatorCreateInfo info = {};
info.vulkanApiVersion = VK_API_VERSION_1_2;
@ -92,6 +91,10 @@ void VKContext::activate()
back_left = framebuffer;
framebuffer->bind(false);
}
debug::raise_message(0xB41CA2,
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,
"Vulkan Debug Utils Messenger is enabled. VkContext[0x%llx]",
(uintptr_t)this);
}
void VKContext::deactivate() {}

View File

@ -6,11 +6,14 @@
*/
#include "BKE_global.h"
#include "CLG_log.h"
#include "vk_backend.hh"
#include "vk_context.hh"
#include "vk_debug.hh"
static CLG_LogRef LOG = {"gpu.debug.vulkan"};
namespace blender::gpu {
void VKContext::debug_group_begin(const char *name, int)
{
@ -64,6 +67,221 @@ bool VKContext::debug_capture_scope_begin(void * /*scope*/)
void VKContext::debug_capture_scope_end(void * /*scope*/) {}
} // namespace blender::gpu
namespace blender::gpu::debug {
VKDebuggingTools::~VKDebuggingTools()
{
destroy_messenger();
};
void VKDebuggingTools::print_vulkan_version()
{
uint32_t instanceVersion = VK_API_VERSION_1_0;
assert(vkEnumerateInstanceVersion);
vkEnumerateInstanceVersion(&instanceVersion);
uint32_t major = VK_VERSION_MAJOR(instanceVersion);
uint32_t minor = VK_VERSION_MINOR(instanceVersion);
uint32_t patch = VK_VERSION_PATCH(instanceVersion);
printf("Vulkan Version:%d.%d.%d\n", major, minor, patch);
}
void VKDebuggingTools::print_labels(const VkDebugUtilsMessengerCallbackDataEXT *callback_data,
bool use_color)
{
#define COLOR_FILE \
if (use_color) { \
ss << "\x1b[2m"; \
}
#define COLOR_RESET \
if (use_color) { \
ss << "\x1b[0m"; \
}
std::stringstream ss;
if (callback_data->objectCount > 0) {
COLOR_FILE
ss << callback_data->objectCount << " Object[s] related \n";
COLOR_RESET;
for (uint32_t object = 0; object < callback_data->objectCount; ++object) {
COLOR_FILE
ss << "ObjectType[" << to_string(callback_data->pObjects[object].objectType) << "],";
ss << "Handle[" << std::hex
<< static_cast<uintptr_t>(callback_data->pObjects[object].objectHandle) << "],";
ss << "Name[" << callback_data->pObjects[object].pObjectName << "] \n";
COLOR_RESET;
}
}
if (callback_data->cmdBufLabelCount > 0) {
COLOR_FILE
ss << callback_data->cmdBufLabelCount << " Command Buffer Label[s] \n";
COLOR_RESET;
for (uint32_t label = 0; label < callback_data->cmdBufLabelCount; ++label) {
COLOR_FILE
ss << "CmdBufLabelName : " << callback_data->pCmdBufLabels[label].pLabelName << "\n";
COLOR_RESET;
}
}
if (callback_data->queueLabelCount > 0) {
COLOR_FILE
ss << callback_data->queueLabelCount << " Queue Label[s]\n";
COLOR_RESET;
for (uint32_t label = 0; label < callback_data->queueLabelCount; ++label) {
COLOR_FILE
ss << "QueueLabelName : " << callback_data->pQueueLabels[label].pLabelName << "\n";
COLOR_RESET;
}
}
printf("%s\n", ss.str().c_str());
fflush(stdout);
#undef COLOR_FILE
#undef COLOR_RESET
}
VKAPI_ATTR VkBool32 VKAPI_CALL
messenger_callback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
VkDebugUtilsMessageTypeFlagsEXT /* message_type*/,
const VkDebugUtilsMessengerCallbackDataEXT *callback_data,
void *user_data)
{
#define CONSOLE_COLOR_YELLOW "\x1b[33m"
#define CONSOLE_COLOR_RED "\x1b[31m"
#define CONSOLE_COLOR_RESET "\x1b[0m"
#define CONSOLE_COLOR_FINE "\x1b[2m"
VKDebuggingTools &debugging_tools = *reinterpret_cast<VKDebuggingTools *>(user_data);
if (debugging_tools.is_ignore(callback_data->messageIdNumber)) {
return VK_FALSE;
}
const bool use_color = CLG_color_support_get(&LOG);
bool enabled = false;
if ((message_severity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) ||
(message_severity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT)) {
if ((LOG.type->flag & CLG_FLAG_USE) && (LOG.type->level >= CLG_SEVERITY_INFO)) {
const char *format = use_color ? CONSOLE_COLOR_FINE "{0x%x}% s\n %s " CONSOLE_COLOR_RESET :
"{0x%x}% s\n %s ";
CLG_logf(LOG.type,
CLG_SEVERITY_INFO,
"",
"",
format,
callback_data->messageIdNumber,
callback_data->pMessageIdName,
callback_data->pMessage);
enabled = true;
}
}
else {
CLG_Severity clog_severity;
switch (message_severity) {
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT:
clog_severity = CLG_SEVERITY_WARN;
break;
case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT:
clog_severity = CLG_SEVERITY_ERROR;
break;
default:
BLI_assert_unreachable();
}
enabled = true;
if (clog_severity == CLG_SEVERITY_ERROR) {
const char *format = use_color ? CONSOLE_COLOR_RED "%s {0x%x}\n" CONSOLE_COLOR_RESET
" %s \n " :
" %s {0x%x}\n %s ";
CLG_logf(LOG.type,
clog_severity,
"",
"",
format,
callback_data->pMessageIdName,
callback_data->messageIdNumber,
callback_data->pMessage);
}
else if (LOG.type->level >= CLG_SEVERITY_WARN) {
const char *format = use_color ? CONSOLE_COLOR_YELLOW "%s {0x%x}\n" CONSOLE_COLOR_RESET
" %s \n " :
" %s {0x%x}\n %s ";
CLG_logf(LOG.type,
clog_severity,
"",
"",
format,
callback_data->pMessageIdName,
callback_data->messageIdNumber,
callback_data->pMessage);
}
}
if ((enabled) && ((callback_data->objectCount > 0) || (callback_data->cmdBufLabelCount > 0) ||
(callback_data->queueLabelCount > 0))) {
debugging_tools.print_labels(callback_data, use_color);
}
#undef CONSOLE_COLOR_YELLOW
#undef CONSOLE_COLOR_RED
#undef CONSOLE_COLOR_RESET
#undef CONSOLE_COLOR_FINE
return VK_TRUE;
};
VkResult VKDebuggingTools::create_messenger()
{
print_vulkan_version();
vk_message_id_number_ignored.clear();
BLI_assert(enabled);
VkDebugUtilsMessengerCreateInfoEXT create_info;
create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
create_info.pNext = nullptr;
create_info.flags = 0;
create_info.messageSeverity = message_severity;
create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
create_info.pfnUserCallback = messenger_callback;
create_info.pUserData = this;
VkResult res = vkCreateDebugUtilsMessengerEXT_r(
vk_instance_, &create_info, nullptr, &vk_debug_utils_messenger);
BLI_assert(res == VK_SUCCESS);
return res;
}
void VKDebuggingTools::destroy_messenger()
{
if (vk_debug_utils_messenger == nullptr) {
return;
}
BLI_assert(enabled);
vkDestroyDebugUtilsMessengerEXT_r(vk_instance_, vk_debug_utils_messenger, nullptr);
vk_message_id_number_ignored.clear();
vk_debug_utils_messenger = nullptr;
vk_instance_ = VK_NULL_HANDLE;
return;
}
bool VKDebuggingTools::is_ignore(int32_t id_number)
{
bool found = false;
{
std::scoped_lock lock(ignore_mutex);
found = vk_message_id_number_ignored.contains(id_number);
}
return found;
}
void VKDebuggingTools::add_group(int32_t id_number)
{
std::scoped_lock lock(ignore_mutex);
vk_message_id_number_ignored.add(id_number);
};
void VKDebuggingTools::remove_group(int32_t id_number)
{
std::scoped_lock lock(ignore_mutex);
vk_message_id_number_ignored.remove(id_number);
};
}; // namespace blender::gpu::debug
namespace blender::gpu::debug {
static void load_dynamic_functions(VKContext *context,
@ -99,6 +317,7 @@ static void load_dynamic_functions(VKContext *context,
instance_proc_addr(vk_instance, "vkSubmitDebugUtilsMessageEXT");
if (debugging_tools.vkCmdBeginDebugUtilsLabelEXT_r) {
debugging_tools.enabled = true;
debugging_tools.vk_instance_set(vk_instance);
}
}
else {
@ -121,7 +340,11 @@ bool init_callbacks(VKContext *context, PFN_vkGetInstanceProcAddr instance_proc_
{
if (instance_proc_addr) {
load_dynamic_functions(context, instance_proc_addr);
return true;
VKDebuggingTools &debuggingtools = context->debugging_tools_get();
if (!debuggingtools.enabled) {
return false;
}
return (debuggingtools.create_messenger() == VK_SUCCESS);
};
return false;
}
@ -130,6 +353,7 @@ void destroy_callbacks(VKContext *context)
{
VKDebuggingTools &debugging_tools = context->debugging_tools_get();
if (debugging_tools.enabled) {
debugging_tools.destroy_messenger();
load_dynamic_functions(context, nullptr);
}
}

View File

@ -7,17 +7,25 @@
#pragma once
#include "BKE_global.h"
#include "BLI_set.hh"
#include "BLI_string.h"
#include "vk_common.hh"
#include <mutex>
#include <typeindex>
namespace blender::gpu {
class VKContext;
namespace debug {
typedef struct VKDebuggingTools {
class VKDebuggingTools {
public:
bool enabled = false;
VkDebugUtilsMessageSeverityFlagsEXT message_severity =
VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
/* Function pointer definitions. */
PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT_r = nullptr;
PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT_r = nullptr;
@ -30,8 +38,26 @@ typedef struct VKDebuggingTools {
PFN_vkQueueInsertDebugUtilsLabelEXT vkQueueInsertDebugUtilsLabelEXT_r = nullptr;
PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT_r = nullptr;
PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT_r = nullptr;
VKDebuggingTools() = default;
~VKDebuggingTools();
bool is_ignore(int32_t id_number);
VkResult create_messenger();
void destroy_messenger();
void print_labels(const VkDebugUtilsMessengerCallbackDataEXT *callback_data, bool use_color);
void vk_instance_set(VkInstance vk_instance)
{
vk_instance_ = vk_instance;
}
} VKDebuggingTools;
private:
VkInstance vk_instance_ = VK_NULL_HANDLE;
VkDebugUtilsMessengerEXT vk_debug_utils_messenger = nullptr;
Set<int32_t> vk_message_id_number_ignored;
std::mutex ignore_mutex;
void print_vulkan_version();
void add_group(int32_t id_number);
void remove_group(int32_t id_number);
};
bool init_callbacks(VKContext *context, PFN_vkGetInstanceProcAddr instance_proc_addr);
void destroy_callbacks(VKContext *context);
@ -54,6 +80,38 @@ template<typename T> void object_label(VKContext *context, T vk_object_type, con
context, to_vk_object_type(vk_object_type), (uint64_t)vk_object_type, (const char *)label);
};
/* how to use : debug::raise_message(-12345,VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,"This is
* a raise message. %llx", (uintptr_t)vk_object); */
template<typename... Args>
void raise_message(int32_t id_number,
VkDebugUtilsMessageSeverityFlagBitsEXT vk_severity_flag_bits,
const char *fmt,
Args... args)
{
VKContext *context = VKContext::get();
if (!context) {
return;
}
VKDebuggingTools &debugging_tools = context->debugging_tools_get();
if (debugging_tools.enabled) {
char *info = BLI_sprintfN(fmt, args...);
static VkDebugUtilsMessengerCallbackDataEXT vk_call_back_data;
vk_call_back_data.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
vk_call_back_data.pNext = VK_NULL_HANDLE;
vk_call_back_data.messageIdNumber = id_number;
vk_call_back_data.pMessageIdName = "VulkanMessenger";
vk_call_back_data.objectCount = 0;
vk_call_back_data.flags = 0;
vk_call_back_data.pObjects = VK_NULL_HANDLE;
vk_call_back_data.pMessage = info;
debugging_tools.vkSubmitDebugUtilsMessageEXT_r(context->instance_get(),
vk_severity_flag_bits,
VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
&vk_call_back_data);
MEM_freeN((void *)info);
}
}
void push_marker(VKContext *context, VkCommandBuffer vk_command_buffer, const char *name);
void set_marker(VKContext *context, VkCommandBuffer vk_command_buffer, const char *name);
void pop_marker(VKContext *context, VkCommandBuffer vk_command_buffer);