From f9869cb2163b0e3644dae4c7b592cdc5b516608b Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 24 Oct 2018 14:47:48 +1000 Subject: Vulkan: Support runtime selection of WSI --- Source/Core/VideoBackends/Vulkan/SwapChain.cpp | 172 ++++++++++++------------- 1 file changed, 79 insertions(+), 93 deletions(-) (limited to 'Source/Core/VideoBackends/Vulkan/SwapChain.cpp') diff --git a/Source/Core/VideoBackends/Vulkan/SwapChain.cpp b/Source/Core/VideoBackends/Vulkan/SwapChain.cpp index 2759a59283..94cd0ade67 100644 --- a/Source/Core/VideoBackends/Vulkan/SwapChain.cpp +++ b/Source/Core/VideoBackends/Vulkan/SwapChain.cpp @@ -18,16 +18,12 @@ #if defined(VK_USE_PLATFORM_XLIB_KHR) #include -#elif defined(VK_USE_PLATFORM_XCB_KHR) -#include -#include #endif namespace Vulkan { -SwapChain::SwapChain(void* display_handle, void* native_handle, VkSurfaceKHR surface, bool vsync) - : m_display_handle(display_handle), m_native_handle(native_handle), m_surface(surface), - m_vsync_enabled(vsync) +SwapChain::SwapChain(const WindowSystemInfo& wsi, VkSurfaceKHR surface, bool vsync) + : m_wsi(wsi), m_surface(surface), m_vsync_enabled(vsync) { } @@ -39,110 +35,101 @@ SwapChain::~SwapChain() DestroySemaphores(); } -VkSurfaceKHR SwapChain::CreateVulkanSurface(VkInstance instance, void* display_handle, void* hwnd) +VkSurfaceKHR SwapChain::CreateVulkanSurface(VkInstance instance, const WindowSystemInfo& wsi) { #if defined(VK_USE_PLATFORM_WIN32_KHR) - VkWin32SurfaceCreateInfoKHR surface_create_info = { - VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, // VkStructureType sType - nullptr, // const void* pNext - 0, // VkWin32SurfaceCreateFlagsKHR flags - nullptr, // HINSTANCE hinstance - reinterpret_cast(hwnd) // HWND hwnd - }; - - VkSurfaceKHR surface; - VkResult res = vkCreateWin32SurfaceKHR(instance, &surface_create_info, nullptr, &surface); - if (res != VK_SUCCESS) + if (wsi.type == WindowSystemType::Windows) { - LOG_VULKAN_ERROR(res, "vkCreateWin32SurfaceKHR failed: "); - return VK_NULL_HANDLE; - } - - return surface; - -#elif defined(VK_USE_PLATFORM_XLIB_KHR) - VkXlibSurfaceCreateInfoKHR surface_create_info = { - VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, // VkStructureType sType - nullptr, // const void* pNext - 0, // VkXlibSurfaceCreateFlagsKHR flags - static_cast(display_handle), // Display* dpy - reinterpret_cast(hwnd) // Window window - }; + VkWin32SurfaceCreateInfoKHR surface_create_info = { + VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, // VkStructureType sType + nullptr, // const void* pNext + 0, // VkWin32SurfaceCreateFlagsKHR flags + nullptr, // HINSTANCE hinstance + reinterpret_cast(wsi.render_surface) // HWND hwnd + }; + + VkSurfaceKHR surface; + VkResult res = vkCreateWin32SurfaceKHR(instance, &surface_create_info, nullptr, &surface); + if (res != VK_SUCCESS) + { + LOG_VULKAN_ERROR(res, "vkCreateWin32SurfaceKHR failed: "); + return VK_NULL_HANDLE; + } - VkSurfaceKHR surface; - VkResult res = vkCreateXlibSurfaceKHR(instance, &surface_create_info, nullptr, &surface); - if (res != VK_SUCCESS) - { - LOG_VULKAN_ERROR(res, "vkCreateXlibSurfaceKHR failed: "); - return VK_NULL_HANDLE; + return surface; } +#endif - return surface; - -#elif defined(VK_USE_PLATFORM_XCB_KHR) - // If we ever switch to using xcb, we should pass the display handle as well. - xcb_connection_t* connection = XGetXCBConnection(display_handle); - - VkXcbSurfaceCreateInfoKHR surface_create_info = { - VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, // VkStructureType sType - nullptr, // const void* pNext - 0, // VkXcbSurfaceCreateFlagsKHR flags - connection, // xcb_connection_t* connection - static_cast(reinterpret_cast(hwnd)) // xcb_window_t window - }; - - VkSurfaceKHR surface; - VkResult res = vkCreateXcbSurfaceKHR(instance, &surface_create_info, nullptr, &surface); - if (res != VK_SUCCESS) +#if defined(VK_USE_PLATFORM_XLIB_KHR) + if (wsi.type == WindowSystemType::X11) { - LOG_VULKAN_ERROR(res, "vkCreateXcbSurfaceKHR failed: "); - return VK_NULL_HANDLE; - } - - return surface; + VkXlibSurfaceCreateInfoKHR surface_create_info = { + VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, // VkStructureType sType + nullptr, // const void* pNext + 0, // VkXlibSurfaceCreateFlagsKHR flags + static_cast(wsi.display_connection), // Display* dpy + reinterpret_cast(wsi.render_surface) // Window window + }; + + VkSurfaceKHR surface; + VkResult res = vkCreateXlibSurfaceKHR(instance, &surface_create_info, nullptr, &surface); + if (res != VK_SUCCESS) + { + LOG_VULKAN_ERROR(res, "vkCreateXlibSurfaceKHR failed: "); + return VK_NULL_HANDLE; + } -#elif defined(VK_USE_PLATFORM_ANDROID_KHR) - VkAndroidSurfaceCreateInfoKHR surface_create_info = { - VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR, // VkStructureType sType - nullptr, // const void* pNext - 0, // VkAndroidSurfaceCreateFlagsKHR flags - reinterpret_cast(hwnd) // ANativeWindow* window - }; + return surface; + } +#endif - VkSurfaceKHR surface; - VkResult res = vkCreateAndroidSurfaceKHR(instance, &surface_create_info, nullptr, &surface); - if (res != VK_SUCCESS) +#if defined(VK_USE_PLATFORM_ANDROID_KHR) + if (wsi.type == WindowSystemType::Android) { - LOG_VULKAN_ERROR(res, "vkCreateAndroidSurfaceKHR failed: "); - return VK_NULL_HANDLE; + VkAndroidSurfaceCreateInfoKHR surface_create_info = { + VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR, // VkStructureType sType + nullptr, // const void* pNext + 0, // VkAndroidSurfaceCreateFlagsKHR flags + reinterpret_cast(wsi.render_surface) // ANativeWindow* window + }; + + VkSurfaceKHR surface; + VkResult res = vkCreateAndroidSurfaceKHR(instance, &surface_create_info, nullptr, &surface); + if (res != VK_SUCCESS) + { + LOG_VULKAN_ERROR(res, "vkCreateAndroidSurfaceKHR failed: "); + return VK_NULL_HANDLE; + } + + return surface; } +#endif - return surface; +#if defined(VK_USE_PLATFORM_MACOS_MVK) + if (wsi.type == WindowSystemType::MacOS) + { + VkMacOSSurfaceCreateInfoMVK surface_create_info = { + VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK, nullptr, 0, wsi.render_surface}; -#elif defined(VK_USE_PLATFORM_MACOS_MVK) - VkMacOSSurfaceCreateInfoMVK surface_create_info = { - VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK, nullptr, 0, hwnd}; + VkSurfaceKHR surface; + VkResult res = vkCreateMacOSSurfaceMVK(instance, &surface_create_info, nullptr, &surface); + if (res != VK_SUCCESS) + { + LOG_VULKAN_ERROR(res, "vkCreateMacOSSurfaceMVK failed: "); + return VK_NULL_HANDLE; + } - VkSurfaceKHR surface; - VkResult res = vkCreateMacOSSurfaceMVK(instance, &surface_create_info, nullptr, &surface); - if (res != VK_SUCCESS) - { - LOG_VULKAN_ERROR(res, "vkCreateMacOSSurfaceMVK failed: "); - return VK_NULL_HANDLE; + return surface; } +#endif - return surface; -#else return VK_NULL_HANDLE; -#endif } -std::unique_ptr SwapChain::Create(void* display_handle, void* native_handle, - VkSurfaceKHR surface, bool vsync) +std::unique_ptr SwapChain::Create(const WindowSystemInfo& wsi, VkSurfaceKHR surface, + bool vsync) { - std::unique_ptr swap_chain = - std::make_unique(display_handle, native_handle, surface, vsync); - + std::unique_ptr swap_chain = std::make_unique(wsi, surface, vsync); if (!swap_chain->CreateSemaphores() || !swap_chain->CreateSwapChain() || !swap_chain->SetupSwapChainImages()) { @@ -531,9 +518,8 @@ bool SwapChain::RecreateSurface(void* native_handle) DestroySurface(); // Re-create the surface with the new native handle - m_native_handle = native_handle; - m_surface = - CreateVulkanSurface(g_vulkan_context->GetVulkanInstance(), m_display_handle, native_handle); + m_wsi.render_surface = native_handle; + m_surface = CreateVulkanSurface(g_vulkan_context->GetVulkanInstance(), m_wsi); if (m_surface == VK_NULL_HANDLE) return false; -- cgit v1.2.3