VulkanWrapper: fix loading driver when lib path can be resolved by dlopen

On Linux-based machines, a shared library's path may be resolved in
multiple ways, such as from LD_LIBRARY_PATH. For these OSes, use dlopen
to see if it exists. Note that trying to create a vk::DynamicLoader with
an invalid path throws an exception, and enabling exceptions is not
always possible, so we want to detect the error case beforehand.

Bug: b/177624844
Change-Id: I5f27cfe485afbac0e4f6bda14eed2809669c2510
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/52629
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Antonio Maiorano <amaiorano@google.com>
Presubmit-Ready: Antonio Maiorano <amaiorano@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
diff --git a/tests/VulkanWrapper/Util.cpp b/tests/VulkanWrapper/Util.cpp
index 37b8a9b..452cb39 100644
--- a/tests/VulkanWrapper/Util.cpp
+++ b/tests/VulkanWrapper/Util.cpp
@@ -106,7 +106,7 @@
 	}
 	else
 	{
-		assert(!"unsupported layout transition!");
+		assert(false && "unsupported layout transition!");
 	}
 
 	commandBuffer.pipelineBarrier(sourceStage, destinationStage, vk::DependencyFlags{}, 0, nullptr, 0, nullptr, 1, &barrier);
diff --git a/tests/VulkanWrapper/VulkanTester.cpp b/tests/VulkanWrapper/VulkanTester.cpp
index d3ad036..90f2ca0 100644
--- a/tests/VulkanWrapper/VulkanTester.cpp
+++ b/tests/VulkanWrapper/VulkanTester.cpp
@@ -18,12 +18,16 @@
 #if defined(_WIN32)
 #	define OS_WINDOWS 1
 #elif defined(__APPLE__)
+#	include "dlfcn.h"
 #	define OS_MAC 1
 #elif defined(__ANDROID__)
+#	include "dlfcn.h"
 #	define OS_ANDROID 1
 #elif defined(__linux__)
+#	include "dlfcn.h"
 #	define OS_LINUX 1
 #elif defined(__Fuchsia__)
+#	include <zircon/dlfcn.h>
 #	define OS_FUCHSIA 1
 #else
 #	error Unimplemented platform
@@ -34,11 +38,11 @@
 {
 #if OS_WINDOWS
 #	if !defined(STANDALONE)
-// The DLL is delay loaded (see BUILD.gn), so we can load
-// the correct ones from Chrome's swiftshader subdirectory.
-// HMODULE libvulkan = LoadLibraryA("swiftshader\\libvulkan.dll");
-// EXPECT_NE((HMODULE)NULL, libvulkan);
-// return true;
+	// The DLL is delay loaded (see BUILD.gn), so we can load
+	// the correct ones from Chrome's swiftshader subdirectory.
+	// HMODULE libvulkan = LoadLibraryA("swiftshader\\libvulkan.dll");
+	// EXPECT_NE((HMODULE)NULL, libvulkan);
+	// return true;
 #		error TODO: !STANDALONE
 #	elif defined(NDEBUG)
 #		if defined(_WIN64)
@@ -95,6 +99,20 @@
 			continue;
 		return std::make_unique<vk::DynamicLoader>(p);
 	}
+
+#if(OS_MAC || OS_LINUX || OS_ANDROID || OS_FUCHSIA)
+	// On Linux-based OSes, the lib path may be resolved by dlopen
+	for(auto &p : getDriverPaths())
+	{
+		auto lib = dlopen(p, RTLD_LAZY | RTLD_LOCAL);
+		if(lib)
+		{
+			dlclose(lib);
+			return std::make_unique<vk::DynamicLoader>(p);
+		}
+	}
+#endif
+
 	return {};
 }