Moved debug functions to vks namespace (Refs #260)

This commit is contained in:
saschawillems 2017-02-12 11:33:04 +01:00
parent b31d773b93
commit 132c2be990
5 changed files with 130 additions and 126 deletions

View file

@ -8,109 +8,112 @@
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
*/ */
#include "vulkandebug.h" #include "VulkanDebug.h"
#include <iostream> #include <iostream>
namespace vkDebug namespace vks
{ {
int validationLayerCount = 1; namespace debug
const char *validationLayerNames[] =
{ {
// This is a meta layer that enables all of the standard int validationLayerCount = 1;
// validation layers in the correct order : const char *validationLayerNames[] =
// threading, parameter_validation, device_limits, object_tracker, image, core_validation, swapchain, and unique_objects
"VK_LAYER_LUNARG_standard_validation"
};
PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallback = VK_NULL_HANDLE;
PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallback = VK_NULL_HANDLE;
PFN_vkDebugReportMessageEXT dbgBreakCallback = VK_NULL_HANDLE;
VkDebugReportCallbackEXT msgCallback;
VkBool32 messageCallback(
VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objType,
uint64_t srcObject,
size_t location,
int32_t msgCode,
const char* pLayerPrefix,
const char* pMsg,
void* pUserData)
{
// Select prefix depending on flags passed to the callback
// Note that multiple flags may be set for a single validation message
std::string prefix("");
// Error that may result in undefined behaviour
if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
{ {
prefix += "ERROR:"; // This is a meta layer that enables all of the standard
// validation layers in the correct order :
// threading, parameter_validation, device_limits, object_tracker, image, core_validation, swapchain, and unique_objects
"VK_LAYER_LUNARG_standard_validation"
}; };
// Warnings may hint at unexpected / non-spec API usage
if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallback = VK_NULL_HANDLE;
PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallback = VK_NULL_HANDLE;
PFN_vkDebugReportMessageEXT dbgBreakCallback = VK_NULL_HANDLE;
VkDebugReportCallbackEXT msgCallback;
VkBool32 messageCallback(
VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objType,
uint64_t srcObject,
size_t location,
int32_t msgCode,
const char* pLayerPrefix,
const char* pMsg,
void* pUserData)
{ {
prefix += "WARNING:"; // Select prefix depending on flags passed to the callback
}; // Note that multiple flags may be set for a single validation message
// May indicate sub-optimal usage of the API std::string prefix("");
if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
{ // Error that may result in undefined behaviour
prefix += "PERFORMANCE:"; if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT)
}; {
// Informal messages that may become handy during debugging prefix += "ERROR:";
if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) };
{ // Warnings may hint at unexpected / non-spec API usage
prefix += "INFO:"; if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT)
} {
// Diagnostic info from the Vulkan loader and layers prefix += "WARNING:";
// Usually not helpful in terms of API usage, but may help to debug layer and loader problems };
if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) // May indicate sub-optimal usage of the API
{ if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
prefix += "DEBUG:"; {
prefix += "PERFORMANCE:";
};
// Informal messages that may become handy during debugging
if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT)
{
prefix += "INFO:";
}
// Diagnostic info from the Vulkan loader and layers
// Usually not helpful in terms of API usage, but may help to debug layer and loader problems
if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT)
{
prefix += "DEBUG:";
}
// Display message to default output (console if activated)
std::cout << prefix << " [" << pLayerPrefix << "] Code " << msgCode << " : " << pMsg << "\n";
fflush(stdout);
// The return value of this callback controls wether the Vulkan call that caused
// the validation message will be aborted or not
// We return VK_FALSE as we DON'T want Vulkan calls that cause a validation message
// (and return a VkResult) to abort
// If you instead want to have calls abort, pass in VK_TRUE and the function will
// return VK_ERROR_VALIDATION_FAILED_EXT
return VK_FALSE;
} }
// Display message to default output (console if activated) void setupDebugging(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportCallbackEXT callBack)
std::cout << prefix << " [" << pLayerPrefix << "] Code " << msgCode << " : " << pMsg << "\n";
fflush(stdout);
// The return value of this callback controls wether the Vulkan call that caused
// the validation message will be aborted or not
// We return VK_FALSE as we DON'T want Vulkan calls that cause a validation message
// (and return a VkResult) to abort
// If you instead want to have calls abort, pass in VK_TRUE and the function will
// return VK_ERROR_VALIDATION_FAILED_EXT
return VK_FALSE;
}
void setupDebugging(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportCallbackEXT callBack)
{
CreateDebugReportCallback = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"));
DestroyDebugReportCallback = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"));
dbgBreakCallback = reinterpret_cast<PFN_vkDebugReportMessageEXT>(vkGetInstanceProcAddr(instance, "vkDebugReportMessageEXT"));
VkDebugReportCallbackCreateInfoEXT dbgCreateInfo = {};
dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
dbgCreateInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)messageCallback;
dbgCreateInfo.flags = flags;
VkResult err = CreateDebugReportCallback(
instance,
&dbgCreateInfo,
nullptr,
(callBack != VK_NULL_HANDLE) ? &callBack : &msgCallback);
assert(!err);
}
void freeDebugCallback(VkInstance instance)
{
if (msgCallback != VK_NULL_HANDLE)
{ {
DestroyDebugReportCallback(instance, msgCallback, nullptr); CreateDebugReportCallback = reinterpret_cast<PFN_vkCreateDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"));
DestroyDebugReportCallback = reinterpret_cast<PFN_vkDestroyDebugReportCallbackEXT>(vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"));
dbgBreakCallback = reinterpret_cast<PFN_vkDebugReportMessageEXT>(vkGetInstanceProcAddr(instance, "vkDebugReportMessageEXT"));
VkDebugReportCallbackCreateInfoEXT dbgCreateInfo = {};
dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
dbgCreateInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)messageCallback;
dbgCreateInfo.flags = flags;
VkResult err = CreateDebugReportCallback(
instance,
&dbgCreateInfo,
nullptr,
(callBack != VK_NULL_HANDLE) ? &callBack : &msgCallback);
assert(!err);
}
void freeDebugCallback(VkInstance instance)
{
if (msgCallback != VK_NULL_HANDLE)
{
DestroyDebugReportCallback(instance, msgCallback, nullptr);
}
} }
} }
namespace DebugMarker namespace debugmarker
{ {
bool active = false; bool active = false;
@ -277,6 +280,5 @@ namespace vkDebug
setObjectName(device, (uint64_t)_event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, name); setObjectName(device, (uint64_t)_event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, name);
} }
}; };
} }

View file

@ -21,38 +21,41 @@
#define GLM_FORCE_DEPTH_ZERO_TO_ONE #define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <glm/glm.hpp> #include <glm/glm.hpp>
namespace vkDebug namespace vks
{ {
// Default validation layers namespace debug
extern int validationLayerCount; {
extern const char *validationLayerNames[]; // Default validation layers
extern int validationLayerCount;
extern const char *validationLayerNames[];
// Default debug callback // Default debug callback
VkBool32 messageCallback( VkBool32 messageCallback(
VkDebugReportFlagsEXT flags, VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objType, VkDebugReportObjectTypeEXT objType,
uint64_t srcObject, uint64_t srcObject,
size_t location, size_t location,
int32_t msgCode, int32_t msgCode,
const char* pLayerPrefix, const char* pLayerPrefix,
const char* pMsg, const char* pMsg,
void* pUserData); void* pUserData);
// Load debug function pointers and set debug callback // Load debug function pointers and set debug callback
// if callBack is NULL, default message callback will be used // if callBack is NULL, default message callback will be used
void setupDebugging( void setupDebugging(
VkInstance instance, VkInstance instance,
VkDebugReportFlagsEXT flags, VkDebugReportFlagsEXT flags,
VkDebugReportCallbackEXT callBack); VkDebugReportCallbackEXT callBack);
// Clear debug callback // Clear debug callback
void freeDebugCallback(VkInstance instance); void freeDebugCallback(VkInstance instance);
}
// Setup and functions for the VK_EXT_debug_marker_extension // Setup and functions for the VK_EXT_debug_marker_extension
// Extension spec can be found at https://github.com/KhronosGroup/Vulkan-Docs/blob/1.0-VK_EXT_debug_marker/doc/specs/vulkan/appendices/VK_EXT_debug_marker.txt // Extension spec can be found at https://github.com/KhronosGroup/Vulkan-Docs/blob/1.0-VK_EXT_debug_marker/doc/specs/vulkan/appendices/VK_EXT_debug_marker.txt
// Note that the extension will only be present if run from an offline debugging application // Note that the extension will only be present if run from an offline debugging application
// The actual check for extension presence and enabling it on the device is done in the example base class // The actual check for extension presence and enabling it on the device is done in the example base class
// See VulkanExampleBase::createInstance and VulkanExampleBase::createDevice (base/vulkanexamplebase.cpp) // See VulkanExampleBase::createInstance and VulkanExampleBase::createDevice (base/vulkanexamplebase.cpp)
namespace DebugMarker namespace debugmarker
{ {
// Set to true if function pointer for the debug marker are available // Set to true if function pointer for the debug marker are available
extern bool active; extern bool active;
@ -95,5 +98,4 @@ namespace vkDebug
void setFenceName(VkDevice device, VkFence fence, const char * name); void setFenceName(VkDevice device, VkFence fence, const char * name);
void setEventName(VkDevice device, VkEvent _event, const char * name); void setEventName(VkDevice device, VkEvent _event, const char * name);
}; };
} }

View file

@ -50,8 +50,8 @@ VkResult VulkanExampleBase::createInstance(bool enableValidation)
} }
if (settings.validation) if (settings.validation)
{ {
instanceCreateInfo.enabledLayerCount = vkDebug::validationLayerCount; instanceCreateInfo.enabledLayerCount = vks::debug::validationLayerCount;
instanceCreateInfo.ppEnabledLayerNames = vkDebug::validationLayerNames; instanceCreateInfo.ppEnabledLayerNames = vks::debug::validationLayerNames;
} }
return vkCreateInstance(&instanceCreateInfo, nullptr, &instance); return vkCreateInstance(&instanceCreateInfo, nullptr, &instance);
} }
@ -164,7 +164,7 @@ void VulkanExampleBase::prepare()
{ {
if (vulkanDevice->enableDebugMarkers) if (vulkanDevice->enableDebugMarkers)
{ {
vkDebug::DebugMarker::setup(device); vks::debugmarker::setup(device);
} }
createCommandPool(); createCommandPool();
setupSwapChain(); setupSwapChain();
@ -684,7 +684,7 @@ VulkanExampleBase::~VulkanExampleBase()
if (settings.validation) if (settings.validation)
{ {
vkDebug::freeDebugCallback(instance); vks::debug::freeDebugCallback(instance);
} }
vkDestroyInstance(instance, nullptr); vkDestroyInstance(instance, nullptr);
@ -735,7 +735,7 @@ void VulkanExampleBase::initVulkan()
// For validating (debugging) an appplication the error and warning bits should suffice // For validating (debugging) an appplication the error and warning bits should suffice
VkDebugReportFlagsEXT debugReportFlags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; VkDebugReportFlagsEXT debugReportFlags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
// Additional flags include performance info, loader and layer debug messages, etc. // Additional flags include performance info, loader and layer debug messages, etc.
vkDebug::setupDebugging(instance, debugReportFlags, VK_NULL_HANDLE); vks::debug::setupDebugging(instance, debugReportFlags, VK_NULL_HANDLE);
} }
// Physical device // Physical device

View file

@ -39,7 +39,7 @@
#include "keycodes.hpp" #include "keycodes.hpp"
#include "vulkantools.h" #include "vulkantools.h"
#include "vulkandebug.h" #include "VulkanDebug.h"
#include "VulkanInitializers.hpp" #include "VulkanInitializers.hpp"
#include "VulkanDevice.hpp" #include "VulkanDevice.hpp"

View file

@ -18,7 +18,7 @@
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include "vulkantools.h" #include "vulkantools.h"
#include "vulkandebug.h" #include "VulkanDebug.h"
#include "VulkanBuffer.hpp" #include "VulkanBuffer.hpp"
#include "VulkanDevice.hpp" #include "VulkanDevice.hpp"
@ -643,9 +643,9 @@ public:
VK_CHECK_RESULT(vkBeginCommandBuffer(cmdBuffers[i], &cmdBufInfo)); VK_CHECK_RESULT(vkBeginCommandBuffer(cmdBuffers[i], &cmdBufInfo));
if (vkDebug::DebugMarker::active) if (vks::debugmarker::active)
{ {
vkDebug::DebugMarker::beginRegion(cmdBuffers[i], "Text overlay", glm::vec4(1.0f, 0.94f, 0.3f, 1.0f)); vks::debugmarker::beginRegion(cmdBuffers[i], "Text overlay", glm::vec4(1.0f, 0.94f, 0.3f, 1.0f));
} }
vkCmdBeginRenderPass(cmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdBeginRenderPass(cmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
@ -669,9 +669,9 @@ public:
vkCmdEndRenderPass(cmdBuffers[i]); vkCmdEndRenderPass(cmdBuffers[i]);
if (vkDebug::DebugMarker::active) if (vks::debugmarker::active)
{ {
vkDebug::DebugMarker::endRegion(cmdBuffers[i]); vks::debugmarker::endRegion(cmdBuffers[i]);
} }
VK_CHECK_RESULT(vkEndCommandBuffer(cmdBuffers[i])); VK_CHECK_RESULT(vkEndCommandBuffer(cmdBuffers[i]));