Renderer: Allow to enable or disable API validation layers using config
This commit is contained in:
@@ -20,11 +20,12 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
OpenGLDevice::OpenGLDevice(GL::Loader& loader) :
|
||||
OpenGLDevice::OpenGLDevice(GL::Loader& loader, const Renderer::Config& config) :
|
||||
m_loader(loader)
|
||||
{
|
||||
GL::ContextParams params;
|
||||
params.type = loader.GetPreferredContextType();
|
||||
params.validationLevel = config.validationLevel;
|
||||
|
||||
#ifdef NAZARA_OPENGLRENDERER_DEBUG
|
||||
params.wrapErrorHandling = true;
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace Nz
|
||||
return m_device;
|
||||
}
|
||||
|
||||
bool OpenGLRenderer::Prepare(const ParameterList& /*parameters*/)
|
||||
bool OpenGLRenderer::Prepare(const Renderer::Config& config)
|
||||
{
|
||||
std::unique_ptr<GL::Loader> loader = SelectLoader();
|
||||
if (!loader)
|
||||
@@ -64,7 +64,7 @@ namespace Nz
|
||||
|
||||
m_loader = std::move(loader);
|
||||
|
||||
m_device = std::make_shared<OpenGLDevice>(*m_loader);
|
||||
m_device = std::make_shared<OpenGLDevice>(*m_loader, config);
|
||||
m_deviceInfos.emplace_back(m_device->GetDeviceInfo());
|
||||
|
||||
return true;
|
||||
|
||||
@@ -450,13 +450,18 @@ namespace Nz::GL
|
||||
NazaraWarning("desktop support for OpenGL ES is missing, falling back to OpenGL...");
|
||||
}
|
||||
|
||||
// Set debug callback (if supported)
|
||||
if (glDebugMessageCallback)
|
||||
// Set debug callback (if supported and enabled)
|
||||
if (glDebugMessageCallback && params.validationLevel != RenderAPIValidationLevel::None)
|
||||
{
|
||||
m_params.validationLevel = params.validationLevel;
|
||||
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
#ifdef NAZARA_DEBUG
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
|
||||
// Always enable synchronous debug output for debug libraries
|
||||
#ifndef NAZARA_DEBUG
|
||||
if (m_params.validationLevel == RenderAPIValidationLevel::Debug)
|
||||
#endif
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
|
||||
glDebugMessageCallback([](GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam)
|
||||
{
|
||||
@@ -473,10 +478,18 @@ namespace Nz::GL
|
||||
if (glPopDebugGroup)
|
||||
glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_POP_GROUP, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE);
|
||||
|
||||
// Disable driver notifications (NVidia driver is very verbose)
|
||||
glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE);
|
||||
// Handle verbosity level
|
||||
if (m_params.validationLevel < RenderAPIValidationLevel::Debug)
|
||||
// Disable driver notifications except in debug (NVidia driver is very verbose)
|
||||
glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE);
|
||||
else if (m_params.validationLevel < RenderAPIValidationLevel::Verbose)
|
||||
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE);
|
||||
else if (m_params.validationLevel < RenderAPIValidationLevel::Warnings)
|
||||
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, nullptr, GL_FALSE);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_params.validationLevel = m_params.validationLevel;
|
||||
|
||||
GLint maxTextureUnits = -1;
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <Nazara/Renderer/RenderWindow.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/RendererImpl.hpp>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <Nazara/Core/StringExt.hpp>
|
||||
#include <Nazara/Platform/Platform.hpp>
|
||||
#include <Nazara/Renderer/RenderBuffer.hpp>
|
||||
#include <Nazara/Renderer/RendererImpl.hpp>
|
||||
#include <Nazara/Utility/Buffer.hpp>
|
||||
#include <Nazara/Utility/Image.hpp>
|
||||
#include <Nazara/Utility/Utility.hpp>
|
||||
@@ -37,9 +38,10 @@
|
||||
namespace Nz
|
||||
{
|
||||
Renderer::Renderer(Config config) :
|
||||
ModuleBase("Renderer", this)
|
||||
ModuleBase("Renderer", this),
|
||||
m_config(std::move(config))
|
||||
{
|
||||
LoadBackend(config);
|
||||
LoadBackend(m_config);
|
||||
}
|
||||
|
||||
Renderer::~Renderer()
|
||||
@@ -170,7 +172,7 @@ namespace Nz
|
||||
#else
|
||||
std::unique_ptr<RendererImpl> impl = rendererImpl.factory();
|
||||
#endif
|
||||
if (!impl || !impl->Prepare({}))
|
||||
if (!impl || !impl->Prepare(config))
|
||||
{
|
||||
NazaraError("Failed to create renderer implementation");
|
||||
continue;
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace Nz
|
||||
return dummy;
|
||||
}
|
||||
|
||||
bool Vulkan::Initialize(UInt32 targetApiVersion, const ParameterList& parameters)
|
||||
bool Vulkan::Initialize(UInt32 targetApiVersion, RenderAPIValidationLevel validationLevel, const ParameterList& parameters)
|
||||
{
|
||||
NazaraAssert(!IsInitialized(), "Vulkan is already initialized");
|
||||
|
||||
@@ -186,13 +186,14 @@ namespace Nz
|
||||
{
|
||||
//< Nazara default layers goes here
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
// Enable Vulkan validation if available in debug mode
|
||||
if (availableLayerByName.count("VK_LAYER_KHRONOS_validation"))
|
||||
enabledLayers.push_back("VK_LAYER_KHRONOS_validation");
|
||||
else if (availableLayerByName.count("VK_LAYER_LUNARG_standard_validation"))
|
||||
enabledLayers.push_back("VK_LAYER_LUNARG_standard_validation");
|
||||
#endif
|
||||
if (validationLevel != RenderAPIValidationLevel::None)
|
||||
{
|
||||
// Enable Vulkan validation if available in debug mode
|
||||
if (availableLayerByName.count("VK_LAYER_KHRONOS_validation"))
|
||||
enabledLayers.push_back("VK_LAYER_KHRONOS_validation");
|
||||
else if (availableLayerByName.count("VK_LAYER_LUNARG_standard_validation"))
|
||||
enabledLayers.push_back("VK_LAYER_LUNARG_standard_validation");
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<const char*> enabledExtensions;
|
||||
@@ -324,7 +325,7 @@ namespace Nz
|
||||
instanceInfo.enabledLayerCount = UInt32(enabledLayers.size());
|
||||
instanceInfo.ppEnabledLayerNames = enabledLayers.data();
|
||||
|
||||
if (!s_instance.Create(instanceInfo))
|
||||
if (!s_instance.Create(validationLevel, instanceInfo))
|
||||
{
|
||||
NazaraError("Failed to create instance: " + TranslateVulkanError(s_instance.GetLastErrorCode()));
|
||||
return false;
|
||||
|
||||
@@ -38,9 +38,9 @@ namespace Nz
|
||||
return Vulkan::CreateDevice(physDevices[deviceIndex], enabledFeatures);
|
||||
}
|
||||
|
||||
bool VulkanRenderer::Prepare(const ParameterList& parameters)
|
||||
bool VulkanRenderer::Prepare(const Renderer::Config& config)
|
||||
{
|
||||
if (!Vulkan::Initialize(APIVersion, parameters))
|
||||
if (!Vulkan::Initialize(APIVersion, config.validationLevel, config.customParameters))
|
||||
return false;
|
||||
|
||||
const auto& physDevices = Vulkan::GetPhysicalDevices();
|
||||
|
||||
@@ -148,7 +148,7 @@ namespace Nz
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case QueueType::Compute: return VK_QUEUE_COMPUTE_BIT;
|
||||
case QueueType::Compute: return VK_QUEUE_COMPUTE_BIT;
|
||||
case QueueType::Graphics: return VK_QUEUE_GRAPHICS_BIT;
|
||||
case QueueType::Transfer: return VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_TRANSFER_BIT; //< Compute/graphics imply transfer
|
||||
}
|
||||
|
||||
@@ -21,8 +21,22 @@ namespace Nz
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||
void* /*pUserData*/)
|
||||
void* pUserData)
|
||||
{
|
||||
Instance& instance = *static_cast<Instance*>(pUserData);
|
||||
if (messageTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT)
|
||||
{
|
||||
RenderAPIValidationLevel validationLevel = instance.GetValidationLevel();
|
||||
if ((messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) && validationLevel < RenderAPIValidationLevel::Debug)
|
||||
return VK_FALSE;
|
||||
|
||||
if ((messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) && validationLevel < RenderAPIValidationLevel::Verbose)
|
||||
return VK_FALSE;
|
||||
|
||||
if ((messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) && validationLevel < RenderAPIValidationLevel::Warnings)
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "Vulkan log: ";
|
||||
|
||||
@@ -48,7 +62,6 @@ namespace Nz
|
||||
if (messageTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT)
|
||||
ss << "[Validation]";
|
||||
|
||||
|
||||
ss << "[" << pCallbackData->messageIdNumber;
|
||||
if (pCallbackData->pMessageIdName)
|
||||
ss << ":" << pCallbackData->pMessageIdName;
|
||||
@@ -82,7 +95,7 @@ namespace Nz
|
||||
DestroyInstance();
|
||||
}
|
||||
|
||||
bool Instance::Create(const VkInstanceCreateInfo& createInfo, const VkAllocationCallbacks* allocator)
|
||||
bool Instance::Create(RenderAPIValidationLevel validationLevel, const VkInstanceCreateInfo& createInfo, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
m_lastErrorCode = Loader::vkCreateInstance(&createInfo, allocator, &m_instance);
|
||||
if (m_lastErrorCode != VkResult::VK_SUCCESS)
|
||||
@@ -92,6 +105,7 @@ namespace Nz
|
||||
}
|
||||
|
||||
m_apiVersion = createInfo.pApplicationInfo->apiVersion;
|
||||
m_validationLevel = validationLevel;
|
||||
|
||||
// Store the allocator to access them when needed
|
||||
if (allocator)
|
||||
@@ -223,6 +237,7 @@ namespace Nz
|
||||
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;
|
||||
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;
|
||||
callbackCreateInfo.pUserData = this;
|
||||
|
||||
if (!m_internalData->debugMessenger.Create(*this, callbackCreateInfo))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user