116 lines
3.9 KiB
C++
116 lines
3.9 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 OpenVulkano::Vulkan
|
|
{
|
|
const std::initializer_list<std::string> activeValidationLayerNames = {
|
|
"VK_LAYER_LUNARG_assistant_layer",
|
|
"VK_LAYER_LUNARG_standard_validation",
|
|
"VK_LAYER_KHRONOS_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.data());
|
|
}
|
|
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;
|
|
}
|
|
|
|
#if VK_HEADER_VERSION > 303
|
|
VkBool32 ValidationLayerCallback(vk::DebugReportFlagsEXT flags, vk::DebugReportObjectTypeEXT 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::DebugReportFlagBitsEXT::eError) level = spdlog::level::err;
|
|
else if (flags & vk::DebugReportFlagBitsEXT::eWarning) level = spdlog::level::warn;
|
|
else if (flags & vk::DebugReportFlagBitsEXT::ePerformanceWarning)
|
|
{
|
|
level = spdlog::level::warn;
|
|
prefix = "[PERF] " + prefix;
|
|
}
|
|
else if (flags & vk::DebugReportFlagBitsEXT::eDebug) level = spdlog::level::debug;
|
|
|
|
Logger::RENDER->log(level, "{0} [{1}] Code {2}: {3}", prefix, layerPrefix, msgCode, msg);
|
|
|
|
return false;
|
|
}
|
|
#else
|
|
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;
|
|
}
|
|
#endif
|
|
|
|
namespace
|
|
{
|
|
vk::DebugReportCallbackEXT msgCallback;
|
|
}
|
|
|
|
void Debug::SetupValidationLayers(const vk::Instance& instance, const vk::DebugReportFlagsEXT& flags, vk::DispatchLoaderDynamic& dispatchLoaderDynamic)
|
|
{
|
|
Logger::RENDER->info("Setting up Vulkan Validation Layer");
|
|
vk::DebugReportCallbackCreateInfoEXT dbgCreateInfo = {};
|
|
dbgCreateInfo.pfnCallback = &ValidationLayerCallback;
|
|
dbgCreateInfo.flags = flags;
|
|
msgCallback = instance.createDebugReportCallbackEXT(dbgCreateInfo, nullptr, dispatchLoaderDynamic);
|
|
Logger::RENDER->info("Vulkan Validation Layer setup");
|
|
}
|
|
|
|
void Debug::CloseValidationLayers(const vk::Instance& instance, vk::DispatchLoaderDynamic& dispatchLoaderDynamic)
|
|
{
|
|
instance.destroyDebugReportCallbackEXT(msgCallback, nullptr, dispatchLoaderDynamic);
|
|
}
|
|
} |