VulkanDevice: Support SDL window type

arm-build
Stenzek 2 months ago
parent 4bddd38d70
commit ee1a3b904e
No known key found for this signature in database

@ -23,6 +23,11 @@
#include "fmt/format.h"
#include "xxhash.h"
#ifdef ENABLE_SDL
#include <SDL3/SDL.h>
#include <SDL3/SDL_vulkan.h>
#endif
#include <cstdlib>
#include <limits>
#include <mutex>
@ -245,29 +250,53 @@ bool VulkanDevice::SelectInstanceExtensions(ExtensionList* extension_list, const
return false;
};
// Common extensions
if (wi.type != WindowInfo::Type::Surfaceless && !SupportsExtension(VK_KHR_SURFACE_EXTENSION_NAME, true))
return false;
#if defined(VK_USE_PLATFORM_WIN32_KHR)
if (wi.type == WindowInfo::Type::Win32 && !SupportsExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, true))
if (wi.type == WindowInfo::Type::Win32 && (!SupportsExtension(VK_KHR_SURFACE_EXTENSION_NAME, true) ||
!SupportsExtension(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, true)))
return false;
#endif
#if defined(VK_USE_PLATFORM_XCB_KHR)
if (wi.type == WindowInfo::Type::XCB && !SupportsExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME, true))
if (wi.type == WindowInfo::Type::XCB && (!SupportsExtension(VK_KHR_SURFACE_EXTENSION_NAME, true) ||
!SupportsExtension(VK_KHR_XCB_SURFACE_EXTENSION_NAME, true)))
return false;
#endif
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
if (wi.type == WindowInfo::Type::Wayland && !SupportsExtension(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, true))
if (wi.type == WindowInfo::Type::Wayland && (!SupportsExtension(VK_KHR_SURFACE_EXTENSION_NAME, true) ||
!SupportsExtension(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, true)))
return false;
#endif
#if defined(VK_USE_PLATFORM_METAL_EXT)
if (wi.type == WindowInfo::Type::MacOS && !SupportsExtension(VK_EXT_METAL_SURFACE_EXTENSION_NAME, true))
if (wi.type == WindowInfo::Type::MacOS && (!SupportsExtension(VK_KHR_SURFACE_EXTENSION_NAME, true) ||
!SupportsExtension(VK_EXT_METAL_SURFACE_EXTENSION_NAME, true)))
{
return false;
}
#endif
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
if (wi.type == WindowInfo::Type::Android && !SupportsExtension(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, true))
if (wi.type == WindowInfo::Type::Android && (!SupportsExtension(VK_KHR_SURFACE_EXTENSION_NAME, true) ||
!SupportsExtension(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, true)))
{
return false;
}
#endif
#if defined(ENABLE_SDL)
if (wi.type == WindowInfo::Type::SDL)
{
Uint32 sdl_extension_count = 0;
const char* const* sdl_extensions = SDL_Vulkan_GetInstanceExtensions(&sdl_extension_count);
if (!sdl_extensions)
{
ERROR_LOG("SDL_Vulkan_GetInstanceExtensions() failed: {}", SDL_GetError());
return false;
}
for (unsigned int i = 0; i < sdl_extension_count; i++)
{
if (!SupportsExtension(sdl_extensions[i], true))
return false;
}
}
#endif
// VK_EXT_debug_utils
@ -374,7 +403,10 @@ VulkanDevice::GPUList VulkanDevice::EnumerateGPUs()
if (Vulkan::LoadVulkanInstanceFunctions(instance))
ret = EnumerateGPUs(instance);
vkDestroyInstance(instance, nullptr);
if (vkDestroyInstance)
vkDestroyInstance(instance, nullptr);
else
ERROR_LOG("Vulkan instance was leaked because vkDestroyInstance() could not be loaded.");
}
Vulkan::UnloadVulkanLibrary();
@ -1894,7 +1926,13 @@ bool VulkanDevice::CreateDeviceAndMainSwapChain(std::string_view adapter, Featur
bool enable_debug_utils = m_debug_device;
bool enable_validation_layer = m_debug_device;
if (!Vulkan::LoadVulkanLibrary(error))
#ifdef ENABLE_SDL
const bool library_loaded =
(wi.type == WindowInfo::Type::SDL) ? Vulkan::LoadVulkanLibraryFromSDL(error) : Vulkan::LoadVulkanLibrary(error);
#else
const bool library_loaded = Vulkan::LoadVulkanLibrary(error);
#endif
if (!library_loaded)
{
Error::AddPrefix(error,
"Failed to load Vulkan library. Does your GPU and/or driver support Vulkan?\nThe error was:");
@ -1924,6 +1962,12 @@ bool VulkanDevice::CreateDeviceAndMainSwapChain(std::string_view adapter, Featur
{
ERROR_LOG("Failed to load Vulkan instance functions");
Error::SetStringView(error, "Failed to load Vulkan instance functions");
if (vkDestroyInstance)
vkDestroyInstance(std::exchange(m_instance, nullptr), nullptr);
else
ERROR_LOG("Vulkan instance was leaked because vkDestroyInstance() could not be loaded.");
return false;
}

@ -14,12 +14,12 @@ VULKAN_MODULE_ENTRY_POINT(vkGetInstanceProcAddr, true)
VULKAN_MODULE_ENTRY_POINT(vkEnumerateInstanceExtensionProperties, true)
VULKAN_MODULE_ENTRY_POINT(vkEnumerateInstanceLayerProperties, true)
VULKAN_MODULE_ENTRY_POINT(vkEnumerateInstanceVersion, false)
VULKAN_MODULE_ENTRY_POINT(vkDestroyInstance, true)
#endif // VULKAN_MODULE_ENTRY_POINT
#ifdef VULKAN_INSTANCE_ENTRY_POINT
VULKAN_INSTANCE_ENTRY_POINT(vkDestroyInstance, true)
VULKAN_INSTANCE_ENTRY_POINT(vkGetDeviceProcAddr, true)
VULKAN_INSTANCE_ENTRY_POINT(vkEnumeratePhysicalDevices, true)
VULKAN_INSTANCE_ENTRY_POINT(vkGetPhysicalDeviceFeatures, true)

@ -11,6 +11,10 @@
#include "common/error.h"
#include "common/log.h"
#ifdef ENABLE_SDL
#include <SDL3/SDL_vulkan.h>
#endif
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
@ -43,9 +47,17 @@ void Vulkan::ResetVulkanLibraryFunctionPointers()
static DynamicLibrary s_vulkan_library;
#ifdef ENABLE_SDL
static bool s_vulkan_library_loaded_from_sdl = false;
#endif
bool Vulkan::IsVulkanLibraryLoaded()
{
#ifdef ENABLE_SDL
return (s_vulkan_library.IsOpen() || s_vulkan_library_loaded_from_sdl);
#else
return s_vulkan_library.IsOpen();
#endif
}
bool Vulkan::LoadVulkanLibrary(Error* error)
@ -93,10 +105,65 @@ bool Vulkan::LoadVulkanLibrary(Error* error)
return true;
}
#ifdef ENABLE_SDL
bool Vulkan::LoadVulkanLibraryFromSDL(Error* error)
{
if (!SDL_Vulkan_LoadLibrary(nullptr))
{
Error::SetStringFmt(error, "SDL_Vulkan_LoadLibrary() failed: {}", SDL_GetError());
return false;
}
vkGetInstanceProcAddr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(SDL_Vulkan_GetVkGetInstanceProcAddr());
if (!vkGetInstanceProcAddr)
{
Error::SetStringFmt(error, "SDL_Vulkan_GetVkGetInstanceProcAddr() failed: {}", SDL_GetError());
SDL_Vulkan_UnloadLibrary();
return false;
}
bool required_functions_missing = false;
// vkGetInstanceProcAddr() can't resolve itself until Vulkan 1.2.
#define VULKAN_MODULE_ENTRY_POINT(name, required) \
if ((reinterpret_cast<const void*>(&name) != reinterpret_cast<const void*>(&vkGetInstanceProcAddr)) && \
!(name = reinterpret_cast<decltype(name)>(vkGetInstanceProcAddr(nullptr, #name))) && required) \
{ \
ERROR_LOG("Vulkan: Failed to load required module function {}", #name); \
required_functions_missing = true; \
}
#include "vulkan_entry_points.inl"
#undef VULKAN_MODULE_ENTRY_POINT
if (required_functions_missing)
{
Error::SetStringView(error, "One or more required functions are missing. The log contains more information.");
ResetVulkanLibraryFunctionPointers();
SDL_Vulkan_UnloadLibrary();
return false;
}
s_vulkan_library_loaded_from_sdl = true;
return true;
}
#endif
void Vulkan::UnloadVulkanLibrary()
{
ResetVulkanLibraryFunctionPointers();
s_vulkan_library.Close();
#ifdef ENABLE_SDL
if (s_vulkan_library_loaded_from_sdl)
{
s_vulkan_library_loaded_from_sdl = false;
SDL_Vulkan_UnloadLibrary();
}
#endif
}
bool Vulkan::LoadVulkanInstanceFunctions(VkInstance instance)

@ -59,10 +59,16 @@ class Error;
#endif
namespace Vulkan {
bool IsVulkanLibraryLoaded();
bool LoadVulkanLibrary(Error* error);
bool LoadVulkanInstanceFunctions(VkInstance instance);
bool LoadVulkanDeviceFunctions(VkDevice device);
void UnloadVulkanLibrary();
void ResetVulkanLibraryFunctionPointers();
#ifdef ENABLE_SDL
bool LoadVulkanLibraryFromSDL(Error* error);
#endif
} // namespace Vulkan

@ -13,14 +13,14 @@
#include <array>
#include <cmath>
#if defined(VK_USE_PLATFORM_XLIB_KHR)
#include <X11/Xlib.h>
#endif
#if defined(VK_USE_PLATFORM_METAL_EXT)
#include "util/metal_layer.h"
#endif
#ifdef ENABLE_SDL
#include <SDL3/SDL_vulkan.h>
#endif
LOG_CHANNEL(GPUDevice);
static VkFormat GetLinearFormat(VkFormat format)
@ -185,6 +185,19 @@ bool VulkanSwapChain::CreateSurface(VkInstance instance, VkPhysicalDevice physic
}
#endif
#if defined(ENABLE_SDL)
if (m_window_info.type == WindowInfo::Type::SDL)
{
if (!SDL_Vulkan_CreateSurface(static_cast<SDL_Window*>(m_window_info.window_handle), instance, nullptr, &m_surface))
{
Error::SetStringFmt(error, "SDL_Vulkan_CreateSurface() failed: {}", SDL_GetError());
return false;
}
return true;
}
#endif
Error::SetStringFmt(error, "Unhandled window type: {}", static_cast<unsigned>(m_window_info.type));
return false;
}

Loading…
Cancel
Save