Commit c8c414b0 by Jonah Ryan-Davis Committed by Commit Bot

Reland Change to module directory when loading swiftshader ICD.

This is a reland of commit 3b10dda6. Extra changes: Be explicit about calling GetModuleHandleA Do not use the general GetModuleHandle, which may use wide strings GetModuleDirectory should return the full path, not relative. ANGLE wasn't able to locate the vulkan ICD file because it was searching down an invalid relative path. This can be fixed by ensuring the module directory is always the full path. on some platforms. Original change's description: > When loading vulkan, we can be running from any directory. We need > to change to the module directory to ensure the swiftshader ICD is > loaded properly. For example, in some Chrome releases, libGLESv2.dll > and libvk_swiftshader.dll are in a subdirectory relative to chrome.exe > > Bug: chromium:1198567 > Change-Id: I9e68927e512b239728fb2903d1a04702508a4948 > Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2873452 > Commit-Queue: Jonah Ryan-Davis <jonahr@google.com> > Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> > Reviewed-by: Jamie Madill <jmadill@chromium.org> Bug: chromium:1198567 Bug: angleproject:5949 Change-Id: Ib34067002c788f00b5ae2fa11d1e465f57bd7be8 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2893503Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Commit-Queue: Jonah Ryan-Davis <jonahr@google.com>
parent cbbaf76b
...@@ -107,6 +107,9 @@ config("internal_config") { ...@@ -107,6 +107,9 @@ config("internal_config") {
if (is_win) { if (is_win) {
defines += [ "ANGLE_IS_WIN" ] defines += [ "ANGLE_IS_WIN" ]
if (angle_is_winuwp) {
defines += [ "ANGLE_IS_WINUWP" ]
}
} else if (is_linux || is_chromeos) { } else if (is_linux || is_chromeos) {
defines += [ "ANGLE_IS_LINUX" ] defines += [ "ANGLE_IS_LINUX" ]
} }
......
...@@ -19,7 +19,7 @@ namespace angle ...@@ -19,7 +19,7 @@ namespace angle
std::string GetExecutableName(); std::string GetExecutableName();
std::string GetExecutablePath(); std::string GetExecutablePath();
std::string GetExecutableDirectory(); std::string GetExecutableDirectory();
std::string GetHelperExecutableDir(); std::string GetModuleDirectory();
const char *GetSharedLibraryExtension(); const char *GetSharedLibraryExtension();
const char *GetExecutableExtension(); const char *GetExecutableExtension();
char GetPathSeparator(); char GetPathSeparator();
......
...@@ -56,7 +56,7 @@ const char *GetPathSeparatorForEnvironmentVar() ...@@ -56,7 +56,7 @@ const char *GetPathSeparatorForEnvironmentVar()
return ":"; return ":";
} }
std::string GetHelperExecutableDir() std::string GetModuleDirectory()
{ {
std::string directory; std::string directory;
static int placeholderSymbol = 0; static int placeholderSymbol = 0;
...@@ -66,6 +66,12 @@ std::string GetHelperExecutableDir() ...@@ -66,6 +66,12 @@ std::string GetHelperExecutableDir()
std::string moduleName = dlInfo.dli_fname; std::string moduleName = dlInfo.dli_fname;
directory = moduleName.substr(0, moduleName.find_last_of('/') + 1); directory = moduleName.substr(0, moduleName.find_last_of('/') + 1);
} }
// Ensure we return the full path to the module, not the relative path
Optional<std::string> cwd = GetCWD();
if (directory.at(0) != '/' && cwd.valid())
{
directory = cwd.value() + GetPathSeparator() + directory;
}
return directory; return directory;
} }
...@@ -107,7 +113,7 @@ Library *OpenSharedLibrary(const char *libraryName, SearchType searchType) ...@@ -107,7 +113,7 @@ Library *OpenSharedLibrary(const char *libraryName, SearchType searchType)
// On iOS, shared libraries must be loaded from within the app bundle. // On iOS, shared libraries must be loaded from within the app bundle.
directory = GetExecutableDirectory() + "/Frameworks/"; directory = GetExecutableDirectory() + "/Frameworks/";
#else #else
directory = GetHelperExecutableDir(); directory = GetModuleDirectory();
#endif #endif
} }
......
...@@ -15,21 +15,37 @@ ...@@ -15,21 +15,37 @@
namespace angle namespace angle
{ {
std::string GetExecutablePath()
namespace
{
std::string GetPath(HMODULE module)
{ {
std::array<char, MAX_PATH> executableFileBuf; std::array<char, MAX_PATH> executableFileBuf;
DWORD executablePathLen = GetModuleFileNameA(nullptr, executableFileBuf.data(), DWORD executablePathLen = GetModuleFileNameA(module, executableFileBuf.data(),
static_cast<DWORD>(executableFileBuf.size())); static_cast<DWORD>(executableFileBuf.size()));
return (executablePathLen > 0 ? std::string(executableFileBuf.data()) : ""); return (executablePathLen > 0 ? std::string(executableFileBuf.data()) : "");
} }
std::string GetExecutableDirectory() std::string GetDirectory(HMODULE module)
{ {
std::string executablePath = GetExecutablePath(); std::string executablePath = GetPath(module);
size_t lastPathSepLoc = executablePath.find_last_of("\\/"); size_t lastPathSepLoc = executablePath.find_last_of("\\/");
return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : ""; return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : "";
} }
} // anonymous namespace
std::string GetExecutablePath()
{
return GetPath(nullptr);
}
std::string GetExecutableDirectory()
{
return GetDirectory(nullptr);
}
const char *GetSharedLibraryExtension() const char *GetSharedLibraryExtension()
{ {
return "dll"; return "dll";
...@@ -101,8 +117,20 @@ char GetPathSeparator() ...@@ -101,8 +117,20 @@ char GetPathSeparator()
return '\\'; return '\\';
} }
std::string GetHelperExecutableDir() std::string GetModuleDirectory()
{ {
return ""; // GetModuleHandleEx is unavailable on UWP
#if !defined(ANGLE_IS_WINUWP)
static int placeholderSymbol = 0;
HMODULE module = nullptr;
if (GetModuleHandleExA(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
reinterpret_cast<LPCSTR>(&placeholderSymbol), &module))
{
return GetDirectory(module);
}
#endif
return GetDirectory(nullptr);
} }
} // namespace angle } // namespace angle
...@@ -51,12 +51,9 @@ namespace ...@@ -51,12 +51,9 @@ namespace
!defined(ANGLE_PLATFORM_GGP) !defined(ANGLE_PLATFORM_GGP)
const std::string WrapICDEnvironment(const char *icdEnvironment) const std::string WrapICDEnvironment(const char *icdEnvironment)
{ {
# if defined(ANGLE_PLATFORM_APPLE) // The libraries are bundled into the module directory
// On MacOS the libraries are bundled into the application directory std::string ret = angle::GetModuleDirectory() + GetPathSeparator() + icdEnvironment;
std::string ret = angle::GetHelperExecutableDir() + icdEnvironment;
return ret; return ret;
# endif // defined(ANGLE_PLATFORM_APPLE)
return icdEnvironment;
} }
constexpr char kLoaderLayersPathEnv[] = "VK_LAYER_PATH"; constexpr char kLoaderLayersPathEnv[] = "VK_LAYER_PATH";
...@@ -146,9 +143,9 @@ ScopedVkLoaderEnvironment::ScopedVkLoaderEnvironment(bool enableValidationLayers ...@@ -146,9 +143,9 @@ ScopedVkLoaderEnvironment::ScopedVkLoaderEnvironment(bool enableValidationLayers
} }
else else
{ {
mPreviousCWD = cwd.value(); mPreviousCWD = cwd.value();
std::string exeDir = angle::GetExecutableDirectory(); std::string moduleDir = angle::GetModuleDirectory();
mChangedCWD = angle::SetCWD(exeDir.c_str()); mChangedCWD = angle::SetCWD(moduleDir.c_str());
if (!mChangedCWD) if (!mChangedCWD)
{ {
ERR() << "Error setting CWD for Vulkan layers init."; ERR() << "Error setting CWD for Vulkan layers init.";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment