summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp')
-rw-r--r--Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp62
1 files changed, 56 insertions, 6 deletions
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