Renderer: Allow to enable or disable API validation layers using config

This commit is contained in:
SirLynix 2022-08-10 00:04:46 +02:00
parent 38e32025e9
commit 117f7c2a4b
19 changed files with 101 additions and 37 deletions

View File

@ -13,6 +13,7 @@
#include <Nazara/Platform/WindowHandle.hpp> #include <Nazara/Platform/WindowHandle.hpp>
#include <Nazara/Renderer/RenderDevice.hpp> #include <Nazara/Renderer/RenderDevice.hpp>
#include <Nazara/Renderer/RenderDeviceInfo.hpp> #include <Nazara/Renderer/RenderDeviceInfo.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
@ -23,7 +24,7 @@ namespace Nz
friend GL::Context; friend GL::Context;
public: public:
OpenGLDevice(GL::Loader& loader); OpenGLDevice(GL::Loader& loader, const Renderer::Config& config);
OpenGLDevice(const OpenGLDevice&) = delete; OpenGLDevice(const OpenGLDevice&) = delete;
OpenGLDevice(OpenGLDevice&&) = delete; ///TODO? OpenGLDevice(OpenGLDevice&&) = delete; ///TODO?
~OpenGLDevice(); ~OpenGLDevice();

View File

@ -32,7 +32,7 @@ namespace Nz
UInt32 QueryAPIVersion() const override; UInt32 QueryAPIVersion() const override;
const std::vector<RenderDeviceInfo>& QueryRenderDevices() const override; const std::vector<RenderDeviceInfo>& QueryRenderDevices() const override;
bool Prepare(const ParameterList& parameters) override; bool Prepare(const Renderer::Config& config) override;
private: private:
std::unique_ptr<GL::Loader> SelectLoader(); std::unique_ptr<GL::Loader> SelectLoader();

View File

@ -14,6 +14,7 @@
#include <Nazara/OpenGLRenderer/OpenGLVaoCache.hpp> #include <Nazara/OpenGLRenderer/OpenGLVaoCache.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/CoreFunctions.hpp> #include <Nazara/OpenGLRenderer/Wrapper/CoreFunctions.hpp>
#include <Nazara/OpenGLRenderer/Wrapper/Loader.hpp> #include <Nazara/OpenGLRenderer/Wrapper/Loader.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/RenderStates.hpp> #include <Nazara/Renderer/RenderStates.hpp>
#include <array> #include <array>
#include <string> #include <string>
@ -96,6 +97,7 @@ namespace Nz::GL
struct ContextParams struct ContextParams
{ {
ContextType type = ContextType::OpenGL_ES; ContextType type = ContextType::OpenGL_ES;
RenderAPIValidationLevel validationLevel = RenderAPIValidationLevel::Warnings;
bool doubleBuffering = true; bool doubleBuffering = true;
bool wrapErrorHandling = false; bool wrapErrorHandling = false;
unsigned int bitsPerPixel = 32; unsigned int bitsPerPixel = 32;

View File

@ -122,6 +122,16 @@ namespace Nz
constexpr std::size_t RenderAPICount = static_cast<std::size_t>(RenderAPI::Max) + 1; constexpr std::size_t RenderAPICount = static_cast<std::size_t>(RenderAPI::Max) + 1;
enum class RenderAPIValidationLevel
{
None = 0,
Errors = 1,
Warnings = 2,
Verbose = 3,
Debug = 4
};
enum class RenderDeviceType enum class RenderDeviceType
{ {
Integrated, ///< Hardware-accelerated chipset integrated to a CPU (ex: Intel Graphics HD 4000) Integrated, ///< Hardware-accelerated chipset integrated to a CPU (ex: Intel Graphics HD 4000)

View File

@ -9,14 +9,16 @@
#include <Nazara/Prerequisites.hpp> #include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/DynLib.hpp> #include <Nazara/Core/DynLib.hpp>
#include <Nazara/Core/ParameterList.hpp>
#include <Nazara/Platform/Platform.hpp> #include <Nazara/Platform/Platform.hpp>
#include <Nazara/Renderer/Config.hpp> #include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Enums.hpp> #include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/RendererImpl.hpp> #include <Nazara/Renderer/RenderDevice.hpp>
namespace Nz namespace Nz
{ {
class Buffer; class Buffer;
class RendererImpl;
class NAZARA_RENDERER_API Renderer : public ModuleBase<Renderer> class NAZARA_RENDERER_API Renderer : public ModuleBase<Renderer>
{ {
@ -42,13 +44,20 @@ namespace Nz
struct Config struct Config
{ {
ParameterList customParameters;
RenderAPI preferredAPI = RenderAPI::Unknown; RenderAPI preferredAPI = RenderAPI::Unknown;
#ifdef NAZARA_DEBUG
RenderAPIValidationLevel validationLevel = RenderAPIValidationLevel::Verbose;
#else
RenderAPIValidationLevel validationLevel = RenderAPIValidationLevel::Errors;
#endif
}; };
private: private:
void LoadBackend(const Config& config); void LoadBackend(const Config& config);
std::unique_ptr<RendererImpl> m_rendererImpl; std::unique_ptr<RendererImpl> m_rendererImpl;
Config m_config;
DynLib m_rendererLib; DynLib m_rendererLib;
static Renderer* s_instance; static Renderer* s_instance;

View File

@ -12,6 +12,7 @@
#include <Nazara/Renderer/Config.hpp> #include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Enums.hpp> #include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/RenderDeviceInfo.hpp> #include <Nazara/Renderer/RenderDeviceInfo.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Utility/Enums.hpp> #include <Nazara/Utility/Enums.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
@ -44,7 +45,7 @@ namespace Nz
virtual const std::vector<RenderDeviceInfo>& QueryRenderDevices() const = 0; virtual const std::vector<RenderDeviceInfo>& QueryRenderDevices() const = 0;
virtual bool Prepare(const ParameterList& parameters) = 0; virtual bool Prepare(const Renderer::Config& config) = 0;
}; };
} }

View File

@ -47,7 +47,7 @@ namespace Nz
static const std::vector<Vk::PhysicalDevice>& GetPhysicalDevices(); static const std::vector<Vk::PhysicalDevice>& GetPhysicalDevices();
static const Vk::PhysicalDevice& GetPhysicalDeviceInfo(VkPhysicalDevice physDevice); static const Vk::PhysicalDevice& GetPhysicalDeviceInfo(VkPhysicalDevice physDevice);
static bool Initialize(UInt32 targetApiVersion, const ParameterList& parameters); static bool Initialize(UInt32 targetApiVersion, RenderAPIValidationLevel validationLevel, const ParameterList& parameters);
static bool IsInitialized(); static bool IsInitialized();

View File

@ -35,7 +35,7 @@ namespace Nz
UInt32 QueryAPIVersion() const override; UInt32 QueryAPIVersion() const override;
const std::vector<RenderDeviceInfo>& QueryRenderDevices() const override; const std::vector<RenderDeviceInfo>& QueryRenderDevices() const override;
bool Prepare(const ParameterList& parameters) override; bool Prepare(const Renderer::Config& parameters) override;
static constexpr UInt32 APIVersion = VK_API_VERSION_1_2; static constexpr UInt32 APIVersion = VK_API_VERSION_1_2;

View File

@ -8,6 +8,7 @@
#define NAZARA_VULKANRENDERER_WRAPPER_INSTANCE_HPP #define NAZARA_VULKANRENDERER_WRAPPER_INSTANCE_HPP
#include <Nazara/Prerequisites.hpp> #include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/Enums.hpp>
#include <Nazara/VulkanRenderer/Config.hpp> #include <Nazara/VulkanRenderer/Config.hpp>
#include <Nazara/VulkanRenderer/Wrapper/Loader.hpp> #include <Nazara/VulkanRenderer/Wrapper/Loader.hpp>
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
@ -59,8 +60,8 @@ namespace Nz
Instance(Instance&&) = delete; Instance(Instance&&) = delete;
~Instance(); ~Instance();
bool Create(const VkInstanceCreateInfo& createInfo, const VkAllocationCallbacks* allocator = nullptr); bool Create(RenderAPIValidationLevel validationLevel, const VkInstanceCreateInfo& createInfo, const VkAllocationCallbacks* allocator = nullptr);
inline bool Create(const std::string& appName, UInt32 appVersion, const std::string& engineName, UInt32 engineVersion, UInt32 apiVersion, const std::vector<const char*>& layers, const std::vector<const char*>& extensions, const VkAllocationCallbacks* allocator = nullptr); inline bool Create(RenderAPIValidationLevel validationLevel, const std::string& appName, UInt32 appVersion, const std::string& engineName, UInt32 engineVersion, UInt32 apiVersion, const std::vector<const char*>& layers, const std::vector<const char*>& extensions, const VkAllocationCallbacks* allocator = nullptr);
inline void Destroy(); inline void Destroy();
bool EnumeratePhysicalDevices(std::vector<VkPhysicalDevice>* physicalDevices) const; bool EnumeratePhysicalDevices(std::vector<VkPhysicalDevice>* physicalDevices) const;
@ -78,6 +79,7 @@ namespace Nz
inline VkPhysicalDeviceProperties GetPhysicalDeviceProperties(VkPhysicalDevice device) const; inline VkPhysicalDeviceProperties GetPhysicalDeviceProperties(VkPhysicalDevice device) const;
bool GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice device, std::vector<VkQueueFamilyProperties>* queueFamilyProperties) const; bool GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice device, std::vector<VkQueueFamilyProperties>* queueFamilyProperties) const;
inline PFN_vkVoidFunction GetProcAddr(const char* name) const; inline PFN_vkVoidFunction GetProcAddr(const char* name) const;
inline RenderAPIValidationLevel GetValidationLevel() const;
void InstallDebugMessageCallback(); void InstallDebugMessageCallback();
@ -108,6 +110,7 @@ namespace Nz
VkAllocationCallbacks m_allocator; VkAllocationCallbacks m_allocator;
VkInstance m_instance; VkInstance m_instance;
mutable VkResult m_lastErrorCode; mutable VkResult m_lastErrorCode;
RenderAPIValidationLevel m_validationLevel;
UInt32 m_apiVersion; UInt32 m_apiVersion;
}; };
} }

View File

@ -12,7 +12,7 @@ namespace Nz
{ {
namespace Vk namespace Vk
{ {
inline bool Instance::Create(const std::string& appName, UInt32 appVersion, const std::string& engineName, UInt32 engineVersion, UInt32 apiVersion, const std::vector<const char*>& layers, const std::vector<const char*>& extensions, const VkAllocationCallbacks* allocator) inline bool Instance::Create(RenderAPIValidationLevel validationLevel, const std::string& appName, UInt32 appVersion, const std::string& engineName, UInt32 engineVersion, UInt32 apiVersion, const std::vector<const char*>& layers, const std::vector<const char*>& extensions, const VkAllocationCallbacks* allocator)
{ {
VkApplicationInfo appInfo = VkApplicationInfo appInfo =
{ {
@ -37,7 +37,7 @@ namespace Nz
(!extensions.empty()) ? extensions.data() : nullptr (!extensions.empty()) ? extensions.data() : nullptr
}; };
return Create(instanceInfo, allocator); return Create(validationLevel, instanceInfo, allocator);
} }
inline void Instance::Destroy() inline void Instance::Destroy()
@ -77,6 +77,11 @@ namespace Nz
return func; return func;
} }
inline RenderAPIValidationLevel Instance::GetValidationLevel() const
{
return m_validationLevel;
}
inline bool Instance::IsExtensionLoaded(const std::string& extensionName) const inline bool Instance::IsExtensionLoaded(const std::string& extensionName) const
{ {
return m_loadedExtensions.count(extensionName) > 0; return m_loadedExtensions.count(extensionName) > 0;

View File

@ -20,11 +20,12 @@
namespace Nz namespace Nz
{ {
OpenGLDevice::OpenGLDevice(GL::Loader& loader) : OpenGLDevice::OpenGLDevice(GL::Loader& loader, const Renderer::Config& config) :
m_loader(loader) m_loader(loader)
{ {
GL::ContextParams params; GL::ContextParams params;
params.type = loader.GetPreferredContextType(); params.type = loader.GetPreferredContextType();
params.validationLevel = config.validationLevel;
#ifdef NAZARA_OPENGLRENDERER_DEBUG #ifdef NAZARA_OPENGLRENDERER_DEBUG
params.wrapErrorHandling = true; params.wrapErrorHandling = true;

View File

@ -53,7 +53,7 @@ namespace Nz
return m_device; return m_device;
} }
bool OpenGLRenderer::Prepare(const ParameterList& /*parameters*/) bool OpenGLRenderer::Prepare(const Renderer::Config& config)
{ {
std::unique_ptr<GL::Loader> loader = SelectLoader(); std::unique_ptr<GL::Loader> loader = SelectLoader();
if (!loader) if (!loader)
@ -64,7 +64,7 @@ namespace Nz
m_loader = std::move(loader); 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()); m_deviceInfos.emplace_back(m_device->GetDeviceInfo());
return true; return true;

View File

@ -450,13 +450,18 @@ namespace Nz::GL
NazaraWarning("desktop support for OpenGL ES is missing, falling back to OpenGL..."); NazaraWarning("desktop support for OpenGL ES is missing, falling back to OpenGL...");
} }
// Set debug callback (if supported) // Set debug callback (if supported and enabled)
if (glDebugMessageCallback) if (glDebugMessageCallback && params.validationLevel != RenderAPIValidationLevel::None)
{ {
m_params.validationLevel = params.validationLevel;
glEnable(GL_DEBUG_OUTPUT); 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 #endif
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
glDebugMessageCallback([](GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam) 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) if (glPopDebugGroup)
glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_POP_GROUP, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE); 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) // 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); 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; GLint maxTextureUnits = -1;
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits); glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);

View File

@ -5,6 +5,7 @@
#include <Nazara/Renderer/RenderWindow.hpp> #include <Nazara/Renderer/RenderWindow.hpp>
#include <Nazara/Core/Error.hpp> #include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Renderer.hpp> #include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Renderer/RendererImpl.hpp>
#include <chrono> #include <chrono>
#include <thread> #include <thread>
#include <Nazara/Renderer/Debug.hpp> #include <Nazara/Renderer/Debug.hpp>

View File

@ -8,6 +8,7 @@
#include <Nazara/Core/StringExt.hpp> #include <Nazara/Core/StringExt.hpp>
#include <Nazara/Platform/Platform.hpp> #include <Nazara/Platform/Platform.hpp>
#include <Nazara/Renderer/RenderBuffer.hpp> #include <Nazara/Renderer/RenderBuffer.hpp>
#include <Nazara/Renderer/RendererImpl.hpp>
#include <Nazara/Utility/Buffer.hpp> #include <Nazara/Utility/Buffer.hpp>
#include <Nazara/Utility/Image.hpp> #include <Nazara/Utility/Image.hpp>
#include <Nazara/Utility/Utility.hpp> #include <Nazara/Utility/Utility.hpp>
@ -37,9 +38,10 @@
namespace Nz namespace Nz
{ {
Renderer::Renderer(Config config) : Renderer::Renderer(Config config) :
ModuleBase("Renderer", this) ModuleBase("Renderer", this),
m_config(std::move(config))
{ {
LoadBackend(config); LoadBackend(m_config);
} }
Renderer::~Renderer() Renderer::~Renderer()
@ -170,7 +172,7 @@ namespace Nz
#else #else
std::unique_ptr<RendererImpl> impl = rendererImpl.factory(); std::unique_ptr<RendererImpl> impl = rendererImpl.factory();
#endif #endif
if (!impl || !impl->Prepare({})) if (!impl || !impl->Prepare(config))
{ {
NazaraError("Failed to create renderer implementation"); NazaraError("Failed to create renderer implementation");
continue; continue;

View File

@ -116,7 +116,7 @@ namespace Nz
return dummy; 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"); NazaraAssert(!IsInitialized(), "Vulkan is already initialized");
@ -186,13 +186,14 @@ namespace Nz
{ {
//< Nazara default layers goes here //< Nazara default layers goes here
#ifdef NAZARA_DEBUG if (validationLevel != RenderAPIValidationLevel::None)
{
// Enable Vulkan validation if available in debug mode // Enable Vulkan validation if available in debug mode
if (availableLayerByName.count("VK_LAYER_KHRONOS_validation")) if (availableLayerByName.count("VK_LAYER_KHRONOS_validation"))
enabledLayers.push_back("VK_LAYER_KHRONOS_validation"); enabledLayers.push_back("VK_LAYER_KHRONOS_validation");
else if (availableLayerByName.count("VK_LAYER_LUNARG_standard_validation")) else if (availableLayerByName.count("VK_LAYER_LUNARG_standard_validation"))
enabledLayers.push_back("VK_LAYER_LUNARG_standard_validation"); enabledLayers.push_back("VK_LAYER_LUNARG_standard_validation");
#endif }
} }
std::vector<const char*> enabledExtensions; std::vector<const char*> enabledExtensions;
@ -324,7 +325,7 @@ namespace Nz
instanceInfo.enabledLayerCount = UInt32(enabledLayers.size()); instanceInfo.enabledLayerCount = UInt32(enabledLayers.size());
instanceInfo.ppEnabledLayerNames = enabledLayers.data(); instanceInfo.ppEnabledLayerNames = enabledLayers.data();
if (!s_instance.Create(instanceInfo)) if (!s_instance.Create(validationLevel, instanceInfo))
{ {
NazaraError("Failed to create instance: " + TranslateVulkanError(s_instance.GetLastErrorCode())); NazaraError("Failed to create instance: " + TranslateVulkanError(s_instance.GetLastErrorCode()));
return false; return false;

View File

@ -38,9 +38,9 @@ namespace Nz
return Vulkan::CreateDevice(physDevices[deviceIndex], enabledFeatures); 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; return false;
const auto& physDevices = Vulkan::GetPhysicalDevices(); const auto& physDevices = Vulkan::GetPhysicalDevices();

View File

@ -21,8 +21,22 @@ namespace Nz
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes, VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, 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; std::stringstream ss;
ss << "Vulkan log: "; ss << "Vulkan log: ";
@ -48,7 +62,6 @@ namespace Nz
if (messageTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) if (messageTypes & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT)
ss << "[Validation]"; ss << "[Validation]";
ss << "[" << pCallbackData->messageIdNumber; ss << "[" << pCallbackData->messageIdNumber;
if (pCallbackData->pMessageIdName) if (pCallbackData->pMessageIdName)
ss << ":" << pCallbackData->pMessageIdName; ss << ":" << pCallbackData->pMessageIdName;
@ -82,7 +95,7 @@ namespace Nz
DestroyInstance(); 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); m_lastErrorCode = Loader::vkCreateInstance(&createInfo, allocator, &m_instance);
if (m_lastErrorCode != VkResult::VK_SUCCESS) if (m_lastErrorCode != VkResult::VK_SUCCESS)
@ -92,6 +105,7 @@ namespace Nz
} }
m_apiVersion = createInfo.pApplicationInfo->apiVersion; m_apiVersion = createInfo.pApplicationInfo->apiVersion;
m_validationLevel = validationLevel;
// Store the allocator to access them when needed // Store the allocator to access them when needed
if (allocator) 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.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.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.pfnUserCallback = &DebugCallback;
callbackCreateInfo.pUserData = this;
if (!m_internalData->debugMessenger.Create(*this, callbackCreateInfo)) if (!m_internalData->debugMessenger.Create(*this, callbackCreateInfo))
{ {