Move Vulkan debug callback to module

This commit is contained in:
Lynix
2020-04-13 15:12:58 +02:00
parent 7447875753
commit e905c3a004
11 changed files with 366 additions and 95 deletions

View File

@@ -102,13 +102,28 @@ namespace Nz
createFlags = static_cast<VkInstanceCreateFlags>(iParam);
std::vector<const char*> enabledLayers;
std::vector<const char*> enabledExtensions;
// Get supported layer list
std::unordered_set<std::string> availableLayers;
std::vector<VkLayerProperties> layerList;
if (Vk::Loader::EnumerateInstanceLayerProperties(&layerList))
{
for (VkLayerProperties& extProperty : layerList)
availableLayers.insert(extProperty.layerName);
}
if (!parameters.GetBooleanParameter("VkInstanceInfo_OverrideEnabledLayers", &bParam) || !bParam)
{
//< Nazara default layers goes here
#ifdef NAZARA_DEBUG
// Enable Vulkan validation if available in debug mode
if (availableLayers.count("VK_LAYER_LUNARG_standard_validation"))
enabledLayers.push_back("VK_LAYER_LUNARG_standard_validation");
#endif
}
std::vector<const char*> enabledExtensions;
std::vector<String> additionalLayers; // Just to keep the String alive
if (parameters.GetIntegerParameter("VkInstanceInfo_EnabledLayerCount", &iParam))
{
@@ -127,7 +142,7 @@ namespace Nz
}
}
// Get extension list
// Get supported extension list
std::unordered_set<std::string> availableExtensions;
std::vector<VkExtensionProperties> extensionList;
if (Vk::Loader::EnumerateInstanceExtensionProperties(&extensionList))
@@ -138,30 +153,26 @@ namespace Nz
if (!parameters.GetBooleanParameter("VkInstanceInfo_OverrideEnabledExtensions", &bParam) || !bParam)
{
enabledExtensions.push_back("VK_KHR_surface");
enabledExtensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
#ifdef VK_USE_PLATFORM_ANDROID_KHR
enabledExtensions.push_back("VK_KHR_android_surface");
#endif
#ifdef VK_USE_PLATFORM_MIR_KHR
enabledExtensions.push_back("VK_KHR_mir_surface");
enabledExtensions.push_back(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
enabledExtensions.push_back("VK_KHR_xcb_surface");
enabledExtensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
enabledExtensions.push_back("VK_KHR_xlib_surface");
enabledExtensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
enabledExtensions.push_back("VK_KHR_wayland_surface");
enabledExtensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
enabledExtensions.push_back("VK_KHR_win32_surface");
enabledExtensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
#endif
if (availableExtensions.count(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))

View File

@@ -5,19 +5,85 @@
#include <Nazara/VulkanRenderer/Wrapper/Instance.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/VulkanRenderer/Wrapper/DebugUtilsMessengerEXT.hpp>
#include <Nazara/VulkanRenderer/Utils.hpp>
#include <sstream>
#include <Nazara/VulkanRenderer/Debug.hpp>
namespace Nz
{
namespace Vk
{
namespace
{
VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* /*pUserData*/)
{
std::stringstream ss;
ss << "Vulkan log: ";
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT)
ss << "[Verbose]";
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT)
ss << "[Info]";
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
ss << "[Warning]";
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
ss << "[Error]";
if (messageTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT)
ss << "[General]";
if (messageTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT)
ss << "[Performance]";
if (messageTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT)
ss << "[Validation]";
ss << "[" << pCallbackData->messageIdNumber << ":" << pCallbackData->pMessageIdName << "]: " << pCallbackData->pMessage;
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
NazaraError(ss.str());
else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
NazaraWarning(ss.str());
else
NazaraNotice(ss.str());
return VK_FALSE; //< Should the Vulkan call be aborted
}
}
struct Instance::InternalData
{
DebugUtilsMessengerEXT debugMessenger;
};
Instance::Instance() :
m_instance(nullptr)
{
}
Instance::~Instance()
{
if (m_instance)
DestroyInstance();
}
bool Instance::Create(const VkInstanceCreateInfo& createInfo, const VkAllocationCallbacks* allocator)
{
m_lastErrorCode = Loader::vkCreateInstance(&createInfo, allocator, &m_instance);
if (m_lastErrorCode != VkResult::VK_SUCCESS)
{
NazaraError("Failed to create Vulkan instance");
NazaraError("Failed to create Vulkan instance: " + TranslateVulkanError(m_lastErrorCode));
return false;
}
@@ -64,6 +130,9 @@ namespace Nz
return false;
}
m_internalData = std::make_unique<InternalData>();
InstallDebugMessageCallback();
return true;
}
@@ -140,6 +209,38 @@ namespace Nz
return true;
}
void Instance::InstallDebugMessageCallback()
{
NazaraAssert(m_internalData, "Instance must be created before callbacks are installed");
if (!Vk::DebugUtilsMessengerEXT::IsSupported(*this))
{
NazaraWarning(VK_EXT_DEBUG_UTILS_EXTENSION_NAME " is not supported, cannot install debug message callback");
return;
}
VkDebugUtilsMessengerCreateInfoEXT callbackCreateInfo = { VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT };
callbackCreateInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
callbackCreateInfo.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;
callbackCreateInfo.pfnUserCallback = &DebugCallback;
if (!m_internalData->debugMessenger.Create(*this, callbackCreateInfo))
{
NazaraWarning("failed to install debug message callback");
return;
}
}
void Instance::DestroyInstance()
{
assert(m_instance != VK_NULL_HANDLE);
m_internalData.reset();
if (vkDestroyInstance)
vkDestroyInstance(m_instance, (m_allocator.pfnAllocation) ? &m_allocator : nullptr);
}
void Instance::ResetPointers()
{
assert(m_instance != VK_NULL_HANDLE);