diff --git a/include/Nazara/Vulkan/VkSurface.hpp b/include/Nazara/Vulkan/VkSurface.hpp new file mode 100644 index 000000000..ff7ac0002 --- /dev/null +++ b/include/Nazara/Vulkan/VkSurface.hpp @@ -0,0 +1,87 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_VULKAN_VKSURFACE_HPP +#define NAZARA_VULKAN_VKSURFACE_HPP + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + class Instance; + + class NAZARA_VULKAN_API Surface + { + public: + inline Surface(Instance& instance); + Surface(const Surface&) = delete; + Surface(Surface&&) = delete; + inline ~Surface(); + + #ifdef VK_USE_PLATFORM_ANDROID_KHR + // VK_KHR_android_surface + bool Create(const VkAndroidSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(ANativeWindow* window, VkAndroidSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + #ifdef VK_USE_PLATFORM_MIR_KHR + // VK_KHR_mir_surface + bool Create(const VkMirSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(MirConnection* connection, MirSurface* surface, VkMirSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + // VK_KHR_xcb_surface + bool Create(const VkXcbSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(xcb_connection_t* connection, xcb_window_t window, VkXcbSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + // VK_KHR_xlib_surface + bool Create(const VkXlibSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(Display* display, Window window, VkXlibSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + // VK_KHR_wayland_surface + bool Create(const VkWaylandSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(wl_display* display, wl_surface* surface, VkWaylandSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + // VK_KHR_win32_surface + bool Create(const VkWin32SurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr); + inline bool Create(HINSTANCE instance, HWND handle, VkWin32SurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + inline void Destroy(); + + inline bool IsSupported() const; + + inline VkResult GetLastErrorCode() const; + + Surface& operator=(const Surface&) = delete; + Surface& operator=(Surface&&) = delete; + + private: + bool Create(const VkAllocationCallbacks* allocator); + + Instance& m_instance; + VkAllocationCallbacks m_allocator; + VkSurfaceKHR m_surface; + VkResult m_lastErrorCode; + }; + } +} + +#include + +#endif // Surface diff --git a/include/Nazara/Vulkan/VkSurface.inl b/include/Nazara/Vulkan/VkSurface.inl new file mode 100644 index 000000000..daab26d1e --- /dev/null +++ b/include/Nazara/Vulkan/VkSurface.inl @@ -0,0 +1,166 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + inline Surface::Surface(Instance& instance) : + m_instance(instance), + m_surface(0) + { + } + + inline Surface::~Surface() + { + Destroy(); + } + + #ifdef VK_USE_PLATFORM_ANDROID_KHR + inline bool Surface::Create(ANativeWindow* window, VkAndroidSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) + { + VkAndroidSurfaceCreateInfoKHR createInfo = + { + VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR, + nullptr, + flags, + window + }; + + return Create(createInfo, allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_MIR_KHR + inline bool Surface::Create(MirConnection* connection, MirSurface* surface, VkMirSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) + { + VkMirSurfaceCreateInfoKHR createInfo = + { + VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR, + nullptr, + flags, + connection, + surface + }; + + return Create(createInfo, allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + inline bool Surface::Create(xcb_connection_t* connection, xcb_window_t window, VkXcbSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) + { + VkXcbSurfaceCreateInfoKHR createInfo = + { + VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, + nullptr, + flags, + connection, + window + }; + + return Create(createInfo, allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + inline bool Surface::Create(Display* display, Window window, VkXlibSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) + { + VkXlibSurfaceCreateInfoKHR createInfo = + { + VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, + nullptr, + flags, + display, + window + }; + + return Create(createInfo, allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + inline bool Surface::Create(wl_display* display, wl_surface* surface, VkWaylandSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) + { + VkWaylandSurfaceCreateInfoKHR createInfo = + { + VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, + nullptr, + flags, + display, + surface + }; + + return Create(createInfo, allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + inline bool Surface::Create(HINSTANCE instance, HWND handle, VkWin32SurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator) + { + VkWin32SurfaceCreateInfoKHR createInfo = + { + VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, + nullptr, + flags, + instance, + handle + }; + + return Create(createInfo, allocator); + } + #endif + + inline void Surface::Destroy() + { + if (m_surface) + m_instance.vkDestroySurfaceKHR(m_instance, m_surface, (m_allocator.pfnAllocation) ? &m_allocator : nullptr); + } + + inline bool Surface::IsSupported() const + { + if (!m_instance.IsExtensionLoaded("VK_KHR_surface")) + return false; + + #ifdef VK_USE_PLATFORM_ANDROID_KHR + if (m_instance.IsExtensionLoaded("VK_KHR_android_surface")) + return true; + #endif + + #ifdef VK_USE_PLATFORM_MIR_KHR + if (m_instance.IsExtensionLoaded("VK_KHR_mir_surface")) + return true; + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + if (m_instance.IsExtensionLoaded("VK_KHR_xcb_surface")) + return true; + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + if (m_instance.IsExtensionLoaded("VK_KHR_xlib_surface")) + return true; + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + if (m_instance.IsExtensionLoaded("VK_KHR_wayland_surface")) + return true; + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + if (m_instance.IsExtensionLoaded("VK_KHR_win32_surface")) + return true; + #endif + + return false; + } + } +} + +#include diff --git a/src/Nazara/Vulkan/VkSurface.cpp b/src/Nazara/Vulkan/VkSurface.cpp new file mode 100644 index 000000000..87b8657a9 --- /dev/null +++ b/src/Nazara/Vulkan/VkSurface.cpp @@ -0,0 +1,78 @@ +// Copyright (C) 2016 Jérôme Leclercq +// This file is part of the "Nazara Engine - Vulkan" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + namespace Vk + { + #ifdef VK_USE_PLATFORM_ANDROID_KHR + bool Surface::Create(const VkAndroidSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.PFN_vkCreateAndroidSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_MIR_KHR + bool Surface::Create(const VkMirSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.PFN_vkCreateMirSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + bool Surface::Create(const VkXcbSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.PFN_vkCreateXcbSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + bool Surface::Create(const VkXlibSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.PFN_vkCreateXlibSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + bool Surface::Create(const VkWaylandSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.vkCreateWaylandSurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + bool Surface::Create(const VkWin32SurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator) + { + m_lastErrorCode = m_instance.vkCreateWin32SurfaceKHR(m_instance, &createInfo, allocator, &m_surface); + return Create(allocator); + } + #endif + + bool Surface::Create(const VkAllocationCallbacks* allocator) + { + if (m_lastErrorCode != VkResult::VK_SUCCESS) + { + NazaraError("Failed to create Vulkan surface"); + return false; + } + + // Store the allocator to access them when needed + if (allocator) + m_allocator = *allocator; + else + m_allocator.pfnAllocation = nullptr; + + return true; + } + } +}