Add runtime search paths to Instance descriptor
So that Chrome can configure Dawn to load SwiftShader from the bundled/module directory. The shared libraries and ICD are packaged in a separate directory while dawn::native is linked statically into the Chrome executable. Change the Vulkan backend to use these paths for loading Vulkan. Bug: chromium:1266550 Change-Id: I40468b481881f6c249694c1c61137bc0c9b8fe76 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/78840 Reviewed-by: Loko Kung <lokokung@google.com> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
6806a61a26
commit
2fbc170827
12
dawn.json
12
dawn.json
|
@ -1410,6 +1410,15 @@
|
||||||
"extensible": "in",
|
"extensible": "in",
|
||||||
"members": []
|
"members": []
|
||||||
},
|
},
|
||||||
|
"dawn instance descriptor": {
|
||||||
|
"tags": ["dawn", "native"],
|
||||||
|
"category": "structure",
|
||||||
|
"chained": "in",
|
||||||
|
"members": [
|
||||||
|
{"name": "additional runtime search paths count", "type": "uint32_t", "default": 0},
|
||||||
|
{"name": "additional runtime search paths", "type": "char", "annotation": "const*const*", "length": "additional runtime search paths count"}
|
||||||
|
]
|
||||||
|
},
|
||||||
"vertex attribute": {
|
"vertex attribute": {
|
||||||
"category": "structure",
|
"category": "structure",
|
||||||
"extensible": false,
|
"extensible": false,
|
||||||
|
@ -2378,7 +2387,8 @@
|
||||||
{"value": 1000, "name": "dawn texture internal usage descriptor", "tags": ["dawn"]},
|
{"value": 1000, "name": "dawn texture internal usage descriptor", "tags": ["dawn"]},
|
||||||
{"value": 1001, "name": "primitive depth clamping state", "tags": ["dawn", "emscripten"]},
|
{"value": 1001, "name": "primitive depth clamping state", "tags": ["dawn", "emscripten"]},
|
||||||
{"value": 1002, "name": "dawn toggles device descriptor", "tags": ["dawn", "native"]},
|
{"value": 1002, "name": "dawn toggles device descriptor", "tags": ["dawn", "native"]},
|
||||||
{"value": 1003, "name": "dawn encoder internal usage descriptor", "tags": ["dawn"]}
|
{"value": 1003, "name": "dawn encoder internal usage descriptor", "tags": ["dawn"]},
|
||||||
|
{"value": 1004, "name": "dawn instance descriptor", "tags": ["dawn", "native"]}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"texture": {
|
"texture": {
|
||||||
|
|
|
@ -88,93 +88,119 @@ bool SetEnvironmentVar(const char* variableName, const char* value) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(DAWN_PLATFORM_WINDOWS)
|
#if defined(DAWN_PLATFORM_WINDOWS)
|
||||||
std::string GetExecutablePath() {
|
std::optional<std::string> GetHModulePath(HMODULE module) {
|
||||||
std::array<char, MAX_PATH> executableFileBuf;
|
std::array<char, MAX_PATH> executableFileBuf;
|
||||||
DWORD executablePathLen = GetModuleFileNameA(nullptr, executableFileBuf.data(),
|
DWORD executablePathLen = GetModuleFileNameA(nullptr, executableFileBuf.data(),
|
||||||
static_cast<DWORD>(executableFileBuf.size()));
|
static_cast<DWORD>(executableFileBuf.size()));
|
||||||
return executablePathLen > 0 ? std::string(executableFileBuf.data()) : "";
|
if (executablePathLen == 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return executableFileBuf.data();
|
||||||
|
}
|
||||||
|
std::optional<std::string> GetExecutablePath() {
|
||||||
|
return GetHModulePath(nullptr);
|
||||||
}
|
}
|
||||||
#elif defined(DAWN_PLATFORM_LINUX)
|
#elif defined(DAWN_PLATFORM_LINUX)
|
||||||
std::string GetExecutablePath() {
|
std::optional<std::string> GetExecutablePath() {
|
||||||
std::array<char, PATH_MAX> path;
|
std::array<char, PATH_MAX> path;
|
||||||
ssize_t result = readlink("/proc/self/exe", path.data(), PATH_MAX - 1);
|
ssize_t result = readlink("/proc/self/exe", path.data(), PATH_MAX - 1);
|
||||||
if (result < 0 || static_cast<size_t>(result) >= PATH_MAX - 1) {
|
if (result < 0 || static_cast<size_t>(result) >= PATH_MAX - 1) {
|
||||||
return "";
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
path[result] = '\0';
|
path[result] = '\0';
|
||||||
return path.data();
|
return path.data();
|
||||||
}
|
}
|
||||||
#elif defined(DAWN_PLATFORM_MACOS) || defined(DAWN_PLATFORM_IOS)
|
#elif defined(DAWN_PLATFORM_MACOS) || defined(DAWN_PLATFORM_IOS)
|
||||||
std::string GetExecutablePath() {
|
std::optional<std::string> GetExecutablePath() {
|
||||||
uint32_t size = 0;
|
uint32_t size = 0;
|
||||||
_NSGetExecutablePath(nullptr, &size);
|
_NSGetExecutablePath(nullptr, &size);
|
||||||
|
|
||||||
std::vector<char> buffer(size + 1);
|
std::vector<char> buffer(size + 1);
|
||||||
if (_NSGetExecutablePath(buffer.data(), &size) != 0) {
|
if (_NSGetExecutablePath(buffer.data(), &size) != 0) {
|
||||||
return "";
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer[size] = '\0';
|
buffer[size] = '\0';
|
||||||
return buffer.data();
|
return buffer.data();
|
||||||
}
|
}
|
||||||
#elif defined(DAWN_PLATFORM_FUCHSIA)
|
#elif defined(DAWN_PLATFORM_FUCHSIA)
|
||||||
std::string GetExecutablePath() {
|
std::optional<std::string> GetExecutablePath() {
|
||||||
// TODO: Implement on Fuchsia
|
// TODO: Implement on Fuchsia
|
||||||
return "";
|
return {};
|
||||||
}
|
}
|
||||||
#elif defined(DAWN_PLATFORM_EMSCRIPTEN)
|
#elif defined(DAWN_PLATFORM_EMSCRIPTEN)
|
||||||
std::string GetExecutablePath() {
|
std::optional<std::string> GetExecutablePath() {
|
||||||
UNREACHABLE();
|
return {};
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# error "Implement GetExecutablePath for your platform."
|
# error "Implement GetExecutablePath for your platform."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string GetExecutableDirectory() {
|
std::optional<std::string> GetExecutableDirectory() {
|
||||||
std::string exePath = GetExecutablePath();
|
std::optional<std::string> exePath = GetExecutablePath();
|
||||||
size_t lastPathSepLoc = exePath.find_last_of(GetPathSeparator());
|
if (!exePath) {
|
||||||
return lastPathSepLoc != std::string::npos ? exePath.substr(0, lastPathSepLoc + 1) : "";
|
return {};
|
||||||
|
}
|
||||||
|
size_t lastPathSepLoc = exePath->find_last_of(GetPathSeparator());
|
||||||
|
if (lastPathSepLoc == std::string::npos) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return exePath->substr(0, lastPathSepLoc + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DAWN_PLATFORM_LINUX) || defined(DAWN_PLATFORM_MACOS) || defined(DAWN_PLATFORM_IOS)
|
#if defined(DAWN_PLATFORM_LINUX) || defined(DAWN_PLATFORM_MACOS) || defined(DAWN_PLATFORM_IOS)
|
||||||
std::string GetModulePath() {
|
std::optional<std::string> GetModulePath() {
|
||||||
static int placeholderSymbol = 0;
|
static int placeholderSymbol = 0;
|
||||||
Dl_info dlInfo;
|
Dl_info dlInfo;
|
||||||
if (dladdr(&placeholderSymbol, &dlInfo) == 0) {
|
if (dladdr(&placeholderSymbol, &dlInfo) == 0) {
|
||||||
return "";
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<char, PATH_MAX> absolutePath;
|
std::array<char, PATH_MAX> absolutePath;
|
||||||
if (realpath(dlInfo.dli_fname, absolutePath.data()) == NULL) {
|
if (realpath(dlInfo.dli_fname, absolutePath.data()) == NULL) {
|
||||||
return "";
|
return {};
|
||||||
}
|
}
|
||||||
return absolutePath.data();
|
return absolutePath.data();
|
||||||
}
|
}
|
||||||
#elif defined(DAWN_PLATFORM_WINDOWS)
|
#elif defined(DAWN_PLATFORM_WINDOWS)
|
||||||
std::string GetModulePath() {
|
std::optional<std::string> GetModulePath() {
|
||||||
UNREACHABLE();
|
static int placeholderSymbol = 0;
|
||||||
return "";
|
HMODULE module = nullptr;
|
||||||
|
// GetModuleHandleEx is unavailable on UWP
|
||||||
|
# if defined(DAWN_IS_WINUWP)
|
||||||
|
return {};
|
||||||
|
# else
|
||||||
|
if (!GetModuleHandleExA(
|
||||||
|
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||||
|
reinterpret_cast<LPCSTR>(&placeholderSymbol), &module)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
return GetHModulePath(module);
|
||||||
}
|
}
|
||||||
#elif defined(DAWN_PLATFORM_FUCHSIA)
|
#elif defined(DAWN_PLATFORM_FUCHSIA)
|
||||||
std::string GetModulePath() {
|
std::optional<std::string> GetModulePath() {
|
||||||
UNREACHABLE();
|
return {};
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
#elif defined(DAWN_PLATFORM_EMSCRIPTEN)
|
#elif defined(DAWN_PLATFORM_EMSCRIPTEN)
|
||||||
std::string GetModulePath() {
|
std::optional<std::string> GetModulePath() {
|
||||||
UNREACHABLE();
|
return {};
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# error "Implement GetModulePath for your platform."
|
# error "Implement GetModulePath for your platform."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string GetModuleDirectory() {
|
std::optional<std::string> GetModuleDirectory() {
|
||||||
std::string modPath = GetModulePath();
|
std::optional<std::string> modPath = GetModulePath();
|
||||||
size_t lastPathSepLoc = modPath.find_last_of(GetPathSeparator());
|
if (!modPath) {
|
||||||
return lastPathSepLoc != std::string::npos ? modPath.substr(0, lastPathSepLoc + 1) : "";
|
return {};
|
||||||
|
}
|
||||||
|
size_t lastPathSepLoc = modPath->find_last_of(GetPathSeparator());
|
||||||
|
if (lastPathSepLoc == std::string::npos) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return modPath->substr(0, lastPathSepLoc + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScopedEnvironmentVar
|
// ScopedEnvironmentVar
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "common/Platform.h"
|
#include "common/Platform.h"
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
const char* GetPathSeparator();
|
const char* GetPathSeparator();
|
||||||
|
@ -25,8 +26,11 @@ const char* GetPathSeparator();
|
||||||
std::pair<std::string, bool> GetEnvironmentVar(const char* variableName);
|
std::pair<std::string, bool> GetEnvironmentVar(const char* variableName);
|
||||||
bool SetEnvironmentVar(const char* variableName, const char* value);
|
bool SetEnvironmentVar(const char* variableName, const char* value);
|
||||||
// Directories are always returned with a trailing path separator.
|
// Directories are always returned with a trailing path separator.
|
||||||
std::string GetExecutableDirectory();
|
// May return std::nullopt if the path is too long, there is no current
|
||||||
std::string GetModuleDirectory();
|
// module (statically linked into executable), or the function is not
|
||||||
|
// implemented on the platform.
|
||||||
|
std::optional<std::string> GetExecutableDirectory();
|
||||||
|
std::optional<std::string> GetModuleDirectory();
|
||||||
|
|
||||||
#ifdef DAWN_PLATFORM_MACOS
|
#ifdef DAWN_PLATFORM_MACOS
|
||||||
void GetMacOSVersion(int32_t* majorVersion, int32_t* minorVersion = nullptr);
|
void GetMacOSVersion(int32_t* majorVersion, int32_t* minorVersion = nullptr);
|
||||||
|
|
|
@ -331,10 +331,10 @@ source_set("dawn_native_sources") {
|
||||||
"VertexFormat.cpp",
|
"VertexFormat.cpp",
|
||||||
"VertexFormat.h",
|
"VertexFormat.h",
|
||||||
"dawn_platform.h",
|
"dawn_platform.h",
|
||||||
"webgpu_absl_format.cpp",
|
|
||||||
"webgpu_absl_format.h",
|
|
||||||
"utils/WGPUHelpers.cpp",
|
"utils/WGPUHelpers.cpp",
|
||||||
"utils/WGPUHelpers.h",
|
"utils/WGPUHelpers.h",
|
||||||
|
"webgpu_absl_format.cpp",
|
||||||
|
"webgpu_absl_format.h",
|
||||||
]
|
]
|
||||||
|
|
||||||
if (dawn_use_x11) {
|
if (dawn_use_x11) {
|
||||||
|
@ -673,6 +673,9 @@ source_set("dawn_native_sources") {
|
||||||
"//third_party/fuchsia-sdk/sdk:trace_engine",
|
"//third_party/fuchsia-sdk/sdk:trace_engine",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
if (dawn_is_winuwp) {
|
||||||
|
defines += [ "DAWN_IS_WINUWP" ]
|
||||||
|
}
|
||||||
if (enable_vulkan_validation_layers) {
|
if (enable_vulkan_validation_layers) {
|
||||||
defines += [
|
defines += [
|
||||||
"DAWN_ENABLE_VULKAN_VALIDATION_LAYERS",
|
"DAWN_ENABLE_VULKAN_VALIDATION_LAYERS",
|
||||||
|
@ -681,17 +684,11 @@ source_set("dawn_native_sources") {
|
||||||
}
|
}
|
||||||
if (enable_vulkan_loader) {
|
if (enable_vulkan_loader) {
|
||||||
data_deps += [ "${dawn_vulkan_loader_dir}:libvulkan" ]
|
data_deps += [ "${dawn_vulkan_loader_dir}:libvulkan" ]
|
||||||
defines += [ "DAWN_ENABLE_VULKAN_LOADER" ]
|
|
||||||
}
|
}
|
||||||
if (use_swiftshader) {
|
if (use_swiftshader) {
|
||||||
data_deps += [
|
data_deps +=
|
||||||
"${dawn_swiftshader_dir}/src/Vulkan:icd_file",
|
[ "${dawn_swiftshader_dir}/src/Vulkan:swiftshader_libvulkan" ]
|
||||||
"${dawn_swiftshader_dir}/src/Vulkan:swiftshader_libvulkan",
|
defines += [ "DAWN_ENABLE_SWIFTSHADER" ]
|
||||||
]
|
|
||||||
defines += [
|
|
||||||
"DAWN_ENABLE_SWIFTSHADER",
|
|
||||||
"DAWN_SWIFTSHADER_VK_ICD_JSON=\"${swiftshader_icd_file_name}\"",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,7 +187,8 @@ namespace dawn::native {
|
||||||
|
|
||||||
// Instance
|
// Instance
|
||||||
|
|
||||||
Instance::Instance() : mImpl(InstanceBase::Create()) {
|
Instance::Instance(const WGPUInstanceDescriptor* desc)
|
||||||
|
: mImpl(InstanceBase::Create(reinterpret_cast<const InstanceDescriptor*>(desc))) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Instance::~Instance() {
|
Instance::~Instance() {
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include "common/Assert.h"
|
#include "common/Assert.h"
|
||||||
#include "common/GPUInfo.h"
|
#include "common/GPUInfo.h"
|
||||||
#include "common/Log.h"
|
#include "common/Log.h"
|
||||||
|
#include "common/SystemUtils.h"
|
||||||
|
#include "dawn_native/ChainUtils_autogen.h"
|
||||||
#include "dawn_native/ErrorData.h"
|
#include "dawn_native/ErrorData.h"
|
||||||
#include "dawn_native/Surface.h"
|
#include "dawn_native/Surface.h"
|
||||||
#include "dawn_native/ValidationUtils_autogen.h"
|
#include "dawn_native/ValidationUtils_autogen.h"
|
||||||
|
@ -96,15 +98,36 @@ namespace dawn::native {
|
||||||
// static
|
// static
|
||||||
InstanceBase* InstanceBase::Create(const InstanceDescriptor* descriptor) {
|
InstanceBase* InstanceBase::Create(const InstanceDescriptor* descriptor) {
|
||||||
Ref<InstanceBase> instance = AcquireRef(new InstanceBase);
|
Ref<InstanceBase> instance = AcquireRef(new InstanceBase);
|
||||||
if (!instance->Initialize(descriptor)) {
|
static constexpr InstanceDescriptor kDefaultDesc = {};
|
||||||
|
if (descriptor == nullptr) {
|
||||||
|
descriptor = &kDefaultDesc;
|
||||||
|
}
|
||||||
|
if (instance->ConsumedError(instance->Initialize(descriptor))) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return instance.Detach();
|
return instance.Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/dawn/832): make the platform an initialization parameter of the instance.
|
// TODO(crbug.com/dawn/832): make the platform an initialization parameter of the instance.
|
||||||
bool InstanceBase::Initialize(const InstanceDescriptor*) {
|
MaybeError InstanceBase::Initialize(const InstanceDescriptor* descriptor) {
|
||||||
return true;
|
DAWN_TRY(ValidateSingleSType(descriptor->nextInChain, wgpu::SType::DawnInstanceDescriptor));
|
||||||
|
const DawnInstanceDescriptor* dawnDesc = nullptr;
|
||||||
|
FindInChain(descriptor->nextInChain, &dawnDesc);
|
||||||
|
if (dawnDesc != nullptr) {
|
||||||
|
for (uint32_t i = 0; i < dawnDesc->additionalRuntimeSearchPathsCount; ++i) {
|
||||||
|
mRuntimeSearchPaths.push_back(dawnDesc->additionalRuntimeSearchPaths[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Default paths to search are next to the shared library, next to the executable, and
|
||||||
|
// no path (just libvulkan.so).
|
||||||
|
if (auto p = GetModuleDirectory()) {
|
||||||
|
mRuntimeSearchPaths.push_back(std::move(*p));
|
||||||
|
}
|
||||||
|
if (auto p = GetExecutableDirectory()) {
|
||||||
|
mRuntimeSearchPaths.push_back(std::move(*p));
|
||||||
|
}
|
||||||
|
mRuntimeSearchPaths.push_back("");
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceBase::APIRequestAdapter(const RequestAdapterOptions* options,
|
void InstanceBase::APIRequestAdapter(const RequestAdapterOptions* options,
|
||||||
|
@ -386,6 +409,10 @@ namespace dawn::native {
|
||||||
return mDefaultPlatform.get();
|
return mDefaultPlatform.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& InstanceBase::GetRuntimeSearchPaths() const {
|
||||||
|
return mRuntimeSearchPaths;
|
||||||
|
}
|
||||||
|
|
||||||
const XlibXcbFunctions* InstanceBase::GetOrCreateXlibXcbFunctions() {
|
const XlibXcbFunctions* InstanceBase::GetOrCreateXlibXcbFunctions() {
|
||||||
#if defined(DAWN_USE_X11)
|
#if defined(DAWN_USE_X11)
|
||||||
if (mXlibXcbFunctions == nullptr) {
|
if (mXlibXcbFunctions == nullptr) {
|
||||||
|
|
|
@ -76,6 +76,8 @@ namespace dawn::native {
|
||||||
void SetPlatform(dawn::platform::Platform* platform);
|
void SetPlatform(dawn::platform::Platform* platform);
|
||||||
dawn::platform::Platform* GetPlatform();
|
dawn::platform::Platform* GetPlatform();
|
||||||
|
|
||||||
|
const std::vector<std::string>& GetRuntimeSearchPaths() const;
|
||||||
|
|
||||||
// Get backend-independent libraries that need to be loaded dynamically.
|
// Get backend-independent libraries that need to be loaded dynamically.
|
||||||
const XlibXcbFunctions* GetOrCreateXlibXcbFunctions();
|
const XlibXcbFunctions* GetOrCreateXlibXcbFunctions();
|
||||||
|
|
||||||
|
@ -89,7 +91,7 @@ namespace dawn::native {
|
||||||
InstanceBase(const InstanceBase& other) = delete;
|
InstanceBase(const InstanceBase& other) = delete;
|
||||||
InstanceBase& operator=(const InstanceBase& other) = delete;
|
InstanceBase& operator=(const InstanceBase& other) = delete;
|
||||||
|
|
||||||
bool Initialize(const InstanceDescriptor* descriptor);
|
MaybeError Initialize(const InstanceDescriptor* descriptor);
|
||||||
|
|
||||||
// Lazily creates connections to all backends that have been compiled.
|
// Lazily creates connections to all backends that have been compiled.
|
||||||
void EnsureBackendConnection(wgpu::BackendType backendType);
|
void EnsureBackendConnection(wgpu::BackendType backendType);
|
||||||
|
@ -99,6 +101,8 @@ namespace dawn::native {
|
||||||
ResultOrError<Ref<AdapterBase>> RequestAdapterInternal(
|
ResultOrError<Ref<AdapterBase>> RequestAdapterInternal(
|
||||||
const RequestAdapterOptions* options);
|
const RequestAdapterOptions* options);
|
||||||
|
|
||||||
|
std::vector<std::string> mRuntimeSearchPaths;
|
||||||
|
|
||||||
BackendsBitset mBackendsConnected;
|
BackendsBitset mBackendsConnected;
|
||||||
|
|
||||||
bool mDiscoveredDefaultAdapters = false;
|
bool mDiscoveredDefaultAdapters = false;
|
||||||
|
|
|
@ -172,55 +172,43 @@ namespace dawn::native::vulkan {
|
||||||
ScopedEnvironmentVar vkICDFilenames;
|
ScopedEnvironmentVar vkICDFilenames;
|
||||||
ScopedEnvironmentVar vkLayerPath;
|
ScopedEnvironmentVar vkLayerPath;
|
||||||
|
|
||||||
#if defined(DAWN_ENABLE_VULKAN_LOADER)
|
const std::vector<std::string>& searchPaths = instance->GetRuntimeSearchPaths();
|
||||||
// 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
|
auto CommaSeparatedResolvedSearchPaths = [&](const char* name) {
|
||||||
// loader by getting the path to the dawn native library and traversing relative from there.
|
std::string list;
|
||||||
// This has implications for dawn tests because some of them are linking statically to
|
bool first = true;
|
||||||
// dawn_native which means the "module" is actually the test as well. If the directory
|
for (const std::string& path : searchPaths) {
|
||||||
// location of the tests change w.r.t the shared lib then this may break. Essentially we are
|
if (!first) {
|
||||||
// assuming that our custom built Vulkan loader will always be in the same directory as the
|
list += ", ";
|
||||||
// shared dawn native library and all test binaries that link statically.
|
}
|
||||||
const std::string resolvedVulkanLibPath = GetModuleDirectory() + kVulkanLibName;
|
first = false;
|
||||||
#else
|
list += (path + name);
|
||||||
const std::string resolvedVulkanLibPath = kVulkanLibName;
|
}
|
||||||
#endif // defined(DAWN_ENABLE_VULKAN_LOADER)
|
return list;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto LoadVulkan = [&](const char* libName) -> MaybeError {
|
||||||
|
for (const std::string& path : searchPaths) {
|
||||||
|
std::string resolvedPath = path + libName;
|
||||||
|
if (mVulkanLib.Open(resolvedPath)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DAWN_FORMAT_INTERNAL_ERROR("Couldn't load Vulkan. Searched %s.",
|
||||||
|
CommaSeparatedResolvedSearchPaths(libName));
|
||||||
|
};
|
||||||
|
|
||||||
switch (icd) {
|
switch (icd) {
|
||||||
case ICD::None: {
|
case ICD::None: {
|
||||||
if (!mVulkanLib.Open(resolvedVulkanLibPath)) {
|
DAWN_TRY(LoadVulkan(kVulkanLibName));
|
||||||
return DAWN_FORMAT_INTERNAL_ERROR("Couldn't load %s.", resolvedVulkanLibPath);
|
// Succesfully loaded driver; break.
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ICD::SwiftShader: {
|
case ICD::SwiftShader: {
|
||||||
#if defined(DAWN_ENABLE_SWIFTSHADER)
|
#if defined(DAWN_ENABLE_SWIFTSHADER)
|
||||||
// First try to load the system Vulkan driver, if that fails, try to load with
|
DAWN_TRY(LoadVulkan(kSwiftshaderLibName));
|
||||||
// Swiftshader. Note: The system driver could potentially be Swiftshader if it was
|
break;
|
||||||
// installed.
|
|
||||||
# if defined(DAWN_SWIFTSHADER_VK_ICD_JSON)
|
|
||||||
if (mVulkanLib.Open(resolvedVulkanLibPath)) {
|
|
||||||
std::string fullSwiftshaderICDPath =
|
|
||||||
GetExecutableDirectory() + DAWN_SWIFTSHADER_VK_ICD_JSON;
|
|
||||||
if (!vkICDFilenames.Set("VK_ICD_FILENAMES", fullSwiftshaderICDPath.c_str())) {
|
|
||||||
return DAWN_FORMAT_INTERNAL_ERROR("Couldn't set VK_ICD_FILENAMES to %s.",
|
|
||||||
fullSwiftshaderICDPath);
|
|
||||||
}
|
|
||||||
// Succesfully loaded driver and set VK_ICD_FILENAMES.
|
|
||||||
break;
|
|
||||||
} else
|
|
||||||
# endif // defined(DAWN_SWIFTSHADER_VK_ICD_JSON)
|
|
||||||
// Fallback to loading SwiftShader directly.
|
|
||||||
if (mVulkanLib.Open(kSwiftshaderLibName)) {
|
|
||||||
// Succesfully loaded SwiftShader.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return DAWN_FORMAT_INTERNAL_ERROR(
|
|
||||||
"Failed to load SwiftShader. DAWN_SWIFTSHADER_VK_ICD_JSON was not defined and "
|
|
||||||
"could not load %s.",
|
|
||||||
kSwiftshaderLibName);
|
|
||||||
#endif // defined(DAWN_ENABLE_SWIFTSHADER)
|
#endif // defined(DAWN_ENABLE_SWIFTSHADER)
|
||||||
|
|
||||||
// ICD::SwiftShader should not be passed if SwiftShader is not enabled.
|
// ICD::SwiftShader should not be passed if SwiftShader is not enabled.
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -228,7 +216,8 @@ namespace dawn::native::vulkan {
|
||||||
|
|
||||||
if (instance->IsBackendValidationEnabled()) {
|
if (instance->IsBackendValidationEnabled()) {
|
||||||
#if defined(DAWN_ENABLE_VULKAN_VALIDATION_LAYERS)
|
#if defined(DAWN_ENABLE_VULKAN_VALIDATION_LAYERS)
|
||||||
std::string vkDataDir = GetExecutableDirectory() + DAWN_VK_DATA_DIR;
|
auto execDir = GetExecutableDirectory();
|
||||||
|
std::string vkDataDir = execDir.value_or("") + DAWN_VK_DATA_DIR;
|
||||||
if (!vkLayerPath.Set("VK_LAYER_PATH", vkDataDir.c_str())) {
|
if (!vkLayerPath.Set("VK_LAYER_PATH", vkDataDir.c_str())) {
|
||||||
return DAWN_INTERNAL_ERROR("Couldn't set VK_LAYER_PATH");
|
return DAWN_INTERNAL_ERROR("Couldn't set VK_LAYER_PATH");
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ namespace dawn::native {
|
||||||
// for this instance.
|
// for this instance.
|
||||||
class DAWN_NATIVE_EXPORT Instance {
|
class DAWN_NATIVE_EXPORT Instance {
|
||||||
public:
|
public:
|
||||||
Instance();
|
explicit Instance(const WGPUInstanceDescriptor* desc = nullptr);
|
||||||
~Instance();
|
~Instance();
|
||||||
|
|
||||||
Instance(const Instance& other) = delete;
|
Instance(const Instance& other) = delete;
|
||||||
|
|
|
@ -40,10 +40,12 @@ TEST(SystemUtilsTests, SetEnvironmentVar) {
|
||||||
|
|
||||||
// Tests for GetExecutableDirectory
|
// Tests for GetExecutableDirectory
|
||||||
TEST(SystemUtilsTests, GetExecutableDirectory) {
|
TEST(SystemUtilsTests, GetExecutableDirectory) {
|
||||||
|
auto dir = GetExecutableDirectory();
|
||||||
// Test returned value is non-empty string
|
// Test returned value is non-empty string
|
||||||
EXPECT_NE(GetExecutableDirectory(), "");
|
EXPECT_NE(dir, std::optional{std::string("")});
|
||||||
// Test last charecter in path
|
ASSERT_NE(dir, std::nullopt);
|
||||||
EXPECT_EQ(GetExecutableDirectory().back(), *GetPathSeparator());
|
// Test last character in path
|
||||||
|
EXPECT_EQ(dir->back(), *GetPathSeparator());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests for ScopedEnvironmentVar
|
// Tests for ScopedEnvironmentVar
|
||||||
|
|
Loading…
Reference in New Issue