forked from suyu/suyu
renderer_vulkan: Initialize surface in separate file
Move surface initialization code to a separate file. It's unlikely to use this code outside of Vulkan, but keeping platform-specific code (Win32, Xlib, Wayland) in its own translation unit keeps things cleaner.
This commit is contained in:
parent
dce8720780
commit
11f0f7598d
6 changed files with 109 additions and 73 deletions
|
@ -264,6 +264,8 @@ add_library(video_core STATIC
|
||||||
vulkan_common/vulkan_instance.h
|
vulkan_common/vulkan_instance.h
|
||||||
vulkan_common/vulkan_library.cpp
|
vulkan_common/vulkan_library.cpp
|
||||||
vulkan_common/vulkan_library.h
|
vulkan_common/vulkan_library.h
|
||||||
|
vulkan_common/vulkan_surface.cpp
|
||||||
|
vulkan_common/vulkan_surface.h
|
||||||
vulkan_common/vulkan_wrapper.cpp
|
vulkan_common/vulkan_wrapper.cpp
|
||||||
vulkan_common/vulkan_wrapper.h
|
vulkan_common/vulkan_wrapper.h
|
||||||
)
|
)
|
||||||
|
|
|
@ -32,21 +32,9 @@
|
||||||
#include "video_core/vulkan_common/vulkan_debug_callback.h"
|
#include "video_core/vulkan_common/vulkan_debug_callback.h"
|
||||||
#include "video_core/vulkan_common/vulkan_instance.h"
|
#include "video_core/vulkan_common/vulkan_instance.h"
|
||||||
#include "video_core/vulkan_common/vulkan_library.h"
|
#include "video_core/vulkan_common/vulkan_library.h"
|
||||||
|
#include "video_core/vulkan_common/vulkan_surface.h"
|
||||||
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||||
|
|
||||||
// Include these late to avoid polluting previous headers
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <windows.h>
|
|
||||||
// ensure include order
|
|
||||||
#include <vulkan/vulkan_win32.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <vulkan/vulkan_wayland.h>
|
|
||||||
#include <vulkan/vulkan_xlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
namespace {
|
namespace {
|
||||||
std::string GetReadableVersion(u32 version) {
|
std::string GetReadableVersion(u32 version) {
|
||||||
|
@ -144,8 +132,8 @@ bool RendererVulkan::Init() try {
|
||||||
if (Settings::values.renderer_debug) {
|
if (Settings::values.renderer_debug) {
|
||||||
debug_callback = CreateDebugCallback(instance);
|
debug_callback = CreateDebugCallback(instance);
|
||||||
}
|
}
|
||||||
|
surface = CreateSurface(instance, render_window);
|
||||||
if (!CreateSurface() || !PickDevices()) {
|
if (!PickDevices()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,62 +179,6 @@ void RendererVulkan::ShutDown() {
|
||||||
device.reset();
|
device.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RendererVulkan::CreateSurface() {
|
|
||||||
[[maybe_unused]] const auto& window_info = render_window.GetWindowInfo();
|
|
||||||
VkSurfaceKHR unsafe_surface = nullptr;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (window_info.type == Core::Frontend::WindowSystemType::Windows) {
|
|
||||||
const HWND hWnd = static_cast<HWND>(window_info.render_surface);
|
|
||||||
const VkWin32SurfaceCreateInfoKHR win32_ci{VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
|
|
||||||
nullptr, 0, nullptr, hWnd};
|
|
||||||
const auto vkCreateWin32SurfaceKHR = reinterpret_cast<PFN_vkCreateWin32SurfaceKHR>(
|
|
||||||
dld.vkGetInstanceProcAddr(*instance, "vkCreateWin32SurfaceKHR"));
|
|
||||||
if (!vkCreateWin32SurfaceKHR ||
|
|
||||||
vkCreateWin32SurfaceKHR(*instance, &win32_ci, nullptr, &unsafe_surface) != VK_SUCCESS) {
|
|
||||||
LOG_ERROR(Render_Vulkan, "Failed to initialize Win32 surface");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
|
||||||
if (window_info.type == Core::Frontend::WindowSystemType::X11) {
|
|
||||||
const VkXlibSurfaceCreateInfoKHR xlib_ci{
|
|
||||||
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, nullptr, 0,
|
|
||||||
static_cast<Display*>(window_info.display_connection),
|
|
||||||
reinterpret_cast<Window>(window_info.render_surface)};
|
|
||||||
const auto vkCreateXlibSurfaceKHR = reinterpret_cast<PFN_vkCreateXlibSurfaceKHR>(
|
|
||||||
dld.vkGetInstanceProcAddr(*instance, "vkCreateXlibSurfaceKHR"));
|
|
||||||
if (!vkCreateXlibSurfaceKHR ||
|
|
||||||
vkCreateXlibSurfaceKHR(*instance, &xlib_ci, nullptr, &unsafe_surface) != VK_SUCCESS) {
|
|
||||||
LOG_ERROR(Render_Vulkan, "Failed to initialize Xlib surface");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (window_info.type == Core::Frontend::WindowSystemType::Wayland) {
|
|
||||||
const VkWaylandSurfaceCreateInfoKHR wayland_ci{
|
|
||||||
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, nullptr, 0,
|
|
||||||
static_cast<wl_display*>(window_info.display_connection),
|
|
||||||
static_cast<wl_surface*>(window_info.render_surface)};
|
|
||||||
const auto vkCreateWaylandSurfaceKHR = reinterpret_cast<PFN_vkCreateWaylandSurfaceKHR>(
|
|
||||||
dld.vkGetInstanceProcAddr(*instance, "vkCreateWaylandSurfaceKHR"));
|
|
||||||
if (!vkCreateWaylandSurfaceKHR ||
|
|
||||||
vkCreateWaylandSurfaceKHR(*instance, &wayland_ci, nullptr, &unsafe_surface) !=
|
|
||||||
VK_SUCCESS) {
|
|
||||||
LOG_ERROR(Render_Vulkan, "Failed to initialize Wayland surface");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!unsafe_surface) {
|
|
||||||
LOG_ERROR(Render_Vulkan, "Presentation not supported on this platform");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
surface = vk::SurfaceKHR(unsafe_surface, *instance, dld);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RendererVulkan::PickDevices() {
|
bool RendererVulkan::PickDevices() {
|
||||||
const auto devices = instance.EnumeratePhysicalDevices();
|
const auto devices = instance.EnumeratePhysicalDevices();
|
||||||
if (!devices) {
|
if (!devices) {
|
||||||
|
|
|
@ -56,8 +56,6 @@ public:
|
||||||
static std::vector<std::string> EnumerateDevices();
|
static std::vector<std::string> EnumerateDevices();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool CreateSurface();
|
|
||||||
|
|
||||||
bool PickDevices();
|
bool PickDevices();
|
||||||
|
|
||||||
void Report() const;
|
void Report() const;
|
||||||
|
|
81
src/video_core/vulkan_common/vulkan_surface.cpp
Normal file
81
src/video_core/vulkan_common/vulkan_surface.cpp
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
// Copyright 2020 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "core/frontend/emu_window.h"
|
||||||
|
#include "video_core/vulkan_common/vulkan_surface.h"
|
||||||
|
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||||
|
|
||||||
|
// Include these late to avoid polluting previous headers
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
// ensure include order
|
||||||
|
#include <vulkan/vulkan_win32.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <vulkan/vulkan_wayland.h>
|
||||||
|
#include <vulkan/vulkan_xlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Vulkan {
|
||||||
|
|
||||||
|
vk::SurfaceKHR CreateSurface(const vk::Instance& instance,
|
||||||
|
const Core::Frontend::EmuWindow& emu_window) {
|
||||||
|
[[maybe_unused]] const vk::InstanceDispatch& dld = instance.Dispatch();
|
||||||
|
[[maybe_unused]] const auto& window_info = emu_window.GetWindowInfo();
|
||||||
|
VkSurfaceKHR unsafe_surface = nullptr;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (window_info.type == Core::Frontend::WindowSystemType::Windows) {
|
||||||
|
const HWND hWnd = static_cast<HWND>(window_info.render_surface);
|
||||||
|
const VkWin32SurfaceCreateInfoKHR win32_ci{VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
|
||||||
|
nullptr, 0, nullptr, hWnd};
|
||||||
|
const auto vkCreateWin32SurfaceKHR = reinterpret_cast<PFN_vkCreateWin32SurfaceKHR>(
|
||||||
|
dld.vkGetInstanceProcAddr(*instance, "vkCreateWin32SurfaceKHR"));
|
||||||
|
if (!vkCreateWin32SurfaceKHR ||
|
||||||
|
vkCreateWin32SurfaceKHR(*instance, &win32_ci, nullptr, &unsafe_surface) != VK_SUCCESS) {
|
||||||
|
LOG_ERROR(Render_Vulkan, "Failed to initialize Win32 surface");
|
||||||
|
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||||
|
if (window_info.type == Core::Frontend::WindowSystemType::X11) {
|
||||||
|
const VkXlibSurfaceCreateInfoKHR xlib_ci{
|
||||||
|
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, nullptr, 0,
|
||||||
|
static_cast<Display*>(window_info.display_connection),
|
||||||
|
reinterpret_cast<Window>(window_info.render_surface)};
|
||||||
|
const auto vkCreateXlibSurfaceKHR = reinterpret_cast<PFN_vkCreateXlibSurfaceKHR>(
|
||||||
|
dld.vkGetInstanceProcAddr(*instance, "vkCreateXlibSurfaceKHR"));
|
||||||
|
if (!vkCreateXlibSurfaceKHR ||
|
||||||
|
vkCreateXlibSurfaceKHR(*instance, &xlib_ci, nullptr, &unsafe_surface) != VK_SUCCESS) {
|
||||||
|
LOG_ERROR(Render_Vulkan, "Failed to initialize Xlib surface");
|
||||||
|
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (window_info.type == Core::Frontend::WindowSystemType::Wayland) {
|
||||||
|
const VkWaylandSurfaceCreateInfoKHR wayland_ci{
|
||||||
|
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR, nullptr, 0,
|
||||||
|
static_cast<wl_display*>(window_info.display_connection),
|
||||||
|
static_cast<wl_surface*>(window_info.render_surface)};
|
||||||
|
const auto vkCreateWaylandSurfaceKHR = reinterpret_cast<PFN_vkCreateWaylandSurfaceKHR>(
|
||||||
|
dld.vkGetInstanceProcAddr(*instance, "vkCreateWaylandSurfaceKHR"));
|
||||||
|
if (!vkCreateWaylandSurfaceKHR ||
|
||||||
|
vkCreateWaylandSurfaceKHR(*instance, &wayland_ci, nullptr, &unsafe_surface) !=
|
||||||
|
VK_SUCCESS) {
|
||||||
|
LOG_ERROR(Render_Vulkan, "Failed to initialize Wayland surface");
|
||||||
|
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!unsafe_surface) {
|
||||||
|
LOG_ERROR(Render_Vulkan, "Presentation not supported on this platform");
|
||||||
|
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
|
||||||
|
}
|
||||||
|
return vk::SurfaceKHR(unsafe_surface, *instance, dld);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Vulkan
|
18
src/video_core/vulkan_common/vulkan_surface.h
Normal file
18
src/video_core/vulkan_common/vulkan_surface.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2020 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||||
|
|
||||||
|
namespace Core::Frontend {
|
||||||
|
class EmuWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Vulkan {
|
||||||
|
|
||||||
|
[[nodiscard]] vk::SurfaceKHR CreateSurface(const vk::Instance& instance,
|
||||||
|
const Core::Frontend::EmuWindow& emu_window);
|
||||||
|
|
||||||
|
} // namespace Vulkan
|
|
@ -586,6 +586,11 @@ public:
|
||||||
/// @throw Exception on creation failure.
|
/// @throw Exception on creation failure.
|
||||||
DebugUtilsMessenger CreateDebugUtilsMessenger(
|
DebugUtilsMessenger CreateDebugUtilsMessenger(
|
||||||
const VkDebugUtilsMessengerCreateInfoEXT& create_info) const;
|
const VkDebugUtilsMessengerCreateInfoEXT& create_info) const;
|
||||||
|
|
||||||
|
/// Returns dispatch table.
|
||||||
|
const InstanceDispatch& Dispatch() const noexcept {
|
||||||
|
return *dld;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Queue {
|
class Queue {
|
||||||
|
|
Loading…
Reference in a new issue