diff options
| -rw-r--r-- | src/video_core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.cpp | 74 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.h | 2 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_surface.cpp | 81 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_surface.h | 18 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_wrapper.h | 5 |
6 files changed, 109 insertions, 73 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 9287faee1..f977cf12b 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -264,6 +264,8 @@ add_library(video_core STATIC | |||
| 264 | vulkan_common/vulkan_instance.h | 264 | vulkan_common/vulkan_instance.h |
| 265 | vulkan_common/vulkan_library.cpp | 265 | vulkan_common/vulkan_library.cpp |
| 266 | vulkan_common/vulkan_library.h | 266 | vulkan_common/vulkan_library.h |
| 267 | vulkan_common/vulkan_surface.cpp | ||
| 268 | vulkan_common/vulkan_surface.h | ||
| 267 | vulkan_common/vulkan_wrapper.cpp | 269 | vulkan_common/vulkan_wrapper.cpp |
| 268 | vulkan_common/vulkan_wrapper.h | 270 | vulkan_common/vulkan_wrapper.h |
| 269 | ) | 271 | ) |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index ccdc86ed7..831c204c2 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp | |||
| @@ -32,21 +32,9 @@ | |||
| 32 | #include "video_core/vulkan_common/vulkan_debug_callback.h" | 32 | #include "video_core/vulkan_common/vulkan_debug_callback.h" |
| 33 | #include "video_core/vulkan_common/vulkan_instance.h" | 33 | #include "video_core/vulkan_common/vulkan_instance.h" |
| 34 | #include "video_core/vulkan_common/vulkan_library.h" | 34 | #include "video_core/vulkan_common/vulkan_library.h" |
| 35 | #include "video_core/vulkan_common/vulkan_surface.h" | ||
| 35 | #include "video_core/vulkan_common/vulkan_wrapper.h" | 36 | #include "video_core/vulkan_common/vulkan_wrapper.h" |
| 36 | 37 | ||
| 37 | // Include these late to avoid polluting previous headers | ||
| 38 | #ifdef _WIN32 | ||
| 39 | #include <windows.h> | ||
| 40 | // ensure include order | ||
| 41 | #include <vulkan/vulkan_win32.h> | ||
| 42 | #endif | ||
| 43 | |||
| 44 | #if !defined(_WIN32) && !defined(__APPLE__) | ||
| 45 | #include <X11/Xlib.h> | ||
| 46 | #include <vulkan/vulkan_wayland.h> | ||
| 47 | #include <vulkan/vulkan_xlib.h> | ||
| 48 | #endif | ||
| 49 | |||
| 50 | namespace Vulkan { | 38 | namespace Vulkan { |
| 51 | namespace { | 39 | namespace { |
| 52 | std::string GetReadableVersion(u32 version) { | 40 | std::string GetReadableVersion(u32 version) { |
| @@ -144,8 +132,8 @@ bool RendererVulkan::Init() try { | |||
| 144 | if (Settings::values.renderer_debug) { | 132 | if (Settings::values.renderer_debug) { |
| 145 | debug_callback = CreateDebugCallback(instance); | 133 | debug_callback = CreateDebugCallback(instance); |
| 146 | } | 134 | } |
| 147 | 135 | surface = CreateSurface(instance, render_window); | |
| 148 | if (!CreateSurface() || !PickDevices()) { | 136 | if (!PickDevices()) { |
| 149 | return false; | 137 | return false; |
| 150 | } | 138 | } |
| 151 | 139 | ||
| @@ -191,62 +179,6 @@ void RendererVulkan::ShutDown() { | |||
| 191 | device.reset(); | 179 | device.reset(); |
| 192 | } | 180 | } |
| 193 | 181 | ||
| 194 | bool RendererVulkan::CreateSurface() { | ||
| 195 | [[maybe_unused]] const auto& window_info = render_window.GetWindowInfo(); | ||
| 196 | VkSurfaceKHR unsafe_surface = nullptr; | ||
| 197 | |||
| 198 | #ifdef _WIN32 | ||
| 199 | if (window_info.type == Core::Frontend::WindowSystemType::Windows) { | ||
| 200 | const HWND hWnd = static_cast<HWND>(window_info.render_surface); | ||
| 201 | const VkWin32SurfaceCreateInfoKHR win32_ci{VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, | ||
| 202 | nullptr, 0, nullptr, hWnd}; | ||
| 203 | const auto vkCreateWin32SurfaceKHR = reinterpret_cast<PFN_vkCreateWin32SurfaceKHR>( | ||
| 204 | dld.vkGetInstanceProcAddr(*instance, "vkCreateWin32SurfaceKHR")); | ||
| 205 | if (!vkCreateWin32SurfaceKHR || | ||
| 206 | vkCreateWin32SurfaceKHR(*instance, &win32_ci, nullptr, &unsafe_surface) != VK_SUCCESS) { | ||
| 207 | LOG_ERROR(Render_Vulkan, "Failed to initialize Win32 surface"); | ||
| 208 | return false; | ||
| 209 | } | ||
| 210 | } | ||
| 211 | #endif | ||
| 212 | #if !defined(_WIN32) && !defined(__APPLE__) | ||
| 213 | if (window_info.type == Core::Frontend::WindowSystemType::X11) { | ||
| 214 | const VkXlibSurfaceCreateInfoKHR xlib_ci{ | ||
| 215 | VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, nullptr, 0, | ||
| 216 | static_cast<Display*>(window_info.display_connection), | ||
| 217 | reinterpret_cast<Window>(window_info.render_surface)}; | ||
| 218 | const auto vkCreateXlibSurfaceKHR = reinterpret_cast<PFN_vkCreateXlibSurfaceKHR>( | ||
| 219 | dld.vkGetInstanceProcAddr(*instance, "vkCreateXlibSurfaceKHR")); | ||
| 220 | if (!vkCreateXlibSurfaceKHR || | ||
| 221 | vkCreateXlibSurfaceKHR(*instance, &xlib_ci, nullptr, &unsafe_surface) != VK_SUCCESS) { | ||
| 222 | LOG_ERROR(Render_Vulkan, "Failed to initialize Xlib surface"); | ||
| 223 | return false; | ||
| 224 | } | ||
| 225 | } | ||
| 226 | if (window_info.type == Core::Frontend::WindowSystemType::Wayland) { | ||
| 227 | const VkWaylandSurfaceCreateInfoKHR wayland_ci{ | ||
| 228 | VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, nullptr, 0, | ||
| 229 | static_cast<wl_display*>(window_info.display_connection), | ||
| 230 | static_cast<wl_surface*>(window_info.render_surface)}; | ||
| 231 | const auto vkCreateWaylandSurfaceKHR = reinterpret_cast<PFN_vkCreateWaylandSurfaceKHR>( | ||
| 232 | dld.vkGetInstanceProcAddr(*instance, "vkCreateWaylandSurfaceKHR")); | ||
| 233 | if (!vkCreateWaylandSurfaceKHR || | ||
| 234 | vkCreateWaylandSurfaceKHR(*instance, &wayland_ci, nullptr, &unsafe_surface) != | ||
| 235 | VK_SUCCESS) { | ||
| 236 | LOG_ERROR(Render_Vulkan, "Failed to initialize Wayland surface"); | ||
| 237 | return false; | ||
| 238 | } | ||
| 239 | } | ||
| 240 | #endif | ||
| 241 | if (!unsafe_surface) { | ||
| 242 | LOG_ERROR(Render_Vulkan, "Presentation not supported on this platform"); | ||
| 243 | return false; | ||
| 244 | } | ||
| 245 | |||
| 246 | surface = vk::SurfaceKHR(unsafe_surface, *instance, dld); | ||
| 247 | return true; | ||
| 248 | } | ||
| 249 | |||
| 250 | bool RendererVulkan::PickDevices() { | 182 | bool RendererVulkan::PickDevices() { |
| 251 | const auto devices = instance.EnumeratePhysicalDevices(); | 183 | const auto devices = instance.EnumeratePhysicalDevices(); |
| 252 | if (!devices) { | 184 | if (!devices) { |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index fa7628d0e..7c5ce1da4 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h | |||
| @@ -56,8 +56,6 @@ public: | |||
| 56 | static std::vector<std::string> EnumerateDevices(); | 56 | static std::vector<std::string> EnumerateDevices(); |
| 57 | 57 | ||
| 58 | private: | 58 | private: |
| 59 | bool CreateSurface(); | ||
| 60 | |||
| 61 | bool PickDevices(); | 59 | bool PickDevices(); |
| 62 | 60 | ||
| 63 | void Report() const; | 61 | void Report() const; |
diff --git a/src/video_core/vulkan_common/vulkan_surface.cpp b/src/video_core/vulkan_common/vulkan_surface.cpp new file mode 100644 index 000000000..3c3238f96 --- /dev/null +++ b/src/video_core/vulkan_common/vulkan_surface.cpp | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/logging/log.h" | ||
| 6 | #include "core/frontend/emu_window.h" | ||
| 7 | #include "video_core/vulkan_common/vulkan_surface.h" | ||
| 8 | #include "video_core/vulkan_common/vulkan_wrapper.h" | ||
| 9 | |||
| 10 | // Include these late to avoid polluting previous headers | ||
| 11 | #ifdef _WIN32 | ||
| 12 | #include <windows.h> | ||
| 13 | // ensure include order | ||
| 14 | #include <vulkan/vulkan_win32.h> | ||
| 15 | #endif | ||
| 16 | |||
| 17 | #if !defined(_WIN32) && !defined(__APPLE__) | ||
| 18 | #include <X11/Xlib.h> | ||
| 19 | #include <vulkan/vulkan_wayland.h> | ||
| 20 | #include <vulkan/vulkan_xlib.h> | ||
| 21 | #endif | ||
| 22 | |||
| 23 | namespace Vulkan { | ||
| 24 | |||
| 25 | vk::SurfaceKHR CreateSurface(const vk::Instance& instance, | ||
| 26 | const Core::Frontend::EmuWindow& emu_window) { | ||
| 27 | [[maybe_unused]] const vk::InstanceDispatch& dld = instance.Dispatch(); | ||
| 28 | [[maybe_unused]] const auto& window_info = emu_window.GetWindowInfo(); | ||
| 29 | VkSurfaceKHR unsafe_surface = nullptr; | ||
| 30 | |||
| 31 | #ifdef _WIN32 | ||
| 32 | if (window_info.type == Core::Frontend::WindowSystemType::Windows) { | ||
| 33 | const HWND hWnd = static_cast<HWND>(window_info.render_surface); | ||
| 34 | const VkWin32SurfaceCreateInfoKHR win32_ci{VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, | ||
| 35 | nullptr, 0, nullptr, hWnd}; | ||
| 36 | const auto vkCreateWin32SurfaceKHR = reinterpret_cast<PFN_vkCreateWin32SurfaceKHR>( | ||
| 37 | dld.vkGetInstanceProcAddr(*instance, "vkCreateWin32SurfaceKHR")); | ||
| 38 | if (!vkCreateWin32SurfaceKHR || | ||
| 39 | vkCreateWin32SurfaceKHR(*instance, &win32_ci, nullptr, &unsafe_surface) != VK_SUCCESS) { | ||
| 40 | LOG_ERROR(Render_Vulkan, "Failed to initialize Win32 surface"); | ||
| 41 | throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); | ||
| 42 | } | ||
| 43 | } | ||
| 44 | #endif | ||
| 45 | #if !defined(_WIN32) && !defined(__APPLE__) | ||
| 46 | if (window_info.type == Core::Frontend::WindowSystemType::X11) { | ||
| 47 | const VkXlibSurfaceCreateInfoKHR xlib_ci{ | ||
| 48 | VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, nullptr, 0, | ||
| 49 | static_cast<Display*>(window_info.display_connection), | ||
| 50 | reinterpret_cast<Window>(window_info.render_surface)}; | ||
| 51 | const auto vkCreateXlibSurfaceKHR = reinterpret_cast<PFN_vkCreateXlibSurfaceKHR>( | ||
| 52 | dld.vkGetInstanceProcAddr(*instance, "vkCreateXlibSurfaceKHR")); | ||
| 53 | if (!vkCreateXlibSurfaceKHR || | ||
| 54 | vkCreateXlibSurfaceKHR(*instance, &xlib_ci, nullptr, &unsafe_surface) != VK_SUCCESS) { | ||
| 55 | LOG_ERROR(Render_Vulkan, "Failed to initialize Xlib surface"); | ||
| 56 | throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | if (window_info.type == Core::Frontend::WindowSystemType::Wayland) { | ||
| 60 | const VkWaylandSurfaceCreateInfoKHR wayland_ci{ | ||
| 61 | VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, nullptr, 0, | ||
| 62 | static_cast<wl_display*>(window_info.display_connection), | ||
| 63 | static_cast<wl_surface*>(window_info.render_surface)}; | ||
| 64 | const auto vkCreateWaylandSurfaceKHR = reinterpret_cast<PFN_vkCreateWaylandSurfaceKHR>( | ||
| 65 | dld.vkGetInstanceProcAddr(*instance, "vkCreateWaylandSurfaceKHR")); | ||
| 66 | if (!vkCreateWaylandSurfaceKHR || | ||
| 67 | vkCreateWaylandSurfaceKHR(*instance, &wayland_ci, nullptr, &unsafe_surface) != | ||
| 68 | VK_SUCCESS) { | ||
| 69 | LOG_ERROR(Render_Vulkan, "Failed to initialize Wayland surface"); | ||
| 70 | throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); | ||
| 71 | } | ||
| 72 | } | ||
| 73 | #endif | ||
| 74 | if (!unsafe_surface) { | ||
| 75 | LOG_ERROR(Render_Vulkan, "Presentation not supported on this platform"); | ||
| 76 | throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); | ||
| 77 | } | ||
| 78 | return vk::SurfaceKHR(unsafe_surface, *instance, dld); | ||
| 79 | } | ||
| 80 | |||
| 81 | } // namespace Vulkan | ||
diff --git a/src/video_core/vulkan_common/vulkan_surface.h b/src/video_core/vulkan_common/vulkan_surface.h new file mode 100644 index 000000000..05a169e32 --- /dev/null +++ b/src/video_core/vulkan_common/vulkan_surface.h | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "video_core/vulkan_common/vulkan_wrapper.h" | ||
| 8 | |||
| 9 | namespace Core::Frontend { | ||
| 10 | class EmuWindow; | ||
| 11 | } | ||
| 12 | |||
| 13 | namespace Vulkan { | ||
| 14 | |||
| 15 | [[nodiscard]] vk::SurfaceKHR CreateSurface(const vk::Instance& instance, | ||
| 16 | const Core::Frontend::EmuWindow& emu_window); | ||
| 17 | |||
| 18 | } // namespace Vulkan | ||
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index 03ca97ac0..012982a3f 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h | |||
| @@ -586,6 +586,11 @@ public: | |||
| 586 | /// @throw Exception on creation failure. | 586 | /// @throw Exception on creation failure. |
| 587 | DebugUtilsMessenger CreateDebugUtilsMessenger( | 587 | DebugUtilsMessenger CreateDebugUtilsMessenger( |
| 588 | const VkDebugUtilsMessengerCreateInfoEXT& create_info) const; | 588 | const VkDebugUtilsMessengerCreateInfoEXT& create_info) const; |
| 589 | |||
| 590 | /// Returns dispatch table. | ||
| 591 | const InstanceDispatch& Dispatch() const noexcept { | ||
| 592 | return *dld; | ||
| 593 | } | ||
| 589 | }; | 594 | }; |
| 590 | 595 | ||
| 591 | class Queue { | 596 | class Queue { |