diff --git a/include/Nazara/Vulkan/VkInstance.hpp b/include/Nazara/Vulkan/VkInstance.hpp index b3b0b62eb..4581b9cf1 100644 --- a/include/Nazara/Vulkan/VkInstance.hpp +++ b/include/Nazara/Vulkan/VkInstance.hpp @@ -8,9 +8,11 @@ #define NAZARA_VULKAN_VKINSTANCE_HPP #include +#include #include #include #include +#include namespace Nz { @@ -25,6 +27,7 @@ namespace Nz inline ~Instance(); bool Create(const VkInstanceCreateInfo& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(const String& appName, UInt32 appVersion, const String& engineName, UInt32 engineVersion, const std::vector& layers, const std::vector& extensions, const VkAllocationCallbacks* allocator = nullptr); inline void Destroy(); bool EnumeratePhysicalDevices(std::vector* physicalDevices); @@ -40,12 +43,18 @@ namespace Nz inline VkResult GetLastErrorCode() const; + inline bool IsExtensionLoaded(const String& extensionName); + inline bool IsLayerLoaded(const String& layerName); + Instance& operator=(const Instance&) = delete; Instance& operator=(Instance&&) = delete; + inline operator VkInstance(); + // Vulkan functions #define NAZARA_VULKAN_INSTANCE_FUNCTION(func) PFN_##func func + // Vulkan core NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateDevice); NAZARA_VULKAN_INSTANCE_FUNCTION(vkDestroyInstance); NAZARA_VULKAN_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices); @@ -57,6 +66,72 @@ namespace Nz NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties); NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties); + // VK_KHR_display + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateDisplayModeKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateDisplayPlaneSurfaceKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetDisplayModePropertiesKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetDisplayPlaneCapabilitiesKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetDisplayPlaneSupportedDisplaysKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceDisplayPlanePropertiesKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceDisplayPropertiesKHR); + + // VK_KHR_display_swapchain + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateSharedSwapchainsKHR); + + // VK_KHR_surface + NAZARA_VULKAN_INSTANCE_FUNCTION(vkDestroySurfaceKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR); + + // VK_KHR_swapchain + NAZARA_VULKAN_INSTANCE_FUNCTION(vkAcquireNextImageKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateSwapchainKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkDestroySwapchainKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetSwapchainImagesKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkQueuePresentKHR); + + // VK_EXT_debug_report + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateDebugReportCallbackEXT); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkDestroyDebugReportCallbackEXT); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkDebugReportMessageEXT); + + #ifdef VK_USE_PLATFORM_ANDROID_KHR + // VK_KHR_android_surface + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateAndroidSurfaceKHR); + #endif + + #ifdef VK_USE_PLATFORM_MIR_KHR + // VK_KHR_mir_surface + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateMirSurfaceKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceMirPresentationSupportKHR); + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + // VK_KHR_xcb_surface + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateXcbSurfaceKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceXcbPresentationSupportKHR); + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + // VK_KHR_xlib_surface + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateXlibSurfaceKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceXlibPresentationSupportKHR); + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + // VK_KHR_wayland_surface + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateWaylandSurfaceKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceWaylandPresentationSupportKHR); + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + // VK_KHR_win32_surface + NAZARA_VULKAN_INSTANCE_FUNCTION(vkCreateWin32SurfaceKHR); + NAZARA_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceWin32PresentationSupportKHR); + #endif + #undef NAZARA_VULKAN_INSTANCE_FUNCTION private: @@ -65,6 +140,8 @@ namespace Nz VkAllocationCallbacks m_allocator; VkInstance m_instance; VkResult m_lastErrorCode; + std::unordered_set m_loadedExtensions; + std::unordered_set m_loadedLayers; }; } } diff --git a/include/Nazara/Vulkan/VkInstance.inl b/include/Nazara/Vulkan/VkInstance.inl index 1aaa508ef..8f0f6d2af 100644 --- a/include/Nazara/Vulkan/VkInstance.inl +++ b/include/Nazara/Vulkan/VkInstance.inl @@ -20,6 +20,33 @@ namespace Nz Destroy(); } + inline bool Instance::Create(const String& appName, UInt32 appVersion, const String& engineName, UInt32 engineVersion, const std::vector& layers, const std::vector& extensions, const VkAllocationCallbacks* allocator) + { + VkApplicationInfo appInfo = + { + VK_STRUCTURE_TYPE_APPLICATION_INFO, + nullptr, + appName.GetConstBuffer(), + appVersion, + engineName.GetConstBuffer(), + engineVersion + }; + + VkInstanceCreateInfo instanceInfo = + { + VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + nullptr, + 0, + &appInfo, + static_cast(layers.size()), + &layers[0], + static_cast(extensions.size()), + &extensions[0] + }; + + return Create(instanceInfo, allocator); + } + inline void Instance::Destroy() { if (m_instance) @@ -40,6 +67,21 @@ namespace Nz return m_lastErrorCode; } + inline bool Instance::IsExtensionLoaded(const String& extensionName) + { + return m_loadedExtensions.count(extensionName) != 0; + } + + inline bool Instance::IsLayerLoaded(const String& layerName) + { + return m_loadedLayers.count(layerName) != 0; + } + + inline Instance::operator VkInstance() + { + return m_instance; + } + inline void Instance::GetPhysicalDeviceFeatures(VkPhysicalDevice device, VkPhysicalDeviceFeatures* features) { return vkGetPhysicalDeviceFeatures(device, features); diff --git a/src/Nazara/Vulkan/VkInstance.cpp b/src/Nazara/Vulkan/VkInstance.cpp index 304bbc277..5533798a5 100644 --- a/src/Nazara/Vulkan/VkInstance.cpp +++ b/src/Nazara/Vulkan/VkInstance.cpp @@ -26,12 +26,21 @@ namespace Nz else m_allocator.pfnAllocation = nullptr; + // Parse extensions and layers + for (UInt32 i = 0; i < createInfo.enabledExtensionCount; ++i) + m_loadedExtensions.insert(createInfo.ppEnabledExtensionNames[i]); + + for (UInt32 i = 0; i < createInfo.enabledLayerCount; ++i) + m_loadedLayers.insert(createInfo.ppEnabledLayerNames[i]); + + // And now load everything #define NAZARA_VULKAN_LOAD_INSTANCE(func) func = reinterpret_cast(GetProcAddr(#func)) try { ErrorFlags flags(ErrorFlag_ThrowException, true); + // Vulkan core NAZARA_VULKAN_LOAD_INSTANCE(vkCreateDevice); NAZARA_VULKAN_LOAD_INSTANCE(vkDestroyInstance); NAZARA_VULKAN_LOAD_INSTANCE(vkEnumeratePhysicalDevices); @@ -42,6 +51,101 @@ namespace Nz NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceMemoryProperties); NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceProperties); NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceQueueFamilyProperties); + + // VK_KHR_display + if (IsExtensionLoaded("VK_KHR_display")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateDisplayModeKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateDisplayPlaneSurfaceKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetDisplayModePropertiesKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetDisplayPlaneCapabilitiesKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetDisplayPlaneSupportedDisplaysKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceDisplayPlanePropertiesKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceDisplayPropertiesKHR); + } + + // VK_KHR_display_swapchain + if (IsExtensionLoaded("VK_KHR_display_swapchain")) + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateSharedSwapchainsKHR); + + // VK_KHR_surface + if (IsExtensionLoaded("VK_KHR_display")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkDestroySurfaceKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceSurfaceFormatsKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceSurfacePresentModesKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceSurfaceSupportKHR); + } + + // VK_KHR_swapchain + if (IsExtensionLoaded("VK_KHR_swapchain")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkAcquireNextImageKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateSwapchainKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkDestroySwapchainKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetSwapchainImagesKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkQueuePresentKHR); + } + + // VK_EXT_debug_report + if (IsExtensionLoaded("VK_EXT_debug_report")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateDebugReportCallbackEXT); + NAZARA_VULKAN_LOAD_INSTANCE(vkDestroyDebugReportCallbackEXT); + NAZARA_VULKAN_LOAD_INSTANCE(vkDebugReportMessageEXT); + } + + #ifdef VK_USE_PLATFORM_ANDROID_KHR + // VK_KHR_android_surface + if (IsExtensionLoaded("VK_KHR_android_surface")) + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateAndroidSurfaceKHR); + #endif + + #ifdef VK_USE_PLATFORM_MIR_KHR + // VK_KHR_mir_surface + if (IsExtensionLoaded("VK_KHR_mir_surface")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateMirSurfaceKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceMirPresentationSupportKHR); + } + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + // VK_KHR_xcb_surface + if (IsExtensionLoaded("VK_KHR_xcb_surface")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateXcbSurfaceKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceXcbPresentationSupportKHR); + } + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + // VK_KHR_xlib_surface + if (IsExtensionLoaded("VK_KHR_xlib_surface")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateXlibSurfaceKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceXlibPresentationSupportKHR); + } + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + // VK_KHR_wayland_surface + if (IsExtensionLoaded("VK_KHR_wayland_surface")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateWaylandSurfaceKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceWaylandPresentationSupportKHR); + } + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + // VK_KHR_win32_surface + if (IsExtensionLoaded("VK_KHR_win32_surface")) + { + NAZARA_VULKAN_LOAD_INSTANCE(vkCreateWin32SurfaceKHR); + NAZARA_VULKAN_LOAD_INSTANCE(vkGetPhysicalDeviceWin32PresentationSupportKHR); + } + #endif } catch (const std::exception& e) {