renderer_vulkan: Add vulkan initialization code (#6620)

* common: Move dynamic library to common

* This is so that video_core can use it

* logging: Add vulkan log target

* common: Allow defered library loading

* Also add some comments to the functions

* renderer_vulkan: Add vulkan initialization code

* renderer_vulkan: Address feedback
This commit is contained in:
GPUCode 2023-06-20 15:24:24 +03:00 committed by GitHub
parent 70225e92f7
commit d735f5c458
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 1576 additions and 54 deletions

View file

@ -10,29 +10,11 @@
#endif
#include "dynamic_library.h"
namespace DynamicLibrary {
namespace Common {
DynamicLibrary::DynamicLibrary(std::string_view name, int major, int minor) {
auto full_name = GetLibraryName(name, major, minor);
#if defined(_WIN32)
handle = reinterpret_cast<void*>(LoadLibraryA(full_name.c_str()));
if (!handle) {
DWORD error_message_id = GetLastError();
LPSTR message_buffer = nullptr;
size_t size =
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, error_message_id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPSTR>(&message_buffer), 0, nullptr);
std::string message(message_buffer, size);
load_error = message;
}
#else
handle = dlopen(full_name.c_str(), RTLD_LAZY);
if (!handle) {
load_error = dlerror();
}
#endif // defined(_WIN32)
void(Load(full_name));
}
DynamicLibrary::~DynamicLibrary() {
@ -46,7 +28,32 @@ DynamicLibrary::~DynamicLibrary() {
}
}
void* DynamicLibrary::GetRawSymbol(std::string_view name) {
bool DynamicLibrary::Load(std::string_view filename) {
#if defined(_WIN32)
handle = reinterpret_cast<void*>(LoadLibraryA(filename.data()));
if (!handle) {
DWORD error_message_id = GetLastError();
LPSTR message_buffer = nullptr;
size_t size =
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, error_message_id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<LPSTR>(&message_buffer), 0, nullptr);
std::string message(message_buffer, size);
load_error = message;
return false;
}
#else
handle = dlopen(filename.data(), RTLD_LAZY);
if (!handle) {
load_error = dlerror();
return false;
}
#endif // defined(_WIN32)
return true;
}
void* DynamicLibrary::GetRawSymbol(std::string_view name) const {
#if defined(_WIN32)
return reinterpret_cast<void*>(GetProcAddress(reinterpret_cast<HMODULE>(handle), name.data()));
#else
@ -84,4 +91,4 @@ std::string DynamicLibrary::GetLibraryName(std::string_view name, int major, int
#endif
}
} // namespace DynamicLibrary
} // namespace Common

View file

@ -5,35 +5,46 @@
#pragma once
#include <string>
#include "common/common_types.h"
namespace DynamicLibrary {
namespace Common {
class DynamicLibrary {
public:
explicit DynamicLibrary();
explicit DynamicLibrary(std::string_view name, int major = -1, int minor = -1);
~DynamicLibrary();
bool IsLoaded() {
/// Returns true if the library is loaded, otherwise false.
[[nodiscard]] bool IsLoaded() {
return handle != nullptr;
}
std::string_view GetLoadError() {
/// Loads (or replaces) the handle with the specified library file name.
/// Returns true if the library was loaded and can be used.
[[nodiscard]] bool Load(std::string_view filename);
/// Returns a string containing the last generated load error, if it occured.
[[nodiscard]] std::string_view GetLoadError() const {
return load_error;
}
/// Obtains the address of the specified symbol, automatically casting to the correct type.
template <typename T>
T GetSymbol(std::string_view name) {
[[nodiscard]] T GetSymbol(std::string_view name) const {
return reinterpret_cast<T>(GetRawSymbol(name));
}
static std::string GetLibraryName(std::string_view name, int major = -1, int minor = -1);
/// Returns the specified library name in platform-specific format.
/// Major/minor versions will not be included if set to -1.
/// If libname already contains the "lib" prefix, it will not be added again.
[[nodiscard]] static std::string GetLibraryName(std::string_view name, int major = -1,
int minor = -1);
private:
void* GetRawSymbol(std::string_view name);
void* GetRawSymbol(std::string_view name) const;
void* handle;
std::string load_error;
};
} // namespace DynamicLibrary
} // namespace Common

View file

@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/dynamic_library/dynamic_library.h"
#include "common/dynamic_library/fdk-aac.h"
#include "common/logging/log.h"
@ -15,7 +16,7 @@ aacDecoder_GetStreamInfo_func aacDecoder_GetStreamInfo;
aacDecoder_DecodeFrame_func aacDecoder_DecodeFrame;
aacDecoder_Fill_func aacDecoder_Fill;
static std::unique_ptr<DynamicLibrary> fdk_aac;
static std::unique_ptr<Common::DynamicLibrary> fdk_aac;
#define LOAD_SYMBOL(library, name) \
any_failed = any_failed || (name = library->GetSymbol<name##_func>(#name)) == nullptr
@ -25,7 +26,7 @@ bool LoadFdkAac() {
return true;
}
fdk_aac = std::make_unique<DynamicLibrary>("fdk-aac", 2);
fdk_aac = std::make_unique<Common::DynamicLibrary>("fdk-aac", 2);
if (!fdk_aac->IsLoaded()) {
LOG_WARNING(Common, "Could not dynamically load libfdk-aac: {}", fdk_aac->GetLoadError());
fdk_aac.reset();

View file

@ -8,9 +8,6 @@ extern "C" {
#include <fdk-aac/aacdecoder_lib.h>
}
#include "common/common_types.h"
#include "common/dynamic_library/dynamic_library.h"
namespace DynamicLibrary::FdkAac {
typedef INT (*aacDecoder_GetLibInfo_func)(LIB_INFO* info);

View file

@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/dynamic_library/dynamic_library.h"
#include "common/dynamic_library/ffmpeg.h"
#include "common/logging/log.h"
@ -110,11 +111,11 @@ swr_free_func swr_free;
swr_init_func swr_init;
swresample_version_func swresample_version;
static std::unique_ptr<DynamicLibrary> avutil;
static std::unique_ptr<DynamicLibrary> avcodec;
static std::unique_ptr<DynamicLibrary> avfilter;
static std::unique_ptr<DynamicLibrary> avformat;
static std::unique_ptr<DynamicLibrary> swresample;
static std::unique_ptr<Common::DynamicLibrary> avutil;
static std::unique_ptr<Common::DynamicLibrary> avcodec;
static std::unique_ptr<Common::DynamicLibrary> avfilter;
static std::unique_ptr<Common::DynamicLibrary> avformat;
static std::unique_ptr<Common::DynamicLibrary> swresample;
#define LOAD_SYMBOL(library, name) \
any_failed = any_failed || (name = library->GetSymbol<name##_func>(#name)) == nullptr
@ -124,7 +125,7 @@ static bool LoadAVUtil() {
return true;
}
avutil = std::make_unique<DynamicLibrary>("avutil", LIBAVUTIL_VERSION_MAJOR);
avutil = std::make_unique<Common::DynamicLibrary>("avutil", LIBAVUTIL_VERSION_MAJOR);
if (!avutil->IsLoaded()) {
LOG_WARNING(Common, "Could not dynamically load libavutil: {}", avutil->GetLoadError());
avutil.reset();
@ -194,7 +195,7 @@ static bool LoadAVCodec() {
return true;
}
avcodec = std::make_unique<DynamicLibrary>("avcodec", LIBAVCODEC_VERSION_MAJOR);
avcodec = std::make_unique<Common::DynamicLibrary>("avcodec", LIBAVCODEC_VERSION_MAJOR);
if (!avcodec->IsLoaded()) {
LOG_WARNING(Common, "Could not dynamically load libavcodec: {}", avcodec->GetLoadError());
avcodec.reset();
@ -251,7 +252,7 @@ static bool LoadAVFilter() {
return true;
}
avfilter = std::make_unique<DynamicLibrary>("avfilter", LIBAVFILTER_VERSION_MAJOR);
avfilter = std::make_unique<Common::DynamicLibrary>("avfilter", LIBAVFILTER_VERSION_MAJOR);
if (!avfilter->IsLoaded()) {
LOG_WARNING(Common, "Could not dynamically load libavfilter: {}", avfilter->GetLoadError());
avfilter.reset();
@ -296,7 +297,7 @@ static bool LoadAVFormat() {
return true;
}
avformat = std::make_unique<DynamicLibrary>("avformat", LIBAVFORMAT_VERSION_MAJOR);
avformat = std::make_unique<Common::DynamicLibrary>("avformat", LIBAVFORMAT_VERSION_MAJOR);
if (!avformat->IsLoaded()) {
LOG_WARNING(Common, "Could not dynamically load libavformat: {}", avformat->GetLoadError());
avformat.reset();
@ -344,7 +345,8 @@ static bool LoadSWResample() {
return true;
}
swresample = std::make_unique<DynamicLibrary>("swresample", LIBSWRESAMPLE_VERSION_MAJOR);
swresample =
std::make_unique<Common::DynamicLibrary>("swresample", LIBSWRESAMPLE_VERSION_MAJOR);
if (!swresample->IsLoaded()) {
LOG_WARNING(Common, "Could not dynamically load libswresample: {}",
swresample->GetLoadError());

View file

@ -15,9 +15,6 @@ extern "C" {
#include <libswresample/swresample.h>
}
#include "common/common_types.h"
#include "common/dynamic_library/dynamic_library.h"
namespace DynamicLibrary::FFmpeg {
// avutil

View file

@ -234,6 +234,7 @@ void DebuggerBackend::Write(const Entry& entry) {
CLS(Render) \
SUB(Render, Software) \
SUB(Render, OpenGL) \
SUB(Render, Vulkan) \
CLS(Audio) \
SUB(Audio, DSP) \
SUB(Audio, Sink) \

View file

@ -8,6 +8,7 @@
#include <array>
#include "common/common_types.h"
#include "common/logging/formatter.h"
namespace Log {
// trims up to and including the last of ../, ..\, src/, src\ in a string
@ -103,6 +104,7 @@ enum class Class : ClassType {
Render, ///< Emulator video output and hardware acceleration
Render_Software, ///< Software renderer backend
Render_OpenGL, ///< OpenGL backend
Render_Vulkan, ///< Vulkan backend
Audio, ///< Audio emulation
Audio_DSP, ///< The HLE and LLE implementations of the DSP
Audio_Sink, ///< Emulator audio output backend

View file

@ -432,6 +432,7 @@ struct Values {
"graphics_api"};
Setting<bool> use_gles{false, "use_gles"};
Setting<bool> renderer_debug{false, "renderer_debug"};
Setting<bool> dump_command_buffers{false, "dump_command_buffers"};
SwitchableSetting<bool> use_hw_shader{true, "use_hw_shader"};
SwitchableSetting<bool> use_disk_shader_cache{true, "use_disk_shader_cache"};
SwitchableSetting<bool> shaders_accurate_mul{true, "shaders_accurate_mul"};