From 92887c6c1fb04aa62e07d4b36e82a6e93bf4d436 Mon Sep 17 00:00:00 2001
From: Qining Lu <qining@google.com>
Date: Tue, 20 Feb 2018 18:33:17 -0500
Subject: [PATCH 1/3] Allow DlLoader to have multiple fallback names when
 searching for a library

---
 core/cc/dl_loader.cpp                     | 38 ++++++++++++++++++-----
 core/cc/dl_loader.h                       |  3 +-
 core/cc/linux/get_vulkan_proc_address.cpp |  2 +-
 3 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/core/cc/dl_loader.cpp b/core/cc/dl_loader.cpp
index da0321048b..ff878dd72b 100644
--- a/core/cc/dl_loader.cpp
+++ b/core/cc/dl_loader.cpp
@@ -30,9 +30,15 @@
 namespace {
 
 // load defs
-void* load(const char* name) {
+void* load() {
+    return nullptr;
+}
+
+template<typename... ConstCharPtrs>
+void* load(const char* name, ConstCharPtrs... fallback_names) {
+    void* ret = nullptr;
 #if TARGET_OS == GAPID_OS_WINDOWS
-    return reinterpret_cast<void*>(LoadLibraryExA(name, NULL, 0));
+    ret = reinterpret_cast<void*>(LoadLibraryExA(name, NULL, 0));
 #elif TARGET_OS == GAPID_OS_OSX
     if (name == nullptr) {
         return nullptr;
@@ -50,14 +56,19 @@ void* load(const char* name) {
             remove(tmp);
         }
     }
-    return res;
+    ret = res;
 #else
-    return dlopen(name, RTLD_NOW | RTLD_LOCAL);
+    ret = dlopen(name, RTLD_NOW | RTLD_LOCAL);
 #endif // TARGET_OS
+    if (ret == nullptr) {
+        return load(fallback_names...);
+    }
+    return ret;
 }
 
-void* must_load(const char* name) {
-  void* res = load(name);
+template<typename... ConstCharPtrs>
+void* must_load(const char* name, ConstCharPtrs... fallback_names) {
+  void* res = load(name, fallback_names...);
   if (res == nullptr) {
 #if TARGET_OS == GAPID_OS_WINDOWS
     GAPID_FATAL("Can't load library %s: %d", name, GetLastError());
@@ -100,8 +111,8 @@ void close(void* lib) {
 }  // anonymous namespace
 
 namespace core {
-
-DlLoader::DlLoader(const char* name) : mLibrary(must_load(name)) {}
+template<typename... ConstCharPtrs>
+DlLoader::DlLoader(const char* name, ConstCharPtrs... fallback_names) : mLibrary(must_load(name, fallback_names...)) {}
 
 DlLoader::~DlLoader() {
     close(mLibrary);
@@ -125,4 +136,15 @@ bool DlLoader::can_load(const char* lib_name) {
   return false;
 }
 
+#define CC const char*
+#define DL(...) \
+    template DlLoader::DlLoader(__VA_ARGS__)
+DL(CC _1);
+DL(CC _1, CC _2);
+DL(CC _1, CC _2, CC _3);
+DL(CC _1, CC _2, CC _3, CC _4);
+DL(CC _1, CC _2, CC _3, CC _4, CC _5);
+#undef DLLOADER
+#undef CC
+
 }  // namespace core
diff --git a/core/cc/dl_loader.h b/core/cc/dl_loader.h
index a62e2a09cb..c6a8488d2f 100644
--- a/core/cc/dl_loader.h
+++ b/core/cc/dl_loader.h
@@ -25,7 +25,8 @@ class DlLoader {
     // Loads the specified dynamic library.
     // If the library cannot be loaded then this is a fatal error.
     // For *nix systems, a nullptr can be used to search the application's functions.
-    DlLoader(const char* name);
+    template<typename... ConstCharPtrs>
+    DlLoader(const char* name, ConstCharPtrs... fallback_names);
 
     // Unloads the library loaded in the constructor.
     ~DlLoader();
diff --git a/core/cc/linux/get_vulkan_proc_address.cpp b/core/cc/linux/get_vulkan_proc_address.cpp
index 14eec9f04a..aa740ac60b 100644
--- a/core/cc/linux/get_vulkan_proc_address.cpp
+++ b/core/cc/linux/get_vulkan_proc_address.cpp
@@ -30,7 +30,7 @@ typedef size_t VkInstance;
 void* getVulkanInstanceProcAddress(size_t instance, const char *name, bool bypassLocal) {
     typedef PFN_vkVoidFunction (*VPAPROC)(VkInstance instance, const char *name);
 
-    static DlLoader dylib("libvulkan.so");
+    static DlLoader dylib("libvulkan.so", "libvulkan.so.1");
 
     if (VPAPROC vpa = reinterpret_cast<VPAPROC>(dylib.lookup("vkGetInstanceProcAddr"))) {
         if (void* proc = vpa(instance, name)) {

From 5ae192fb87f328f3ad056d31209e05ec7fb29b6d Mon Sep 17 00:00:00 2001
From: Qining Lu <qining@google.com>
Date: Wed, 21 Feb 2018 19:51:53 -0500
Subject: [PATCH 2/3] update HasVulkanLoader

---
 core/cc/armlinux/get_vulkan_proc_address.cpp | 2 +-
 core/cc/dl_loader.h                          | 7 ++++---
 core/cc/linux/get_vulkan_proc_address.cpp    | 2 +-
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/core/cc/armlinux/get_vulkan_proc_address.cpp b/core/cc/armlinux/get_vulkan_proc_address.cpp
index 14eec9f04a..7399c71ecc 100644
--- a/core/cc/armlinux/get_vulkan_proc_address.cpp
+++ b/core/cc/armlinux/get_vulkan_proc_address.cpp
@@ -72,6 +72,6 @@ GetVulkanInstanceProcAddressFunc* GetVulkanInstanceProcAddress = getVulkanInstan
 GetVulkanDeviceProcAddressFunc* GetVulkanDeviceProcAddress = getVulkanDeviceProcAddress;
 GetVulkanProcAddressFunc* GetVulkanProcAddress = getVulkanProcAddress;
 bool HasVulkanLoader() {
-  return DlLoader::can_load("libvulkan.so");
+  return DlLoader::can_load("libvulkan.so") || DlLoader::can_load("libvulkan.so.1");
 }
 }  // namespace core
diff --git a/core/cc/dl_loader.h b/core/cc/dl_loader.h
index c6a8488d2f..e0997ba8ee 100644
--- a/core/cc/dl_loader.h
+++ b/core/cc/dl_loader.h
@@ -22,9 +22,10 @@ namespace core {
 // Utility class for retrieving function pointers from dynamic libraries.
 class DlLoader {
 public:
-    // Loads the specified dynamic library.
-    // If the library cannot be loaded then this is a fatal error.
-    // For *nix systems, a nullptr can be used to search the application's functions.
+    // Loads the dynamic library specified by the given name and fallback names
+    // (if any). Names will be used to try to find the library in order. If the
+    // library cannot be loaded then this is a fatal error. For *nix systems,
+    // a nullptr can be used to search the application's functions.
     template<typename... ConstCharPtrs>
     DlLoader(const char* name, ConstCharPtrs... fallback_names);
 
diff --git a/core/cc/linux/get_vulkan_proc_address.cpp b/core/cc/linux/get_vulkan_proc_address.cpp
index aa740ac60b..02ea1eda86 100644
--- a/core/cc/linux/get_vulkan_proc_address.cpp
+++ b/core/cc/linux/get_vulkan_proc_address.cpp
@@ -72,6 +72,6 @@ GetVulkanInstanceProcAddressFunc* GetVulkanInstanceProcAddress = getVulkanInstan
 GetVulkanDeviceProcAddressFunc* GetVulkanDeviceProcAddress = getVulkanDeviceProcAddress;
 GetVulkanProcAddressFunc* GetVulkanProcAddress = getVulkanProcAddress;
 bool HasVulkanLoader() {
-  return DlLoader::can_load("libvulkan.so");
+  return DlLoader::can_load("libvulkan.so") || DlLoader::can_load("libvulkan.so.1");
 }
 }  // namespace core

From 1ac3176d972dd8b81f949aae6744dce9ee5e13f8 Mon Sep 17 00:00:00 2001
From: Qining <lqn.anthony@gmail.com>
Date: Thu, 22 Feb 2018 09:57:24 -0500
Subject: [PATCH 3/3] Fix DLLOADER -> DL

---
 core/cc/dl_loader.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/cc/dl_loader.cpp b/core/cc/dl_loader.cpp
index ff878dd72b..101168af78 100644
--- a/core/cc/dl_loader.cpp
+++ b/core/cc/dl_loader.cpp
@@ -144,7 +144,7 @@ DL(CC _1, CC _2);
 DL(CC _1, CC _2, CC _3);
 DL(CC _1, CC _2, CC _3, CC _4);
 DL(CC _1, CC _2, CC _3, CC _4, CC _5);
-#undef DLLOADER
+#undef DL
 #undef CC
 
 }  // namespace core