From b9b5db734c5022d68d5abff095281112e92a4725 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 1 Jun 2016 21:00:00 +0200 Subject: [PATCH] Vulkan/Core: Add loader and instance initialization Former-commit-id: d0635e2727d1f2f52fe8a03ff0530134645f1b1d [formerly fc5f88194171efde1e68387154db661072bfdf90] Former-commit-id: 6e42212b86524334a8324b1e49230303b49f969f --- include/Nazara/Vulkan/Vulkan.hpp | 8 ++ src/Nazara/Vulkan/Vulkan.cpp | 122 +++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) diff --git a/include/Nazara/Vulkan/Vulkan.hpp b/include/Nazara/Vulkan/Vulkan.hpp index 9d90202c2..59c1bb4f3 100644 --- a/include/Nazara/Vulkan/Vulkan.hpp +++ b/include/Nazara/Vulkan/Vulkan.hpp @@ -9,7 +9,9 @@ #include #include +#include #include +#include namespace Nz { @@ -19,13 +21,19 @@ namespace Nz Vulkan() = delete; ~Vulkan() = delete; + static Vk::Instance& GetInstance(); + static bool Initialize(); static bool IsInitialized(); + static void SetParameters(const ParameterList& parameters); + static void Uninitialize(); private: + static Vk::Instance s_instance; + static ParameterList s_initializationParameters; static unsigned int s_moduleReferenceCounter; }; } diff --git a/src/Nazara/Vulkan/Vulkan.cpp b/src/Nazara/Vulkan/Vulkan.cpp index 00bb55337..dc7a201ff 100644 --- a/src/Nazara/Vulkan/Vulkan.cpp +++ b/src/Nazara/Vulkan/Vulkan.cpp @@ -12,6 +12,11 @@ namespace Nz { + Vk::Instance& Vulkan::GetInstance() + { + return s_instance; + } + bool Vulkan::Initialize() { if (s_moduleReferenceCounter > 0) @@ -32,6 +37,113 @@ namespace Nz CallOnExit onExit(Vulkan::Uninitialize); // Initialize module here + if (!Vk::Loader::Initialize()) + { + NazaraError("Failed to load Vulkan API, it may be not installed on your system"); + return false; + } + + String appName = "Another application made with Nazara Engine"; + String engineName = "Nazara Engine - Vulkan Renderer"; + UInt32 apiVersion = VK_MAKE_VERSION(1, 0, 8); + UInt32 appVersion = VK_MAKE_VERSION(1, 0, 0); + UInt32 engineVersion = VK_MAKE_VERSION(1, 0, 0); + + s_initializationParameters.GetStringParameter("VkAppInfo_OverrideApplicationName", &appName); + s_initializationParameters.GetStringParameter("VkAppInfo_OverrideEngineName", &engineName); + + int iParam; + + if (s_initializationParameters.GetIntegerParameter("VkAppInfo_OverrideAPIVersion", &iParam)) + apiVersion = iParam; + + if (s_initializationParameters.GetIntegerParameter("VkAppInfo_OverrideApplicationVersion", &iParam)) + appVersion = iParam; + + if (s_initializationParameters.GetIntegerParameter("VkAppInfo_OverrideEngineVersion", &iParam)) + engineVersion = iParam; + + VkApplicationInfo appInfo = { + VK_STRUCTURE_TYPE_APPLICATION_INFO, + nullptr, + appName.GetConstBuffer(), + appVersion, + engineName.GetConstBuffer(), + engineVersion, + apiVersion + }; + + VkInstanceCreateFlags createFlags = 0; + + if (s_initializationParameters.GetIntegerParameter("VkInstanceInfo_OverrideCreateFlags", &iParam)) + createFlags = static_cast(iParam); + + std::vector enabledLayers; + std::vector enabledExtensions; + + bool bParam; + if (!s_initializationParameters.GetBooleanParameter("VkInstanceInfo_OverrideEnabledExtensions", &bParam) || !bParam) + { + enabledExtensions.push_back("VK_KHR_surface"); + + #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"); + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + enabledExtensions.push_back("VK_KHR_xcb_surface"); + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + enabledExtensions.push_back("VK_KHR_xlib_surface"); + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + enabledExtensions.push_back("VK_KHR_wayland_surface"); + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + enabledExtensions.push_back("VK_KHR_win32_surface"); + #endif + } + + std::vector additionalExtensions; // Just to keep the String alive + if (s_initializationParameters.GetIntegerParameter("VkInstanceInfo_EnabledExtensionCount", &iParam)) + { + for (int i = 0; i < iParam; ++i) + { + Nz::String parameterName = "VkInstanceInfo_EnabledExtension" + String::Number(i); + Nz::String extension; + if (s_initializationParameters.GetStringParameter(parameterName, &extension)) + { + additionalExtensions.emplace_back(std::move(extension)); + enabledExtensions.push_back(additionalExtensions.back().GetConstBuffer()); + } + else + NazaraWarning("Parameter " + parameterName + " expected"); + } + } + + VkInstanceCreateInfo instanceInfo = { + VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + nullptr, + createFlags, + &appInfo, + UInt32(enabledLayers.size()), + enabledLayers.data(), + UInt32(enabledExtensions.size()), + enabledExtensions.data() + }; + + if (!s_instance.Create(instanceInfo)) + { + NazaraError("Failed to create instance"); + return false; + } onExit.Reset(); @@ -44,6 +156,11 @@ namespace Nz return s_moduleReferenceCounter != 0; } + void Vulkan::SetParameters(const ParameterList& parameters) + { + s_initializationParameters = parameters; + } + void Vulkan::Uninitialize() { if (s_moduleReferenceCounter != 1) @@ -58,6 +175,9 @@ namespace Nz s_moduleReferenceCounter = 0; // Uninitialize module here + s_instance.Destroy(); + + Vk::Loader::Uninitialize(); NazaraNotice("Uninitialized: Vulkan module"); @@ -65,6 +185,8 @@ namespace Nz Utility::Uninitialize(); } + Vk::Instance Vulkan::s_instance; + ParameterList Vulkan::s_initializationParameters; unsigned int Vulkan::s_moduleReferenceCounter = 0; }