Files
OpenVulkano/openVulkanoCpp/Vulkan/Debuging/ValidationLayer.cpp
2020-10-28 01:13:11 +01:00

94 lines
3.2 KiB
C++

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "ValidationLayer.hpp"
#include "Base/Logger.hpp"
#include <list>
#define RENDER_DOC
namespace openVulkanoCpp::Vulkan
{
const std::initializer_list<std::string> activeValidationLayerNames = {
"VK_LAYER_LUNARG_assistant_layer",
"VK_LAYER_LUNARG_standard_validation",
//"VK_EXT_debug_marker",
#ifdef RENDER_DOC
"VK_LAYER_RENDERDOC_Capture", // RenderDoc must be open for this layer to work!
#endif
};
std::set<std::string> Debug::GetAvailableValidationLayers()
{
static std::set<std::string> availableLayers;
if (availableLayers.empty())
{
auto layers = vk::enumerateInstanceLayerProperties();
for (const auto& layer: layers)
{
availableLayers.insert(layer.layerName);
}
Logger::RENDER->debug("Available Vulkan Validation Layers: {0}", fmt::join(availableLayers, ", "));
}
return availableLayers;
}
std::vector<const char*> Debug::GetValidationLayers()
{
std::set<std::string> availableLayers = GetAvailableValidationLayers();
std::vector<const char*> layers;
for (const auto& name : activeValidationLayerNames)
{
if (availableLayers.count(name) != 0)
{
layers.push_back(name.c_str());
}
}
Logger::RENDER->debug("Active Vulkan Validation Layers: {0}", fmt::join(layers, ", "));
return layers;
}
VkBool32 ValidationLayerCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType,
uint64_t srcObject, size_t location, int32_t msgCode, const char* layerPrefix,
const char* msg, void* pUserData)
{
std::string prefix = "VK_DEBUG:";
spdlog::level::level_enum level = spdlog::level::info;
if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) level = spdlog::level::err;
else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) level = spdlog::level::warn;
else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT)
{
level = spdlog::level::warn;
prefix = "[PERF] " + prefix;
}
else if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) level = spdlog::level::debug;
Logger::RENDER->log(level, "{0} [{1}] Code {2}: {3}", prefix, layerPrefix, msgCode, msg);
return false;
}
static std::once_flag dispatcherInitFlag;
vk::DispatchLoaderDynamic dispatcher;
vk::DebugReportCallbackEXT msgCallback;
void Debug::SetupValidationLayers(const vk::Instance& instance, const vk::DebugReportFlagsEXT& flags)
{
Logger::RENDER->info("Setting up Vulkan Validation Layer");
std::call_once(dispatcherInitFlag, [&] { dispatcher.init(instance, &vkGetInstanceProcAddr); });
vk::DebugReportCallbackCreateInfoEXT dbgCreateInfo = {};
dbgCreateInfo.pfnCallback = (PFN_vkDebugReportCallbackEXT)ValidationLayerCallback;
dbgCreateInfo.flags = flags;
msgCallback = instance.createDebugReportCallbackEXT(dbgCreateInfo, nullptr, dispatcher);
Logger::RENDER->info("Vulkan Validation Layer setup");
}
void Debug::CloseValidationLayers(const vk::Instance& instance)
{
std::call_once(dispatcherInitFlag, [&] { dispatcher.init(instance, &vkGetInstanceProcAddr); });
instance.destroyDebugReportCallbackEXT(msgCallback, nullptr, dispatcher);
}
}