summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Common/CommonPaths.h7
-rw-r--r--Source/Core/Common/DynamicLibrary.cpp11
-rw-r--r--Source/Core/Common/DynamicLibrary.h4
-rw-r--r--Source/Core/Common/FileUtil.cpp30
-rw-r--r--Source/Core/Common/FileUtil.h6
-rw-r--r--Source/Core/Core/Config/GraphicsSettings.cpp3
-rw-r--r--Source/Core/Core/Config/GraphicsSettings.h4
-rw-r--r--Source/Core/VideoBackends/Vulkan/CMakeLists.txt8
-rw-r--r--Source/Core/VideoBackends/Vulkan/VulkanContext.cpp11
-rw-r--r--Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp62
-rw-r--r--Source/Core/VideoBackends/Vulkan/VulkanLoader.h10
-rw-r--r--Source/Core/VideoCommon/VideoConfig.cpp2
-rw-r--r--Source/Core/VideoCommon/VideoConfig.h3
13 files changed, 154 insertions, 7 deletions
diff --git a/Source/Core/Common/CommonPaths.h b/Source/Core/Common/CommonPaths.h
index b22033a5cd..44ada6dd19 100644
--- a/Source/Core/Common/CommonPaths.h
+++ b/Source/Core/Common/CommonPaths.h
@@ -163,3 +163,10 @@
// Subdirs in Config
#define GRAPHICSMOD_CONFIG_DIR "GraphicMods"
+
+// GPU drivers
+#define GPU_DRIVERS "GpuDrivers"
+#define GPU_DRIVERS_EXTRACTED "Extracted"
+#define GPU_DRIVERS_TMP "Tmp"
+#define GPU_DRIVERS_HOOK "Hook"
+#define GPU_DRIVERS_FILE_REDIRECT "FileRedirect"
diff --git a/Source/Core/Common/DynamicLibrary.cpp b/Source/Core/Common/DynamicLibrary.cpp
index 039b0a034c..7871198dda 100644
--- a/Source/Core/Common/DynamicLibrary.cpp
+++ b/Source/Core/Common/DynamicLibrary.cpp
@@ -24,11 +24,22 @@ DynamicLibrary::DynamicLibrary(const char* filename)
Open(filename);
}
+DynamicLibrary::DynamicLibrary(void* handle)
+{
+ m_handle = handle;
+}
+
DynamicLibrary::~DynamicLibrary()
{
Close();
}
+DynamicLibrary& DynamicLibrary::operator=(void* handle)
+{
+ m_handle = handle;
+ return *this;
+}
+
std::string DynamicLibrary::GetUnprefixedFilename(const char* filename)
{
#if defined(_WIN32)
diff --git a/Source/Core/Common/DynamicLibrary.h b/Source/Core/Common/DynamicLibrary.h
index edfcde8ff3..29cafbafb2 100644
--- a/Source/Core/Common/DynamicLibrary.h
+++ b/Source/Core/Common/DynamicLibrary.h
@@ -21,6 +21,8 @@ public:
// Automatically loads the specified library. Call IsOpen() to check validity before use.
DynamicLibrary(const char* filename);
+ DynamicLibrary(void* handle);
+
// Closes the library.
~DynamicLibrary();
@@ -30,6 +32,8 @@ public:
DynamicLibrary& operator=(const DynamicLibrary&) = delete;
DynamicLibrary& operator=(DynamicLibrary&&) = delete;
+ DynamicLibrary& operator=(void*);
+
// Returns the specified library name with the platform-specific suffix added.
static std::string GetUnprefixedFilename(const char* filename);
diff --git a/Source/Core/Common/FileUtil.cpp b/Source/Core/Common/FileUtil.cpp
index 9a494ab2e0..f5842c14f9 100644
--- a/Source/Core/Common/FileUtil.cpp
+++ b/Source/Core/Common/FileUtil.cpp
@@ -66,6 +66,8 @@ namespace File
{
#ifdef ANDROID
static std::string s_android_sys_directory;
+static std::string s_android_driver_directory;
+static std::string s_android_lib_directory;
#endif
#ifdef __APPLE__
@@ -796,6 +798,34 @@ void SetSysDirectory(const std::string& path)
s_android_sys_directory);
s_android_sys_directory = path;
}
+
+void SetGpuDriverDirectories(const std::string& path, const std::string& lib_path)
+{
+ INFO_LOG_FMT(COMMON, "Setting Driver directory to {} and library path to {}", path, lib_path);
+ ASSERT_MSG(COMMON, s_android_driver_directory.empty(), "Driver directory already set to {}",
+ s_android_driver_directory);
+ ASSERT_MSG(COMMON, s_android_lib_directory.empty(), "Library directory already set to {}",
+ s_android_lib_directory);
+ s_android_driver_directory = path;
+ s_android_lib_directory = lib_path;
+}
+
+const std::string GetGpuDriverDirectory(unsigned int dir_index)
+{
+ switch (dir_index)
+ {
+ case D_GPU_DRIVERS_EXTRACTED:
+ return s_android_driver_directory + DIR_SEP GPU_DRIVERS_EXTRACTED DIR_SEP;
+ case D_GPU_DRIVERS_TMP:
+ return s_android_driver_directory + DIR_SEP GPU_DRIVERS_TMP DIR_SEP;
+ case D_GPU_DRIVERS_HOOKS:
+ return s_android_lib_directory;
+ case D_GPU_DRIVERS_FILE_REDIRECT:
+ return s_android_driver_directory + DIR_SEP GPU_DRIVERS_FILE_REDIRECT DIR_SEP;
+ }
+ return "";
+}
+
#endif
static std::string s_user_paths[NUM_PATH_INDICES];
diff --git a/Source/Core/Common/FileUtil.h b/Source/Core/Common/FileUtil.h
index 2a2e112039..8d5f312d65 100644
--- a/Source/Core/Common/FileUtil.h
+++ b/Source/Core/Common/FileUtil.h
@@ -67,6 +67,10 @@ enum
D_GBAUSER_IDX,
D_GBASAVES_IDX,
D_WIISDCARDSYNCFOLDER_IDX,
+ D_GPU_DRIVERS_EXTRACTED,
+ D_GPU_DRIVERS_TMP,
+ D_GPU_DRIVERS_HOOKS,
+ D_GPU_DRIVERS_FILE_REDIRECT,
FIRST_FILE_USER_PATH_IDX,
F_DOLPHINCONFIG_IDX = FIRST_FILE_USER_PATH_IDX,
F_GCPADCONFIG_IDX,
@@ -228,6 +232,8 @@ const std::string& GetSysDirectory();
#ifdef ANDROID
void SetSysDirectory(const std::string& path);
+void SetGpuDriverDirectories(const std::string& path, const std::string& lib_path);
+const std::string GetGpuDriverDirectory(unsigned int dir_index);
#endif
#ifdef __APPLE__
diff --git a/Source/Core/Core/Config/GraphicsSettings.cpp b/Source/Core/Core/Config/GraphicsSettings.cpp
index ff621b48c2..f4c16b286c 100644
--- a/Source/Core/Core/Config/GraphicsSettings.cpp
+++ b/Source/Core/Core/Config/GraphicsSettings.cpp
@@ -111,6 +111,8 @@ const Info<bool> GFX_PREFER_GLES{{System::GFX, "Settings", "PreferGLES"}, false}
const Info<bool> GFX_MODS_ENABLE{{System::GFX, "Settings", "EnableMods"}, false};
+const Info<std::string> GFX_DRIVER_LIB_NAME{{System::GFX, "Settings", "DriverLibName"}, ""};
+
// Graphics.Enhancements
const Info<TextureFilteringMode> GFX_ENHANCE_FORCE_TEXTURE_FILTERING{
@@ -171,4 +173,5 @@ const Info<bool> GFX_HACK_NO_MIPMAPPING{{System::GFX, "Hacks", "NoMipmapping"},
// Graphics.GameSpecific
const Info<bool> GFX_PERF_QUERIES_ENABLE{{System::GFX, "GameSpecific", "PerfQueriesEnable"}, false};
+
} // namespace Config
diff --git a/Source/Core/Core/Config/GraphicsSettings.h b/Source/Core/Core/Config/GraphicsSettings.h
index ce10005da9..f45d0c4811 100644
--- a/Source/Core/Core/Config/GraphicsSettings.h
+++ b/Source/Core/Core/Config/GraphicsSettings.h
@@ -148,4 +148,8 @@ extern const Info<bool> GFX_HACK_NO_MIPMAPPING;
extern const Info<bool> GFX_PERF_QUERIES_ENABLE;
+// Android custom GPU drivers
+
+extern const Info<std::string> GFX_DRIVER_LIB_NAME;
+
} // namespace Config
diff --git a/Source/Core/VideoBackends/Vulkan/CMakeLists.txt b/Source/Core/VideoBackends/Vulkan/CMakeLists.txt
index 7abf9a038b..ec9e1b51cb 100644
--- a/Source/Core/VideoBackends/Vulkan/CMakeLists.txt
+++ b/Source/Core/VideoBackends/Vulkan/CMakeLists.txt
@@ -48,11 +48,19 @@ PRIVATE
xxhash
)
+if (ANDROID AND _M_ARM_64)
+ target_link_libraries(videovulkan
+ PRIVATE
+ adrenotools
+ )
+endif()
+
# Only include the Vulkan headers when building the Vulkan backend
target_include_directories(videovulkan
PRIVATE
${CMAKE_SOURCE_DIR}/Externals/Vulkan/Include
${CMAKE_SOURCE_DIR}/Externals/VulkanMemoryAllocator/include
+ ${CMAKE_SOURCE_DIR}/Externals/libadrenotools/include
)
if(MSVC)
diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp
index 5b5f2ffaee..ed4d749878 100644
--- a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp
@@ -143,7 +143,18 @@ VkInstance VulkanContext::CreateVulkanInstance(WindowSystemType wstype, bool ena
{
// The device itself may not support 1.1, so we check that before using any 1.1 functionality.
app_info.apiVersion = VK_MAKE_VERSION(1, 1, 0);
+ WARN_LOG_FMT(HOST_GPU, "Using Vulkan 1.1, supported: {}.{}",
+ VK_VERSION_MAJOR(supported_api_version),
+ VK_VERSION_MINOR(supported_api_version));
}
+ else
+ {
+ WARN_LOG_FMT(HOST_GPU, "Using Vulkan 1.0");
+ }
+ }
+ else
+ {
+ WARN_LOG_FMT(HOST_GPU, "Using Vulkan 1.0");
}
*out_vk_api_version = app_info.apiVersion;
diff --git a/Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp b/Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp
index 9b62244dfd..34c531fc2f 100644
--- a/Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp
@@ -8,11 +8,18 @@
#include <cstdarg>
#include <cstdlib>
+#if defined(ANDROID)
+#include <adrenotools/driver.h>
+#include <dlfcn.h>
+#endif
+
#include "Common/CommonFuncs.h"
#include "Common/DynamicLibrary.h"
#include "Common/FileUtil.h"
#include "Common/StringUtil.h"
+#include "VideoCommon/VideoConfig.h"
+
#define VULKAN_MODULE_ENTRY_POINT(name, required) PFN_##name name;
#define VULKAN_INSTANCE_ENTRY_POINT(name, required) PFN_##name name;
#define VULKAN_DEVICE_ENTRY_POINT(name, required) PFN_##name name;
@@ -36,9 +43,9 @@ static void ResetVulkanLibraryFunctionPointers()
static Common::DynamicLibrary s_vulkan_module;
-static bool OpenVulkanLibrary()
+static bool OpenVulkanLibrary(bool force_system_library)
{
-#ifdef __APPLE__
+#if defined(__APPLE__)
// Check if a path to a specific Vulkan library has been specified.
char* libvulkan_env = getenv("LIBVULKAN_PATH");
if (libvulkan_env && s_vulkan_module.Open(libvulkan_env))
@@ -48,6 +55,35 @@ static bool OpenVulkanLibrary()
std::string filename = File::GetBundleDirectory() + "/Contents/Frameworks/libMoltenVK.dylib";
return s_vulkan_module.Open(filename.c_str());
#else
+
+#if defined(ANDROID) && _M_ARM_64
+ const std::string& driver_lib_name = g_Config.customDriverLibraryName;
+
+ if (!force_system_library && !driver_lib_name.empty() && SupportsCustomDriver())
+ {
+ std::string tmp_dir = File::GetGpuDriverDirectory(D_GPU_DRIVERS_TMP);
+ std::string hook_dir = File::GetGpuDriverDirectory(D_GPU_DRIVERS_HOOKS);
+ std::string file_redirect_dir = File::GetGpuDriverDirectory(D_GPU_DRIVERS_FILE_REDIRECT);
+ std::string driver_dir = File::GetGpuDriverDirectory(D_GPU_DRIVERS_EXTRACTED);
+ INFO_LOG_FMT(HOST_GPU, "Loading driver: {}", driver_lib_name);
+
+ s_vulkan_module = adrenotools_open_libvulkan(
+ RTLD_NOW, ADRENOTOOLS_DRIVER_FILE_REDIRECT | ADRENOTOOLS_DRIVER_CUSTOM, tmp_dir.c_str(),
+ hook_dir.c_str(), driver_dir.c_str(), driver_lib_name.c_str(), file_redirect_dir.c_str(),
+ nullptr);
+ if (s_vulkan_module.IsOpen())
+ {
+ INFO_LOG_FMT(HOST_GPU, "Successfully loaded driver: {}", driver_lib_name);
+ return true;
+ }
+ else
+ {
+ WARN_LOG_FMT(HOST_GPU, "Loading driver {} failed.", driver_lib_name);
+ }
+ }
+#endif
+
+ WARN_LOG_FMT(HOST_GPU, "Loading system driver");
std::string filename = Common::DynamicLibrary::GetVersionedFilename("vulkan", 1);
if (s_vulkan_module.Open(filename.c_str()))
return true;
@@ -58,9 +94,9 @@ static bool OpenVulkanLibrary()
#endif
}
-bool LoadVulkanLibrary()
+bool LoadVulkanLibrary(bool force_system_library)
{
- if (!s_vulkan_module.IsOpen() && !OpenVulkanLibrary())
+ if (!s_vulkan_module.IsOpen() && !OpenVulkanLibrary(force_system_library))
return false;
#define VULKAN_MODULE_ENTRY_POINT(name, required) \
@@ -91,7 +127,7 @@ bool LoadVulkanInstanceFunctions(VkInstance instance)
*func_ptr = vkGetInstanceProcAddr(instance, name);
if (!(*func_ptr) && is_required)
{
- ERROR_LOG_FMT(VIDEO, "Vulkan: Failed to load required instance function {}", name);
+ ERROR_LOG_FMT(HOST_GPU, "Vulkan: Failed to load required instance function {}", name);
required_functions_missing = true;
}
};
@@ -111,7 +147,7 @@ bool LoadVulkanDeviceFunctions(VkDevice device)
*func_ptr = vkGetDeviceProcAddr(device, name);
if (!(*func_ptr) && is_required)
{
- ERROR_LOG_FMT(VIDEO, "Vulkan: Failed to load required device function {}", name);
+ ERROR_LOG_FMT(HOST_GPU, "Vulkan: Failed to load required device function {}", name);
required_functions_missing = true;
}
};
@@ -212,4 +248,18 @@ void LogVulkanResult(Common::Log::LogLevel level, const char* func_name, VkResul
static_cast<int>(res), VkResultToString(res));
}
+#ifdef ANDROID
+static bool CheckKgslPresent()
+{
+ constexpr auto KgslPath{"/dev/kgsl-3d0"};
+
+ return access(KgslPath, F_OK) == 0;
+}
+
+bool SupportsCustomDriver()
+{
+ return android_get_device_api_level() >= 28 && CheckKgslPresent();
+}
+#endif
+
} // namespace Vulkan
diff --git a/Source/Core/VideoBackends/Vulkan/VulkanLoader.h b/Source/Core/VideoBackends/Vulkan/VulkanLoader.h
index 652b512dd4..d1a426d952 100644
--- a/Source/Core/VideoBackends/Vulkan/VulkanLoader.h
+++ b/Source/Core/VideoBackends/Vulkan/VulkanLoader.h
@@ -23,6 +23,10 @@
#include "vulkan/vulkan.h"
+#ifdef ANDROID
+#include <unistd.h>
+#endif
+
// Currently, exclusive fullscreen is only supported on Windows.
#if defined(WIN32)
#define SUPPORTS_VULKAN_EXCLUSIVE_FULLSCREEN 1
@@ -78,11 +82,15 @@
namespace Vulkan
{
-bool LoadVulkanLibrary();
+bool LoadVulkanLibrary(bool force_system_library = false);
bool LoadVulkanInstanceFunctions(VkInstance instance);
bool LoadVulkanDeviceFunctions(VkDevice device);
void UnloadVulkanLibrary();
+#ifdef ANDROID
+bool SupportsCustomDriver();
+#endif
+
const char* VkResultToString(VkResult res);
void LogVulkanResult(Common::Log::LogLevel level, const char* func_name, VkResult res,
const char* msg);
diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp
index 38ee680bf3..9284c8171f 100644
--- a/Source/Core/VideoCommon/VideoConfig.cpp
+++ b/Source/Core/VideoCommon/VideoConfig.cpp
@@ -172,6 +172,8 @@ void VideoConfig::Refresh()
bPerfQueriesEnable = Config::Get(Config::GFX_PERF_QUERIES_ENABLE);
bGraphicMods = Config::Get(Config::GFX_MODS_ENABLE);
+
+ customDriverLibraryName = Config::Get(Config::GFX_DRIVER_LIB_NAME);
}
void VideoConfig::VerifyValidity()
diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h
index a479276e6c..33f2a06ebe 100644
--- a/Source/Core/VideoCommon/VideoConfig.h
+++ b/Source/Core/VideoCommon/VideoConfig.h
@@ -214,6 +214,9 @@ struct VideoConfig final
int iShaderCompilerThreads = 0;
int iShaderPrecompilerThreads = 0;
+ // Loading custom drivers on Android
+ std::string customDriverLibraryName;
+
// Static config per API
// TODO: Move this out of VideoConfig
struct