From bc011fc4d78442d1f0167b04aea3484c62e0a92b Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 3 May 2016 12:19:55 +0800 Subject: [PATCH] vulkan: add DebugReportLogger Add DebugReportLogger that can be used during vkCreateInstance and other commands. Add vulkan::driver::Logger to create a temporary DebugReportLogger from a dispatchable object. With them, we can log to debug report by, for example, Logger(instance).Warn(obj, "failed with %s", err); Bug: 28120066 Change-Id: If059d38d3cfcfe591031ca135695d08cad42e0a4 --- vulkan/libvulkan/debug_report.cpp | 42 ++++++++++++++++++++ vulkan/libvulkan/debug_report.h | 80 ++++++++++++++++++++++++++++++++++++++- vulkan/libvulkan/driver.h | 5 +++ 3 files changed, 126 insertions(+), 1 deletion(-) diff --git a/vulkan/libvulkan/debug_report.cpp b/vulkan/libvulkan/debug_report.cpp index 24784071e7..2a34613180 100644 --- a/vulkan/libvulkan/debug_report.cpp +++ b/vulkan/libvulkan/debug_report.cpp @@ -69,6 +69,48 @@ void DebugReportCallbackList::Message(VkDebugReportFlagsEXT flags, } } +void DebugReportLogger::Message(VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT object_type, + uint64_t object, + size_t location, + int32_t message_code, + const char* layer_prefix, + const char* message) const { + const VkDebugReportCallbackCreateInfoEXT* info = + reinterpret_cast( + instance_pnext_); + while (info) { + if (info->sType == VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) { + info->pfnCallback(flags, object_type, object, location, + message_code, layer_prefix, message, + info->pUserData); + } + + info = reinterpret_cast( + info->pNext); + } + + if (callbacks_) { + callbacks_->Message(flags, object_type, object, location, message_code, + layer_prefix, message); + } +} + +void DebugReportLogger::PrintV(VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT object_type, + uint64_t object, + const char* format, + va_list ap) const { + char buf[1024]; + int len = vsnprintf(buf, sizeof(buf), format, ap); + + // message truncated + if (len >= static_cast(sizeof(buf))) + memcpy(buf + sizeof(buf) - 4, "...", 4); + + Message(flags, object_type, object, 0, 0, LOG_TAG, buf); +} + VkResult CreateDebugReportCallbackEXT( VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* create_info, diff --git a/vulkan/libvulkan/debug_report.h b/vulkan/libvulkan/debug_report.h index 6f70f18088..be9b645aa7 100644 --- a/vulkan/libvulkan/debug_report.h +++ b/vulkan/libvulkan/debug_report.h @@ -17,8 +17,9 @@ #ifndef LIBVULKAN_DEBUG_REPORT_H #define LIBVULKAN_DEBUG_REPORT_H 1 -#include +#include #include +#include namespace vulkan { namespace driver { @@ -82,6 +83,83 @@ class DebugReportCallbackList { Node head_; }; +class DebugReportLogger { + public: + DebugReportLogger(const VkInstanceCreateInfo& info) + : instance_pnext_(info.pNext), callbacks_(nullptr) {} + DebugReportLogger(const DebugReportCallbackList& callbacks) + : instance_pnext_(nullptr), callbacks_(&callbacks) {} + + void Message(VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT object_type, + uint64_t object, + size_t location, + int32_t message_code, + const char* layer_prefix, + const char* message) const; + +#define DEBUG_REPORT_LOGGER_PRINTF(fmt, args) \ + __attribute__((format(printf, (fmt) + 1, (args) + 1))) + template + void Info(ObjectType object, const char* format, ...) const + DEBUG_REPORT_LOGGER_PRINTF(2, 3) { + va_list ap; + va_start(ap, format); + PrintV(VK_DEBUG_REPORT_INFORMATION_BIT_EXT, GetObjectType(object), + GetObjectUInt64(object), format, ap); + va_end(ap); + } + + template + void Warn(ObjectType object, const char* format, ...) const + DEBUG_REPORT_LOGGER_PRINTF(2, 3) { + va_list ap; + va_start(ap, format); + PrintV(VK_DEBUG_REPORT_WARNING_BIT_EXT, GetObjectType(object), + GetObjectUInt64(object), format, ap); + va_end(ap); + } + + template + void Err(ObjectType object, const char* format, ...) const + DEBUG_REPORT_LOGGER_PRINTF(2, 3) { + va_list ap; + va_start(ap, format); + PrintV(VK_DEBUG_REPORT_ERROR_BIT_EXT, GetObjectType(object), + GetObjectUInt64(object), format, ap); + va_end(ap); + } + + private: + template + static VkDebugReportObjectTypeEXT GetObjectType(ObjectType) { + if (std::is_same::value) + return VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT; + else if (std::is_same::value) + return VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT; + else if (std::is_same::value) + return VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT; + else + return VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT; + } + + template + static uint64_t GetObjectUInt64(ObjectType object) { + return uint64_t(object); + } + +#define DEBUG_REPORT_LOGGER_VPRINTF(fmt) \ + __attribute__((format(printf, (fmt) + 1, 0))) + void PrintV(VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT object_type, + uint64_t object, + const char* format, + va_list ap) const DEBUG_REPORT_LOGGER_VPRINTF(4); + + const void* const instance_pnext_; + const DebugReportCallbackList* const callbacks_; +}; + } // namespace driver } // namespace vulkan diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h index 9a3c1411dc..210c3c7323 100644 --- a/vulkan/libvulkan/driver.h +++ b/vulkan/libvulkan/driver.h @@ -219,6 +219,11 @@ inline DeviceData& GetData(DeviceDispatchable dispatchable) { return *reinterpret_cast(GetDataInternal(dispatchable)); } +template +const DebugReportLogger Logger(DispatchableType dispatchable) { + return DebugReportLogger(GetData(dispatchable).debug_report_callbacks); +} + } // namespace driver } // namespace vulkan -- 2.11.0