Replace RenderWindow with swapchains

This commit is contained in:
SirLynix
2023-01-21 12:02:34 +01:00
committed by Jérôme Leclercq
parent 8db1c04568
commit 18851c9185
66 changed files with 1404 additions and 2048 deletions

View File

@@ -17,78 +17,75 @@
#include <vulkan/vulkan_metal.h>
#endif
namespace Nz
namespace Nz::Vk
{
namespace Vk
class Surface
{
class Surface
{
public:
inline Surface(Instance& instance);
Surface(const Surface&) = delete;
Surface(Surface&& surface);
inline ~Surface();
public:
inline Surface(Instance& instance);
Surface(const Surface&) = delete;
Surface(Surface&& surface) noexcept;
inline ~Surface();
#ifdef VK_USE_PLATFORM_ANDROID_KHR
// VK_KHR_android_surface
inline 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_ANDROID_KHR
// VK_KHR_android_surface
inline 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_XCB_KHR
// VK_KHR_xcb_surface
inline 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_XCB_KHR
// VK_KHR_xcb_surface
inline 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
inline 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_XLIB_KHR
// VK_KHR_xlib_surface
inline 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
inline 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_WAYLAND_KHR
// VK_KHR_wayland_surface
inline 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
inline bool Create(const VkWin32SurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr);
inline bool Create(HINSTANCE instance, HWND handle, VkWin32SurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr);
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
// VK_KHR_win32_surface
inline bool Create(const VkWin32SurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator = nullptr);
inline bool Create(HINSTANCE instance, HWND handle, VkWin32SurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr);
#endif
#ifdef VK_USE_PLATFORM_METAL_EXT
inline bool Create(const VkMetalSurfaceCreateInfoEXT& createInfo, const VkAllocationCallbacks* allocator = nullptr);
inline bool Create(id layer, const VkAllocationCallbacks* allocator = nullptr);
#endif
#ifdef VK_USE_PLATFORM_METAL_EXT
inline bool Create(const VkMetalSurfaceCreateInfoEXT& createInfo, const VkAllocationCallbacks* allocator = nullptr);
inline bool Create(id layer, const VkAllocationCallbacks* allocator = nullptr);
#endif
inline void Destroy();
inline void Destroy();
bool GetCapabilities(VkPhysicalDevice physicalDevice, VkSurfaceCapabilitiesKHR* surfaceCapabilities) const;
bool GetFormats(VkPhysicalDevice physicalDevice, std::vector<VkSurfaceFormatKHR>* surfaceFormats) const;
bool GetPresentModes(VkPhysicalDevice physicalDevice, std::vector<VkPresentModeKHR>* presentModes) const;
bool GetSupportPresentation(VkPhysicalDevice physicalDevice, UInt32 queueFamilyIndex, bool* supported) const;
bool GetCapabilities(VkPhysicalDevice physicalDevice, VkSurfaceCapabilitiesKHR* surfaceCapabilities) const;
bool GetFormats(VkPhysicalDevice physicalDevice, std::vector<VkSurfaceFormatKHR>* surfaceFormats) const;
bool GetPresentModes(VkPhysicalDevice physicalDevice, std::vector<VkPresentModeKHR>* presentModes) const;
bool GetSupportPresentation(VkPhysicalDevice physicalDevice, UInt32 queueFamilyIndex, bool* supported) const;
inline VkResult GetLastErrorCode() const;
inline VkResult GetLastErrorCode() const;
Surface& operator=(const Surface&) = delete;
Surface& operator=(Surface&&) = delete;
Surface& operator=(const Surface&) = delete;
Surface& operator=(Surface&&) = delete;
inline operator VkSurfaceKHR() const;
inline operator VkSurfaceKHR() const;
static inline bool IsSupported(const Instance& instance);
static inline bool IsSupported(const Instance& instance);
private:
inline bool Create(const VkAllocationCallbacks* allocator);
private:
inline bool Create(const VkAllocationCallbacks* allocator);
Instance& m_instance;
VkAllocationCallbacks m_allocator;
VkSurfaceKHR m_surface;
mutable VkResult m_lastErrorCode;
};
}
Instance& m_instance;
VkAllocationCallbacks m_allocator;
VkSurfaceKHR m_surface;
mutable VkResult m_lastErrorCode;
};
}
#include <Nazara/VulkanRenderer/Wrapper/Surface.inl>

View File

@@ -7,305 +7,302 @@
#include <Nazara/VulkanRenderer/Utils.hpp>
#include <Nazara/VulkanRenderer/Debug.hpp>
namespace Nz
namespace Nz::Vk
{
namespace Vk
inline Surface::Surface(Instance& instance) :
m_instance(instance),
m_surface(VK_NULL_HANDLE)
{
inline Surface::Surface(Instance& instance) :
m_instance(instance),
m_surface(VK_NULL_HANDLE)
}
inline Surface::Surface(Surface&& surface) noexcept :
m_instance(surface.m_instance),
m_allocator(surface.m_allocator),
m_surface(surface.m_surface),
m_lastErrorCode(surface.m_lastErrorCode)
{
surface.m_surface = VK_NULL_HANDLE;
}
inline Surface::~Surface()
{
Destroy();
}
#ifdef VK_USE_PLATFORM_ANDROID_KHR
inline bool Surface::Create(const VkAndroidSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
{
m_lastErrorCode = m_instance.vkCreateAndroidSurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
return Create(allocator);
}
inline bool Surface::Create(ANativeWindow* window, VkAndroidSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
{
VkAndroidSurfaceCreateInfoKHR createInfo =
{
}
VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,
nullptr,
flags,
window
};
inline Surface::Surface(Surface&& surface) :
m_instance(surface.m_instance),
m_allocator(surface.m_allocator),
m_surface(surface.m_surface),
m_lastErrorCode(surface.m_lastErrorCode)
return Create(createInfo, allocator);
}
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
inline bool Surface::Create(const VkXcbSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
{
m_lastErrorCode = m_instance.vkCreateXcbSurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
return Create(allocator);
}
inline bool Surface::Create(xcb_connection_t* connection, xcb_window_t window, VkXcbSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
{
VkXcbSurfaceCreateInfoKHR createInfo =
{
surface.m_surface = VK_NULL_HANDLE;
}
VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR,
nullptr,
flags,
connection,
window
};
inline Surface::~Surface()
return Create(createInfo, allocator);
}
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
inline bool Surface::Create(const VkXlibSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
{
m_lastErrorCode = m_instance.vkCreateXlibSurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
return Create(allocator);
}
inline bool Surface::Create(Display* display, Window window, VkXlibSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
{
VkXlibSurfaceCreateInfoKHR createInfo =
{
Destroy();
}
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
nullptr,
flags,
display,
window
};
#ifdef VK_USE_PLATFORM_ANDROID_KHR
inline bool Surface::Create(const VkAndroidSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
return Create(createInfo, allocator);
}
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
inline bool Surface::Create(const VkWaylandSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
{
m_lastErrorCode = m_instance.vkCreateWaylandSurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
return Create(allocator);
}
inline bool Surface::Create(wl_display* display, wl_surface* surface, VkWaylandSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
{
VkWaylandSurfaceCreateInfoKHR createInfo =
{
m_lastErrorCode = m_instance.vkCreateAndroidSurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
return Create(allocator);
}
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR,
nullptr,
flags,
display,
surface
};
inline bool Surface::Create(ANativeWindow* window, VkAndroidSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
return Create(createInfo, allocator);
}
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
inline bool Surface::Create(const VkWin32SurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
{
m_lastErrorCode = m_instance.vkCreateWin32SurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
return Create(allocator);
}
inline bool Surface::Create(HINSTANCE instance, HWND handle, VkWin32SurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
{
VkWin32SurfaceCreateInfoKHR createInfo =
{
VkAndroidSurfaceCreateInfoKHR createInfo =
{
VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR,
nullptr,
flags,
window
};
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
nullptr,
flags,
instance,
handle
};
return Create(createInfo, allocator);
}
#endif
return Create(createInfo, allocator);
}
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
inline bool Surface::Create(const VkXcbSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
#ifdef VK_USE_PLATFORM_METAL_EXT
inline bool Surface::Create(const VkMetalSurfaceCreateInfoEXT& createInfo, const VkAllocationCallbacks* allocator)
{
m_lastErrorCode = m_instance.vkCreateMetalSurfaceEXT(m_instance, &createInfo, allocator, &m_surface);
return Create(allocator);
}
inline bool Surface::Create(id layer, const VkAllocationCallbacks* allocator)
{
VkMetalSurfaceCreateInfoEXT createInfo =
{
m_lastErrorCode = m_instance.vkCreateXcbSurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
return Create(allocator);
}
VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT,
nullptr,
0,
layer
};
inline bool Surface::Create(xcb_connection_t* connection, xcb_window_t window, VkXcbSurfaceCreateFlagsKHR flags, const VkAllocationCallbacks* allocator)
return Create(createInfo, allocator);
}
#endif
inline void Surface::Destroy()
{
if (m_surface != VK_NULL_HANDLE)
{
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(const VkXlibSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
{
m_lastErrorCode = m_instance.vkCreateXlibSurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
return Create(allocator);
}
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(const VkWaylandSurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
{
m_lastErrorCode = m_instance.vkCreateWaylandSurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
return Create(allocator);
}
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(const VkWin32SurfaceCreateInfoKHR& createInfo, const VkAllocationCallbacks* allocator)
{
m_lastErrorCode = m_instance.vkCreateWin32SurfaceKHR(m_instance, &createInfo, allocator, &m_surface);
return Create(allocator);
}
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
#ifdef VK_USE_PLATFORM_METAL_EXT
inline bool Surface::Create(const VkMetalSurfaceCreateInfoEXT& createInfo, const VkAllocationCallbacks* allocator)
{
m_lastErrorCode = m_instance.vkCreateMetalSurfaceEXT(m_instance, &createInfo, allocator, &m_surface);
return Create(allocator);
}
inline bool Surface::Create(id layer, const VkAllocationCallbacks* allocator)
{
VkMetalSurfaceCreateInfoEXT createInfo =
{
VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT,
nullptr,
0,
layer
};
return Create(createInfo, allocator);
}
#endif
inline void Surface::Destroy()
{
if (m_surface != VK_NULL_HANDLE)
{
m_instance.vkDestroySurfaceKHR(m_instance, m_surface, (m_allocator.pfnAllocation) ? &m_allocator : nullptr);
m_surface = VK_NULL_HANDLE;
}
m_instance.vkDestroySurfaceKHR(m_instance, m_surface, (m_allocator.pfnAllocation) ? &m_allocator : nullptr);
m_surface = VK_NULL_HANDLE;
}
}
inline VkResult Surface::GetLastErrorCode() const
inline VkResult Surface::GetLastErrorCode() const
{
return m_lastErrorCode;
}
inline bool Surface::GetCapabilities(VkPhysicalDevice physicalDevice, VkSurfaceCapabilitiesKHR* surfaceCapabilities) const
{
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, m_surface, surfaceCapabilities);
if (m_lastErrorCode != VkResult::VK_SUCCESS)
{
return m_lastErrorCode;
}
inline bool Surface::GetCapabilities(VkPhysicalDevice physicalDevice, VkSurfaceCapabilitiesKHR* surfaceCapabilities) const
{
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, m_surface, surfaceCapabilities);
if (m_lastErrorCode != VkResult::VK_SUCCESS)
{
NazaraError("Failed to query surface capabilities: " + TranslateVulkanError(m_lastErrorCode));
return false;
}
return true;
}
inline bool Surface::GetFormats(VkPhysicalDevice physicalDevice, std::vector<VkSurfaceFormatKHR>* surfaceFormats) const
{
// First, query format count
UInt32 surfaceCount = 0; // Remember, Nz::UInt32 is a typedef on uint32_t
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, m_surface, &surfaceCount, nullptr);
if (m_lastErrorCode != VkResult::VK_SUCCESS || surfaceCount == 0)
{
NazaraError("Failed to query format count: " + TranslateVulkanError(m_lastErrorCode));
return false;
}
// Now we can get the list of the available physical device
surfaceFormats->resize(surfaceCount);
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, m_surface, &surfaceCount, surfaceFormats->data());
if (m_lastErrorCode != VkResult::VK_SUCCESS)
{
NazaraError("Failed to query formats: " + TranslateVulkanError(m_lastErrorCode));
return false;
}
return true;
}
inline bool Surface::GetPresentModes(VkPhysicalDevice physicalDevice, std::vector<VkPresentModeKHR>* presentModes) const
{
// First, query present modes count
UInt32 presentModeCount = 0; // Remember, Nz::UInt32 is a typedef on uint32_t
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, m_surface, &presentModeCount, nullptr);
if (m_lastErrorCode != VkResult::VK_SUCCESS || presentModeCount == 0)
{
NazaraError("Failed to query present mode count");
return false;
}
// Now we can get the list of the available physical device
presentModes->resize(presentModeCount);
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, m_surface, &presentModeCount, presentModes->data());
if (m_lastErrorCode != VkResult::VK_SUCCESS)
{
NazaraError("Failed to query present modes: " + TranslateVulkanError(m_lastErrorCode));
return false;
}
return true;
}
inline bool Surface::GetSupportPresentation(VkPhysicalDevice physicalDevice, UInt32 queueFamilyIndex, bool* supported) const
{
VkBool32 presentationSupported = VK_FALSE;
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, m_surface, &presentationSupported);
if (m_lastErrorCode != VkResult::VK_SUCCESS)
{
NazaraError("Failed to query surface capabilities: " + TranslateVulkanError(m_lastErrorCode));
return false;
}
*supported = (presentationSupported == VK_TRUE);
return true;
}
inline Surface::operator VkSurfaceKHR() const
{
return m_surface;
}
inline bool Surface::IsSupported(const Instance& instance)
{
if (!instance.IsExtensionLoaded(VK_KHR_SURFACE_EXTENSION_NAME))
return false;
#ifdef VK_USE_PLATFORM_ANDROID_KHR
if (instance.IsExtensionLoaded(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME))
return true;
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
if (instance.IsExtensionLoaded(VK_KHR_XCB_SURFACE_EXTENSION_NAME))
return true;
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
if (instance.IsExtensionLoaded(VK_KHR_XLIB_SURFACE_EXTENSION_NAME))
return true;
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
if (instance.IsExtensionLoaded(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME))
return true;
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
if (instance.IsExtensionLoaded(VK_KHR_WIN32_SURFACE_EXTENSION_NAME))
return true;
#endif
#ifdef VK_USE_PLATFORM_METAL_EXT
if (instance.IsExtensionLoaded(VK_EXT_METAL_SURFACE_EXTENSION_NAME))
return true;
#endif
NazaraError("Failed to query surface capabilities: " + TranslateVulkanError(m_lastErrorCode));
return false;
}
inline bool Surface::Create(const VkAllocationCallbacks* allocator)
return true;
}
inline bool Surface::GetFormats(VkPhysicalDevice physicalDevice, std::vector<VkSurfaceFormatKHR>* surfaceFormats) const
{
// First, query format count
UInt32 surfaceCount = 0; // Remember, Nz::UInt32 is a typedef on uint32_t
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, m_surface, &surfaceCount, nullptr);
if (m_lastErrorCode != VkResult::VK_SUCCESS || surfaceCount == 0)
{
if (m_lastErrorCode != VkResult::VK_SUCCESS)
{
NazaraError("Failed to create Vulkan surface: " + TranslateVulkanError(m_lastErrorCode));
return false;
}
// Store the allocator to access them when needed
if (allocator)
m_allocator = *allocator;
else
m_allocator.pfnAllocation = nullptr;
return true;
NazaraError("Failed to query format count: " + TranslateVulkanError(m_lastErrorCode));
return false;
}
// Now we can get the list of the available physical device
surfaceFormats->resize(surfaceCount);
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, m_surface, &surfaceCount, surfaceFormats->data());
if (m_lastErrorCode != VkResult::VK_SUCCESS)
{
NazaraError("Failed to query formats: " + TranslateVulkanError(m_lastErrorCode));
return false;
}
return true;
}
inline bool Surface::GetPresentModes(VkPhysicalDevice physicalDevice, std::vector<VkPresentModeKHR>* presentModes) const
{
// First, query present modes count
UInt32 presentModeCount = 0; // Remember, Nz::UInt32 is a typedef on uint32_t
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, m_surface, &presentModeCount, nullptr);
if (m_lastErrorCode != VkResult::VK_SUCCESS || presentModeCount == 0)
{
NazaraError("Failed to query present mode count");
return false;
}
// Now we can get the list of the available physical device
presentModes->resize(presentModeCount);
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, m_surface, &presentModeCount, presentModes->data());
if (m_lastErrorCode != VkResult::VK_SUCCESS)
{
NazaraError("Failed to query present modes: " + TranslateVulkanError(m_lastErrorCode));
return false;
}
return true;
}
inline bool Surface::GetSupportPresentation(VkPhysicalDevice physicalDevice, UInt32 queueFamilyIndex, bool* supported) const
{
VkBool32 presentationSupported = VK_FALSE;
m_lastErrorCode = m_instance.vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, m_surface, &presentationSupported);
if (m_lastErrorCode != VkResult::VK_SUCCESS)
{
NazaraError("Failed to query surface capabilities: " + TranslateVulkanError(m_lastErrorCode));
return false;
}
*supported = (presentationSupported == VK_TRUE);
return true;
}
inline Surface::operator VkSurfaceKHR() const
{
return m_surface;
}
inline bool Surface::IsSupported(const Instance& instance)
{
if (!instance.IsExtensionLoaded(VK_KHR_SURFACE_EXTENSION_NAME))
return false;
#ifdef VK_USE_PLATFORM_ANDROID_KHR
if (instance.IsExtensionLoaded(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME))
return true;
#endif
#ifdef VK_USE_PLATFORM_XCB_KHR
if (instance.IsExtensionLoaded(VK_KHR_XCB_SURFACE_EXTENSION_NAME))
return true;
#endif
#ifdef VK_USE_PLATFORM_XLIB_KHR
if (instance.IsExtensionLoaded(VK_KHR_XLIB_SURFACE_EXTENSION_NAME))
return true;
#endif
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
if (instance.IsExtensionLoaded(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME))
return true;
#endif
#ifdef VK_USE_PLATFORM_WIN32_KHR
if (instance.IsExtensionLoaded(VK_KHR_WIN32_SURFACE_EXTENSION_NAME))
return true;
#endif
#ifdef VK_USE_PLATFORM_METAL_EXT
if (instance.IsExtensionLoaded(VK_EXT_METAL_SURFACE_EXTENSION_NAME))
return true;
#endif
return false;
}
inline bool Surface::Create(const VkAllocationCallbacks* allocator)
{
if (m_lastErrorCode != VkResult::VK_SUCCESS)
{
NazaraError("Failed to create Vulkan surface: " + TranslateVulkanError(m_lastErrorCode));
return false;
}
// Store the allocator to access them when needed
if (allocator)
m_allocator = *allocator;
else
m_allocator.pfnAllocation = nullptr;
return true;
}
}