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:
parent
70225e92f7
commit
d735f5c458
18 changed files with 1576 additions and 54 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue