Commit a66779fc by Jamie Madill Committed by Commit Bot

Vulkan: Load layers relative to executable dir.

Instead of baking in a relative path and expecting the app to run from a fixed directory, we can change the CWD at runtime so the layers can load relative to the current executable directory. Future alternatives could include modifying the layers SDK to provide a path dynamically, but for now the relative paths must be baked in at compile-time. BUG=angleproject:1319 BUG=chromium:677841 Change-Id: I443b6b35d38276ea667cdf08ec2204ea280b6cec Reviewed-on: https://chromium-review.googlesource.com/425441 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarFrank Henigman <fjhenigman@chromium.org>
parent 57f17473
......@@ -10,19 +10,16 @@
import os, sys
if len(sys.argv) < 4:
print("Usage: " + sys.argv[0] + " <layers_source_path> <output_file> <default_vk_layers_path>")
print("Usage: " + sys.argv[0] + " <json_source_path> <output_file> <product_dir>")
sys.exit(1)
layers_source_path = sys.argv[1]
output_file = sys.argv[2]
default_vk_layers_path = sys.argv[3].rstrip("\"")
product_dir = sys.argv[3].rstrip("\"")
def fixpath(inpath):
return os.path.relpath(inpath).replace('\\', '/')
def all_paths(inpath):
return fixpath(inpath) + ";" + fixpath(os.path.join("..", fixpath(inpath)))
return os.path.relpath(inpath, product_dir).replace('\\', '/')
with open(output_file, "w") as outfile:
outfile.write("#define LAYERS_SOURCE_PATH \"" + all_paths(layers_source_path) + "\"\n")
outfile.write("#define DEFAULT_VK_LAYERS_PATH \"" + all_paths(default_vk_layers_path) + "\"\n")
outfile.write("#define LAYERS_SOURCE_PATH \"" + fixpath(layers_source_path) + "\"\n")
outfile.write("#define DEFAULT_VK_LAYERS_PATH \"" + fixpath(product_dir) + "\"\n")
......@@ -10,6 +10,7 @@
#define COMMON_SYSTEM_UTILS_H_
#include "common/angleutils.h"
#include "common/Optional.h"
namespace angle
{
......@@ -17,6 +18,8 @@ namespace angle
const char *GetExecutablePath();
const char *GetExecutableDirectory();
const char *GetSharedLibraryExtension();
Optional<std::string> GetCWD();
bool SetCWD(const char *dirName);
} // namespace angle
......
......@@ -13,6 +13,8 @@
#include <sys/types.h>
#include <unistd.h>
#include <array>
namespace angle
{
......@@ -63,4 +65,20 @@ const char *GetSharedLibraryExtension()
return "so";
}
Optional<std::string> GetCWD()
{
std::array<char, 4096> pathBuf;
char *result = getcwd(pathBuf.data(), pathBuf.size());
if (result == nullptr)
{
return Optional<std::string>::Invalid();
}
return std::string(pathBuf.data());
}
bool SetCWD(const char *dirName)
{
return (chdir(dirName) == 0);
}
} // namespace angle
......@@ -8,10 +8,14 @@
#include "system_utils.h"
#include <unistd.h>
#include <cstdlib>
#include <mach-o/dyld.h>
#include <vector>
#include <array>
namespace angle
{
......@@ -66,4 +70,20 @@ const char *GetSharedLibraryExtension()
return "dylib";
}
Optional<std::string> GetCWD()
{
std::array<char, 4096> pathBuf;
char *result = getcwd(pathBuf.data(), pathBuf.size());
if (result == nullptr)
{
return Optional<std::string>::Invalid();
}
return std::string(pathBuf.data());
}
bool SetCWD(const char *dirName)
{
return (chdir(dirName) == 0);
}
} // namespace angle
......@@ -55,4 +55,20 @@ const char *GetSharedLibraryExtension()
return "dll";
}
Optional<std::string> GetCWD()
{
std::array<char, MAX_PATH> pathBuf;
DWORD result = GetCurrentDirectoryA(static_cast<DWORD>(pathBuf.size()), pathBuf.data());
if (result == 0)
{
return Optional<std::string>::Invalid();
}
return std::string(pathBuf.data());
}
bool SetCWD(const char *dirName)
{
return (SetCurrentDirectoryA(dirName) == TRUE);
}
} // namespace angle
......@@ -15,6 +15,7 @@
#include <EGL/eglext.h>
#include "common/debug.h"
#include "common/system_utils.h"
#include "libANGLE/renderer/driver_utils.h"
#include "libANGLE/renderer/vulkan/CompilerVk.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h"
......@@ -129,6 +130,39 @@ RendererVk::~RendererVk()
vk::Error RendererVk::initialize(const egl::AttributeMap &attribs)
{
#if !defined(NDEBUG)
// Validation layers enabled by default in Debug.
mEnableValidationLayers = true;
#endif
// If specified in the attributes, override the default.
if (attribs.contains(EGL_PLATFORM_ANGLE_ENABLE_VALIDATION_LAYER_ANGLE))
{
mEnableValidationLayers =
(attribs.get(EGL_PLATFORM_ANGLE_ENABLE_VALIDATION_LAYER_ANGLE, EGL_FALSE) == EGL_TRUE);
}
// If we're loading the validation layers, we could be running from any random directory.
// Change to the executable directory so we can find the layers, then change back to the
// previous directory to be safe we don't disrupt the application.
std::string previousCWD;
if (mEnableValidationLayers)
{
const auto &cwd = angle::GetCWD();
if (!cwd.valid())
{
ANGLEPlatformCurrent()->logError("Error getting CWD for Vulkan layers init.");
mEnableValidationLayers = false;
}
else
{
previousCWD = cwd.value();
}
const char *exeDir = angle::GetExecutableDirectory();
angle::SetCWD(exeDir);
}
// Gather global layer properties.
uint32_t instanceLayerCount = 0;
ANGLE_VK_TRY(vkEnumerateInstanceLayerProperties(&instanceLayerCount, nullptr));
......@@ -150,18 +184,6 @@ vk::Error RendererVk::initialize(const egl::AttributeMap &attribs)
instanceExtensionProps.data()));
}
#if !defined(NDEBUG)
// Validation layers enabled by default in Debug.
mEnableValidationLayers = true;
#endif
// If specified in the attributes, override the default.
if (attribs.contains(EGL_PLATFORM_ANGLE_ENABLE_VALIDATION_LAYER_ANGLE))
{
mEnableValidationLayers =
(attribs.get(EGL_PLATFORM_ANGLE_ENABLE_VALIDATION_LAYER_ANGLE, EGL_FALSE) == EGL_TRUE);
}
if (mEnableValidationLayers)
{
// Verify the standard validation layers are available.
......@@ -225,6 +247,10 @@ vk::Error RendererVk::initialize(const egl::AttributeMap &attribs)
if (mEnableValidationLayers)
{
// Change back to the previous working directory now that we've loaded the instance -
// the validation layers should be loaded at this point.
angle::SetCWD(previousCWD.c_str());
VkDebugReportCallbackCreateInfoEXT debugReportInfo;
debugReportInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
......
......@@ -26,10 +26,14 @@ vulkan_gypi =
# Vulkan loader
# -------------
vulkan_gen_dir = "$target_gen_dir/angle/vulkan"
raw_vulkan_gen_dir = rebase_path(vulkan_gen_dir)
relative_vulkan_gen_dir = rebase_path(vulkan_gen_dir, root_build_dir)
config("vulkan_loader_config") {
include_dirs = rebase_path(vulkan_gypi.vulkan_loader_include_dirs, ".", "src")
defines = [
"LAYERS_SOURCE_PATH=\"./gen/third_party/angle/src/vulkan_support/angle/vulkan/json\"",
"LAYERS_SOURCE_PATH=\"$relative_vulkan_gen_dir/json\"",
"DEFAULT_VK_LAYERS_PATH=\".\"",
"API_NAME=\"Vulkan\"",
]
......@@ -68,9 +72,6 @@ static_library("vulkan_loader") {
# Vulkan layer helpers
# --------------------
vulkan_gen_dir = "$target_gen_dir/angle/vulkan"
raw_vulkan_gen_dir = rebase_path(vulkan_gen_dir)
source_set("vulkan_layer_utils") {
sources = rebase_path(vulkan_gypi.vulkan_layer_utils_sources, ".", "src")
public_configs = [
......
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