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: Frank Henigman <fjhenigman@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/RendererVk.cpp b/src/libANGLE/renderer/vulkan/RendererVk.cpp
index 379c1ed..87ebabd 100644
--- a/src/libANGLE/renderer/vulkan/RendererVk.cpp
+++ b/src/libANGLE/renderer/vulkan/RendererVk.cpp
@@ -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 @@
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 @@
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 @@
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;