Fixes Dawn to use custom Vulkan loader on Linux systems.

- Adds system utility to get the module directory for dawn native.
- Updates Vulkan backend to use the module directory to find loader.
- Test ran on NVIDIA GTX 1660 here: https://chromium-swarm.appspot.com/task?id=576d77991add7c10.

Bug: dawn:1191
Change-Id: I7c577008b5252ac94f38c8cdb56f7e8d8a0aa956
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/70860
Commit-Queue: Loko Kung <lokokung@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Loko Kung 2021-11-29 18:18:58 +00:00 committed by Dawn LUCI CQ
parent 11ee0d24f5
commit 349062fb72
6 changed files with 65 additions and 9 deletions

View File

@ -15,8 +15,8 @@
import("//build_overrides/build.gni")
if (build_with_chromium) {
import("//build/config/sanitizers/sanitizers.gni")
import("//build/config/ozone.gni")
import("//build/config/sanitizers/sanitizers.gni")
dawn_use_x11 = ozone_platform_x11
} else {
@ -97,7 +97,8 @@ declare_args() {
# Uses our built version of the Vulkan loader on platforms where we can't
# assume to have one present at the system level.
dawn_enable_vulkan_loader = dawn_enable_vulkan && is_mac
dawn_enable_vulkan_loader =
dawn_enable_vulkan && (is_mac || (is_linux && !is_android))
}
# UWP only supports CoreWindow for windowing

View File

@ -63,8 +63,7 @@ if (!defined(dawn_swiftshader_dir)) {
}
if (!defined(dawn_vulkan_loader_dir)) {
# Default to the Vulkan loader not being available.
dawn_vulkan_loader_dir = ""
dawn_vulkan_loader_dir = "//third_party/vulkan-deps/vulkan-loader/src"
}
if (!defined(dawn_vulkan_validation_layers_dir)) {

View File

@ -21,10 +21,12 @@
# include <Windows.h>
# include <vector>
#elif defined(DAWN_PLATFORM_LINUX)
# include <dlfcn.h>
# include <limits.h>
# include <unistd.h>
# include <cstdlib>
#elif defined(DAWN_PLATFORM_MACOS) || defined(DAWN_PLATFORM_IOS)
# include <dlfcn.h>
# include <mach-o/dyld.h>
# include <vector>
#endif
@ -136,6 +138,45 @@ std::string GetExecutableDirectory() {
return lastPathSepLoc != std::string::npos ? exePath.substr(0, lastPathSepLoc + 1) : "";
}
#if defined(DAWN_PLATFORM_LINUX) || defined(DAWN_PLATFORM_MACOS) || defined(DAWN_PLATFORM_IOS)
std::string GetModulePath() {
static int placeholderSymbol = 0;
Dl_info dlInfo;
if (dladdr(&placeholderSymbol, &dlInfo) == 0) {
return "";
}
std::array<char, PATH_MAX> absolutePath;
if (realpath(dlInfo.dli_fname, absolutePath.data()) == NULL) {
return "";
}
return absolutePath.data();
}
#elif defined(DAWN_PLATFORM_WINDOWS)
std::string GetModulePath() {
UNREACHABLE();
return "";
}
#elif defined(DAWN_PLATFORM_FUCHSIA)
std::string GetModulePath() {
UNREACHABLE();
return "";
}
#elif defined(DAWN_PLATFORM_EMSCRIPTEN)
std::string GetModulePath() {
UNREACHABLE();
return "";
}
#else
# error "Implement GetModulePath for your platform."
#endif
std::string GetModuleDirectory() {
std::string modPath = GetModulePath();
size_t lastPathSepLoc = modPath.find_last_of(GetPathSeparator());
return lastPathSepLoc != std::string::npos ? modPath.substr(0, lastPathSepLoc + 1) : "";
}
// ScopedEnvironmentVar
ScopedEnvironmentVar::ScopedEnvironmentVar(const char* variableName, const char* value)

View File

@ -24,7 +24,9 @@ const char* GetPathSeparator();
// was present.
std::pair<std::string, bool> GetEnvironmentVar(const char* variableName);
bool SetEnvironmentVar(const char* variableName, const char* value);
// Directories are always returned with a trailing path separator.
std::string GetExecutableDirectory();
std::string GetModuleDirectory();
#ifdef DAWN_PLATFORM_MACOS
void GetMacOSVersion(int32_t* majorVersion, int32_t* minorVersion = nullptr);

View File

@ -679,6 +679,7 @@ source_set("dawn_native_sources") {
}
if (enable_vulkan_loader) {
data_deps += [ "${dawn_vulkan_loader_dir}:libvulkan" ]
defines += [ "DAWN_ENABLE_VULKAN_LOADER" ]
}
if (use_swiftshader) {
data_deps += [

View File

@ -111,13 +111,25 @@ namespace dawn_native { namespace vulkan {
}
MaybeError Backend::LoadVulkan(bool useSwiftshader) {
// First try to load the system Vulkan driver, if that fails,
// try to load with Swiftshader. Note: The system driver could potentially be Swiftshader
// if it was installed.
if (mVulkanLib.Open(kVulkanLibName)) {
// First try to load the system Vulkan driver, if that fails, try to load with Swiftshader.
// Note: The system driver could potentially be Swiftshader if it was installed.
#if defined(DAWN_ENABLE_VULKAN_LOADER)
// If enabled, we use our own built Vulkan loader by specifying an absolute path to the
// shared library. Note that when we are currently getting the absolute path for the custom
// loader by getting the path to the dawn native library and traversing relative from there.
// This has implications for dawn tests because some of them are linking statically to
// dawn_native which means the "module" is actually the test as well. If the directory
// location of the tests change w.r.t the shared lib then this may break. Essentially we are
// assuming that our custom built Vulkan loader will always be in the same directory as the
// shared dawn native library and all test binaries that link statically.
const std::string resolvedVulkanLibPath = GetModuleDirectory() + kVulkanLibName;
#else
const std::string resolvedVulkanLibPath = kVulkanLibName;
#endif // defined(DAWN_ENABLE_VULKAN_LOADER)
if (mVulkanLib.Open(resolvedVulkanLibPath)) {
return {};
}
dawn::WarningLog() << std::string("Couldn't open ") + kVulkanLibName;
dawn::WarningLog() << std::string("Couldn't open ") + resolvedVulkanLibPath;
// If |useSwiftshader == true|, fallback and try to directly load the Swiftshader
// library.