vulkan_common: Move dynamic library load to a separate file

Allows us to initialize a Vulkan dynamic library from different backends
without duplicating code.
This commit is contained in:
ReinUsesLisp 2020-12-24 21:24:34 -03:00
parent 53e49e5360
commit d937421422
4 changed files with 59 additions and 31 deletions

View File

@ -260,6 +260,8 @@ add_library(video_core STATIC
textures/texture.h textures/texture.h
video_core.cpp video_core.cpp
video_core.h video_core.h
vulkan_common/vulkan_library.cpp
vulkan_common/vulkan_library.h
) )
create_target_directory_groups(video_core) create_target_directory_groups(video_core)

View File

@ -12,8 +12,6 @@
#include <fmt/format.h> #include <fmt/format.h>
#include "common/dynamic_library.h"
#include "common/file_util.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/telemetry.h" #include "common/telemetry.h"
#include "core/core.h" #include "core/core.h"
@ -32,6 +30,7 @@
#include "video_core/renderer_vulkan/vk_state_tracker.h" #include "video_core/renderer_vulkan/vk_state_tracker.h"
#include "video_core/renderer_vulkan/vk_swapchain.h" #include "video_core/renderer_vulkan/vk_swapchain.h"
#include "video_core/renderer_vulkan/wrapper.h" #include "video_core/renderer_vulkan/wrapper.h"
#include "video_core/vulkan_common/vulkan_library.h"
// Include these late to avoid polluting previous headers // Include these late to avoid polluting previous headers
#ifdef _WIN32 #ifdef _WIN32
@ -70,31 +69,10 @@ VkBool32 DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
return VK_FALSE; return VK_FALSE;
} }
Common::DynamicLibrary OpenVulkanLibrary() { std::pair<vk::Instance, u32> CreateInstance(
Common::DynamicLibrary library; Common::DynamicLibrary& library, vk::InstanceDispatch& dld,
#ifdef __APPLE__ WindowSystemType window_type = WindowSystemType::Headless, bool enable_debug_utils = false,
// Check if a path to a specific Vulkan library has been specified. bool enable_layers = false) {
char* libvulkan_env = getenv("LIBVULKAN_PATH");
if (!libvulkan_env || !library.Open(libvulkan_env)) {
// Use the libvulkan.dylib from the application bundle.
const std::string filename =
Common::FS::GetBundleDirectory() + "/Contents/Frameworks/libvulkan.dylib";
library.Open(filename.c_str());
}
#else
std::string filename = Common::DynamicLibrary::GetVersionedFilename("vulkan", 1);
if (!library.Open(filename.c_str())) {
// Android devices may not have libvulkan.so.1, only libvulkan.so.
filename = Common::DynamicLibrary::GetVersionedFilename("vulkan");
(void)library.Open(filename.c_str());
}
#endif
return library;
}
std::pair<vk::Instance, u32> CreateInstance(Common::DynamicLibrary& library,
vk::InstanceDispatch& dld, WindowSystemType window_type,
bool enable_debug_utils, bool enable_layers) {
if (!library.IsOpen()) { if (!library.IsOpen()) {
LOG_ERROR(Render_Vulkan, "Vulkan library not available"); LOG_ERROR(Render_Vulkan, "Vulkan library not available");
return {}; return {};
@ -285,7 +263,7 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
} }
bool RendererVulkan::Init() { bool RendererVulkan::Init() {
library = OpenVulkanLibrary(); library = OpenLibrary();
std::tie(instance, instance_version) = CreateInstance( std::tie(instance, instance_version) = CreateInstance(
library, dld, render_window.GetWindowInfo().type, true, Settings::values.renderer_debug); library, dld, render_window.GetWindowInfo().type, true, Settings::values.renderer_debug);
if (!instance || !CreateDebugCallback() || !CreateSurface() || !PickDevices()) { if (!instance || !CreateDebugCallback() || !CreateSurface() || !PickDevices()) {
@ -446,9 +424,8 @@ void RendererVulkan::Report() const {
std::vector<std::string> RendererVulkan::EnumerateDevices() { std::vector<std::string> RendererVulkan::EnumerateDevices() {
vk::InstanceDispatch dld; vk::InstanceDispatch dld;
Common::DynamicLibrary library = OpenVulkanLibrary(); Common::DynamicLibrary library = OpenLibrary();
vk::Instance instance = vk::Instance instance = CreateInstance(library, dld).first;
CreateInstance(library, dld, WindowSystemType::Headless, false, false).first;
if (!instance) { if (!instance) {
return {}; return {};
} }

View File

@ -0,0 +1,36 @@
// Copyright 2020 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <cstdlib>
#include <string>
#include "common/dynamic_library.h"
#include "common/file_util.h"
#include "video_core/vulkan_common/vulkan_library.h"
namespace Vulkan {
Common::DynamicLibrary OpenLibrary() {
Common::DynamicLibrary library;
#ifdef __APPLE__
// Check if a path to a specific Vulkan library has been specified.
char* const libvulkan_env = std::getenv("LIBVULKAN_PATH");
if (!libvulkan_env || !library.Open(libvulkan_env)) {
// Use the libvulkan.dylib from the application bundle.
const std::string filename =
Common::FS::GetBundleDirectory() + "/Contents/Frameworks/libvulkan.dylib";
library.Open(filename.c_str());
}
#else
std::string filename = Common::DynamicLibrary::GetVersionedFilename("vulkan", 1);
if (!library.Open(filename.c_str())) {
// Android devices may not have libvulkan.so.1, only libvulkan.so.
filename = Common::DynamicLibrary::GetVersionedFilename("vulkan");
void(library.Open(filename.c_str()));
}
#endif
return library;
}
} // namespace Vulkan

View File

@ -0,0 +1,13 @@
// Copyright 2020 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "common/dynamic_library.h"
namespace Vulkan {
Common::DynamicLibrary OpenLibrary();
} // namespace Vulkan