In vulkan tests, use vkGetInstanceProcAddr to get vkGetDeviceProcAddr.

We've run into drivers a few times now that have bugs where they only
expose vkGetInstaneProcAddr and not vkGetDeviceProcAddr. The latest
being swiftshader (which is getting fixed). To avoid this issue in the
future we can just have our tests use vkGetInstanceProcAddr to get
vkGetDeviceProcAddr.

Change-Id: I6d73abde507519c145b873042393f50ce6c4527c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/494822
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
diff --git a/tests/VkHardwareBufferTest.cpp b/tests/VkHardwareBufferTest.cpp
index 95a3192..9372c2c 100644
--- a/tests/VkHardwareBufferTest.cpp
+++ b/tests/VkHardwareBufferTest.cpp
@@ -508,17 +508,9 @@
 
 bool VulkanTestHelper::init(skiatest::Reporter* reporter) {
     PFN_vkGetInstanceProcAddr instProc;
-    PFN_vkGetDeviceProcAddr devProc;
-    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
+    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc)) {
         return false;
     }
-    auto getProc = [&instProc, &devProc](const char* proc_name,
-                                         VkInstance instance, VkDevice device) {
-        if (device != VK_NULL_HANDLE) {
-            return devProc(device, proc_name);
-        }
-        return instProc(instance, proc_name);
-    };
 
     fExtensions = new GrVkExtensions();
     fFeatures = new VkPhysicalDeviceFeatures2;
@@ -529,11 +521,12 @@
     fBackendContext.fInstance = VK_NULL_HANDLE;
     fBackendContext.fDevice = VK_NULL_HANDLE;
 
-    if (!sk_gpu_test::CreateVkBackendContext(getProc, &fBackendContext, fExtensions,
+    if (!sk_gpu_test::CreateVkBackendContext(instProc, &fBackendContext, fExtensions,
                                              fFeatures, &fDebugCallback)) {
         return false;
     }
     fDevice = fBackendContext.fDevice;
+    auto getProc = fBackendContext.fGetProc;
 
     if (fDebugCallback != VK_NULL_HANDLE) {
         fDestroyDebugCallback = (PFN_vkDestroyDebugReportCallbackEXT) instProc(
diff --git a/tests/VkPriorityExtensionTest.cpp b/tests/VkPriorityExtensionTest.cpp
index 1f4f13c..c844468 100644
--- a/tests/VkPriorityExtensionTest.cpp
+++ b/tests/VkPriorityExtensionTest.cpp
@@ -14,34 +14,35 @@
 #include "tests/Test.h"
 #include "tools/gpu/vk/VkTestUtils.h"
 
-#define ACQUIRE_VK_PROC_NOCHECK(name, instance, device) \
-    PFN_vk##name grVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device))
+#define ACQUIRE_VK_PROC_NOCHECK(name, instance) \
+    PFN_vk##name grVk##name =                                                              \
+            reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, VK_NULL_HANDLE))
 
-#define ACQUIRE_VK_PROC(name, instance, device)                                    \
-    PFN_vk##name grVk##name =                                                      \
-            reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device)); \
-    do {                                                                           \
-        if (grVk##name == nullptr) {                                               \
-            if (device != VK_NULL_HANDLE) {                                        \
-                destroy_instance(getProc, inst);                                   \
-            }                                                                      \
-            return;                                                                \
-        }                                                                          \
+#define ACQUIRE_VK_PROC(name, instance)                                                    \
+    PFN_vk##name grVk##name =                                                              \
+            reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, VK_NULL_HANDLE)); \
+    do {                                                                                   \
+        if (grVk##name == nullptr) {                                                       \
+            if (instance != VK_NULL_HANDLE) {                                              \
+                destroy_instance(getProc, instance);                                       \
+            }                                                                              \
+            return;                                                                        \
+        }                                                                                  \
     } while (0)
 
-#define ACQUIRE_VK_PROC_LOCAL(name, instance, device)                              \
-    PFN_vk##name grVk##name =                                                      \
-            reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device)); \
-    do {                                                                           \
-        if (grVk##name == nullptr) {                                               \
-            return;                                                                \
-        }                                                                          \
+#define ACQUIRE_VK_PROC_LOCAL(name, instance)                                              \
+    PFN_vk##name grVk##name =                                                              \
+            reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, VK_NULL_HANDLE)); \
+    do {                                                                                   \
+        if (grVk##name == nullptr) {                                                       \
+            return;                                                                        \
+        }                                                                                  \
     } while (0)
 
-#define GET_PROC_LOCAL(F, inst, device) PFN_vk ## F F = (PFN_vk ## F) getProc("vk" #F, inst, device)
+#define GET_PROC_LOCAL(F, inst) PFN_vk ## F F = (PFN_vk ## F) getProc("vk" #F, inst, VK_NULL_HANDLE)
 
 static void destroy_instance(GrVkGetProc getProc, VkInstance inst) {
-    ACQUIRE_VK_PROC_LOCAL(DestroyInstance, inst, VK_NULL_HANDLE);
+    ACQUIRE_VK_PROC_LOCAL(DestroyInstance, inst);
     grVkDestroyInstance(inst, nullptr);
 }
 
@@ -50,21 +51,17 @@
 // doesn't crash.
 DEF_GPUTEST(VulkanPriorityExtension, reporter, options) {
     PFN_vkGetInstanceProcAddr instProc;
-    PFN_vkGetDeviceProcAddr devProc;
-    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
+    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc)) {
         return;
     }
-    auto getProc = [instProc, devProc](const char* proc_name,
-                                       VkInstance instance, VkDevice device) {
-        if (device != VK_NULL_HANDLE) {
-            return devProc(device, proc_name);
-        }
+    // This isn't the most effecient but we just use the instProc to get all ptrs.
+    auto getProc = [instProc](const char* proc_name, VkInstance instance, VkDevice) {
         return instProc(instance, proc_name);
     };
 
     VkResult err;
 
-    ACQUIRE_VK_PROC_NOCHECK(EnumerateInstanceVersion, VK_NULL_HANDLE, VK_NULL_HANDLE);
+    ACQUIRE_VK_PROC_NOCHECK(EnumerateInstanceVersion, VK_NULL_HANDLE);
     uint32_t instanceVersion = 0;
     if (!grVkEnumerateInstanceVersion) {
         instanceVersion = VK_MAKE_VERSION(1, 0, 0);
@@ -112,21 +109,21 @@
         nullptr,                                   // ppEnabledExtensionNames
     };
 
-    ACQUIRE_VK_PROC(CreateInstance, VK_NULL_HANDLE, VK_NULL_HANDLE);
+    ACQUIRE_VK_PROC(CreateInstance, VK_NULL_HANDLE);
     err = grVkCreateInstance(&instance_create, nullptr, &inst);
     if (err < 0) {
         ERRORF(reporter, "Failed to create VkInstance");
         return;
     }
 
-    ACQUIRE_VK_PROC(EnumeratePhysicalDevices, inst, VK_NULL_HANDLE);
-    ACQUIRE_VK_PROC(GetPhysicalDeviceProperties, inst, VK_NULL_HANDLE);
-    ACQUIRE_VK_PROC(GetPhysicalDeviceQueueFamilyProperties, inst, VK_NULL_HANDLE);
-    ACQUIRE_VK_PROC(GetPhysicalDeviceFeatures, inst, VK_NULL_HANDLE);
-    ACQUIRE_VK_PROC(CreateDevice, inst, VK_NULL_HANDLE);
-    ACQUIRE_VK_PROC(GetDeviceQueue, inst, VK_NULL_HANDLE);
-    ACQUIRE_VK_PROC(DeviceWaitIdle, inst, VK_NULL_HANDLE);
-    ACQUIRE_VK_PROC(DestroyDevice, inst, VK_NULL_HANDLE);
+    ACQUIRE_VK_PROC(EnumeratePhysicalDevices, inst);
+    ACQUIRE_VK_PROC(GetPhysicalDeviceProperties, inst);
+    ACQUIRE_VK_PROC(GetPhysicalDeviceQueueFamilyProperties, inst);
+    ACQUIRE_VK_PROC(GetPhysicalDeviceFeatures, inst);
+    ACQUIRE_VK_PROC(CreateDevice, inst);
+    ACQUIRE_VK_PROC(GetDeviceQueue, inst);
+    ACQUIRE_VK_PROC(DeviceWaitIdle, inst);
+    ACQUIRE_VK_PROC(DestroyDevice, inst);
 
     uint32_t gpuCount;
     err = grVkEnumeratePhysicalDevices(inst, &gpuCount, nullptr);
@@ -180,8 +177,8 @@
         return;
     }
 
-    GET_PROC_LOCAL(EnumerateDeviceExtensionProperties, inst, VK_NULL_HANDLE);
-    GET_PROC_LOCAL(EnumerateDeviceLayerProperties, inst, VK_NULL_HANDLE);
+    GET_PROC_LOCAL(EnumerateDeviceExtensionProperties, inst);
+    GET_PROC_LOCAL(EnumerateDeviceLayerProperties, inst);
 
     if (!EnumerateDeviceExtensionProperties ||
         !EnumerateDeviceLayerProperties) {
diff --git a/tools/gpu/vk/VkTestContext.cpp b/tools/gpu/vk/VkTestContext.cpp
index 3fa461d..9da5c45 100644
--- a/tools/gpu/vk/VkTestContext.cpp
+++ b/tools/gpu/vk/VkTestContext.cpp
@@ -37,21 +37,14 @@
             ownsContext = false;
         } else {
             PFN_vkGetInstanceProcAddr instProc;
-            PFN_vkGetDeviceProcAddr devProc;
-            if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
+            if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc)) {
                 return nullptr;
             }
-            auto getProc = [instProc, devProc](const char* proc_name,
-                                               VkInstance instance, VkDevice device) {
-                if (device != VK_NULL_HANDLE) {
-                    return devProc(device, proc_name);
-                }
-                return instProc(instance, proc_name);
-            };
+
             extensions = new GrVkExtensions();
             features = new VkPhysicalDeviceFeatures2;
             memset(features, 0, sizeof(VkPhysicalDeviceFeatures2));
-            if (!sk_gpu_test::CreateVkBackendContext(getProc, &backendContext, extensions,
+            if (!sk_gpu_test::CreateVkBackendContext(instProc, &backendContext, extensions,
                                                      features, &debugCallback)) {
                 sk_gpu_test::FreeVulkanFeaturesStructs(features);
                 delete features;
diff --git a/tools/gpu/vk/VkTestHelper.cpp b/tools/gpu/vk/VkTestHelper.cpp
index 12c6807..aea196d 100644
--- a/tools/gpu/vk/VkTestHelper.cpp
+++ b/tools/gpu/vk/VkTestHelper.cpp
@@ -13,16 +13,15 @@
 #include "include/gpu/GrDirectContext.h"
 #include "tools/gpu/vk/VkTestUtils.h"
 
-#define ACQUIRE_INST_VK_PROC(name)                                                           \
-    fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, fBackendContext.fInstance,\
-                                                       VK_NULL_HANDLE));                     \
-    if (fVk##name == nullptr) {                                                              \
-        SkDebugf("Function ptr for vk%s could not be acquired\n", #name);                    \
-        return false;                                                                        \
+#define ACQUIRE_INST_VK_PROC(name)                                                               \
+    fVk##name = reinterpret_cast<PFN_vk##name>(instProc(fBackendContext.fInstance, "vk" #name)); \
+    if (fVk##name == nullptr) {                                                                  \
+        SkDebugf("Function ptr for vk%s could not be acquired\n", #name);                        \
+        return false;                                                                            \
     }
 
 #define ACQUIRE_DEVICE_VK_PROC(name)                                                          \
-    fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, VK_NULL_HANDLE, fDevice)); \
+    fVk##name = reinterpret_cast<PFN_vk##name>(fVkGetDeviceProcAddr(fDevice, "vk" #name));    \
     if (fVk##name == nullptr) {                                                               \
         SkDebugf("Function ptr for vk%s could not be acquired\n", #name);                     \
         return false;                                                                         \
@@ -30,17 +29,9 @@
 
 bool VkTestHelper::init() {
     PFN_vkGetInstanceProcAddr instProc;
-    PFN_vkGetDeviceProcAddr devProc;
-    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
+    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc)) {
         return false;
     }
-    auto getProc = [&instProc, &devProc](const char* proc_name,
-                                         VkInstance instance, VkDevice device) {
-        if (device != VK_NULL_HANDLE) {
-            return devProc(device, proc_name);
-        }
-        return instProc(instance, proc_name);
-    };
 
     fFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
     fFeatures.pNext = nullptr;
@@ -48,7 +39,7 @@
     fBackendContext.fInstance = VK_NULL_HANDLE;
     fBackendContext.fDevice = VK_NULL_HANDLE;
 
-    if (!sk_gpu_test::CreateVkBackendContext(getProc, &fBackendContext, &fExtensions,
+    if (!sk_gpu_test::CreateVkBackendContext(instProc, &fBackendContext, &fExtensions,
                                              &fFeatures, &fDebugCallback, nullptr,
                                              sk_gpu_test::CanPresentFn(), fIsProtected)) {
         return false;
@@ -66,6 +57,8 @@
     ACQUIRE_INST_VK_PROC(GetPhysicalDeviceFormatProperties)
     ACQUIRE_INST_VK_PROC(GetPhysicalDeviceMemoryProperties)
 
+    ACQUIRE_INST_VK_PROC(GetDeviceProcAddr)
+
     ACQUIRE_DEVICE_VK_PROC(CreateImage)
     ACQUIRE_DEVICE_VK_PROC(DestroyImage)
     ACQUIRE_DEVICE_VK_PROC(GetImageMemoryRequirements)
diff --git a/tools/gpu/vk/VkTestHelper.h b/tools/gpu/vk/VkTestHelper.h
index 9fc11e4..e053b08 100644
--- a/tools/gpu/vk/VkTestHelper.h
+++ b/tools/gpu/vk/VkTestHelper.h
@@ -39,6 +39,7 @@
     DECLARE_VK_PROC(DestroyInstance);
     DECLARE_VK_PROC(DeviceWaitIdle);
     DECLARE_VK_PROC(DestroyDevice);
+    DECLARE_VK_PROC(GetDeviceProcAddr);
 
     DECLARE_VK_PROC(GetPhysicalDeviceFormatProperties);
     DECLARE_VK_PROC(GetPhysicalDeviceMemoryProperties);
diff --git a/tools/gpu/vk/VkTestUtils.cpp b/tools/gpu/vk/VkTestUtils.cpp
index d7a10a2..b053da0 100644
--- a/tools/gpu/vk/VkTestUtils.cpp
+++ b/tools/gpu/vk/VkTestUtils.cpp
@@ -33,26 +33,21 @@
 
 namespace sk_gpu_test {
 
-bool LoadVkLibraryAndGetProcAddrFuncs(PFN_vkGetInstanceProcAddr* instProc,
-                                      PFN_vkGetDeviceProcAddr* devProc) {
+bool LoadVkLibraryAndGetProcAddrFuncs(PFN_vkGetInstanceProcAddr* instProc) {
     static void* vkLib = nullptr;
     static PFN_vkGetInstanceProcAddr localInstProc = nullptr;
-    static PFN_vkGetDeviceProcAddr localDevProc = nullptr;
     if (!vkLib) {
         vkLib = SkLoadDynamicLibrary(SK_GPU_TOOLS_VK_LIBRARY_NAME);
         if (!vkLib) {
             return false;
         }
         localInstProc = (PFN_vkGetInstanceProcAddr) SkGetProcedureAddress(vkLib,
-                                                                        "vkGetInstanceProcAddr");
-        localDevProc = (PFN_vkGetDeviceProcAddr) SkGetProcedureAddress(vkLib,
-                                                                     "vkGetDeviceProcAddr");
+                                                                          "vkGetInstanceProcAddr");
     }
-    if (!localInstProc || !localDevProc) {
+    if (!localInstProc) {
         return false;
     }
     *instProc = localInstProc;
-    *devProc = localDevProc;
     return true;
 }
 
@@ -139,34 +134,37 @@
 }
 #endif
 
-#define GET_PROC_LOCAL(F, inst, device) PFN_vk ## F F = (PFN_vk ## F) getProc("vk" #F, inst, device)
+#define ACQUIRE_VK_INST_PROC_LOCAL(name, instance)                                 \
+    PFN_vk##name grVk##name =                                                      \
+        reinterpret_cast<PFN_vk##name>(getInstProc(instance, "vk" #name));         \
+    do {                                                                           \
+        if (grVk##name == nullptr) {                                               \
+            SkDebugf("Function ptr for vk%s could not be acquired\n", #name);      \
+            return false;                                                          \
+        }                                                                          \
+    } while (0)
 
-static bool init_instance_extensions_and_layers(GrVkGetProc getProc,
+static bool init_instance_extensions_and_layers(PFN_vkGetInstanceProcAddr getInstProc,
                                                 uint32_t specVersion,
                                                 SkTArray<VkExtensionProperties>* instanceExtensions,
                                                 SkTArray<VkLayerProperties>* instanceLayers) {
-    if (getProc == nullptr) {
+    if (getInstProc == nullptr) {
         return false;
     }
 
-    GET_PROC_LOCAL(EnumerateInstanceExtensionProperties, VK_NULL_HANDLE, VK_NULL_HANDLE);
-    GET_PROC_LOCAL(EnumerateInstanceLayerProperties, VK_NULL_HANDLE, VK_NULL_HANDLE);
-
-    if (!EnumerateInstanceExtensionProperties ||
-        !EnumerateInstanceLayerProperties) {
-        return false;
-    }
+    ACQUIRE_VK_INST_PROC_LOCAL(EnumerateInstanceExtensionProperties, VK_NULL_HANDLE);
+    ACQUIRE_VK_INST_PROC_LOCAL(EnumerateInstanceLayerProperties, VK_NULL_HANDLE);
 
     VkResult res;
     uint32_t layerCount = 0;
 #ifdef SK_ENABLE_VK_LAYERS
     // instance layers
-    res = EnumerateInstanceLayerProperties(&layerCount, nullptr);
+    res = grVkEnumerateInstanceLayerProperties(&layerCount, nullptr);
     if (VK_SUCCESS != res) {
         return false;
     }
     VkLayerProperties* layers = new VkLayerProperties[layerCount];
-    res = EnumerateInstanceLayerProperties(&layerCount, layers);
+    res = grVkEnumerateInstanceLayerProperties(&layerCount, layers);
     if (VK_SUCCESS != res) {
         delete[] layers;
         return false;
@@ -187,12 +185,12 @@
     // via Vulkan implementation and implicitly enabled layers
     {
         uint32_t extensionCount = 0;
-        res = EnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
+        res = grVkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
         if (VK_SUCCESS != res) {
             return false;
         }
         VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
-        res = EnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions);
+        res = grVkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions);
         if (VK_SUCCESS != res) {
             delete[] extensions;
             return false;
@@ -207,14 +205,14 @@
     layerCount = instanceLayers->count();
     for (uint32_t layerIndex = 0; layerIndex < layerCount; ++layerIndex) {
         uint32_t extensionCount = 0;
-        res = EnumerateInstanceExtensionProperties((*instanceLayers)[layerIndex].layerName,
-                                                   &extensionCount, nullptr);
+        res = grVkEnumerateInstanceExtensionProperties((*instanceLayers)[layerIndex].layerName,
+                                                       &extensionCount, nullptr);
         if (VK_SUCCESS != res) {
             return false;
         }
         VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
-        res = EnumerateInstanceExtensionProperties((*instanceLayers)[layerIndex].layerName,
-                                                   &extensionCount, extensions);
+        res = grVkEnumerateInstanceExtensionProperties((*instanceLayers)[layerIndex].layerName,
+                                                       &extensionCount, extensions);
         if (VK_SUCCESS != res) {
             delete[] extensions;
             return false;
@@ -228,6 +226,8 @@
     return true;
 }
 
+#define GET_PROC_LOCAL(F, inst, device) PFN_vk ## F F = (PFN_vk ## F) getProc("vk" #F, inst, device)
+
 static bool init_device_extensions_and_layers(GrVkGetProc getProc, uint32_t specVersion,
                                               VkInstance inst, VkPhysicalDevice physDev,
                                               SkTArray<VkExtensionProperties>* deviceExtensions,
@@ -317,20 +317,36 @@
     return true;
 }
 
+#define ACQUIRE_VK_INST_PROC_NOCHECK(name, instance) \
+    PFN_vk##name grVk##name = reinterpret_cast<PFN_vk##name>(getInstProc(instance, "vk" #name))
+
+#define ACQUIRE_VK_INST_PROC(name, instance) \
+    PFN_vk##name grVk##name =                                                          \
+        reinterpret_cast<PFN_vk##name>(getInstProc(instance, "vk" #name));             \
+    do {                                                                               \
+        if (grVk##name == nullptr) {                                                   \
+            SkDebugf("Function ptr for vk%s could not be acquired\n", #name);          \
+            if (inst != VK_NULL_HANDLE) {                                              \
+                destroy_instance(getInstProc, inst, debugCallback, hasDebugExtension); \
+            }                                                                          \
+            return false;                                                              \
+        }                                                                              \
+    } while (0)
+
 #define ACQUIRE_VK_PROC_NOCHECK(name, instance, device) \
     PFN_vk##name grVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device))
 
-#define ACQUIRE_VK_PROC(name, instance, device)                                    \
-    PFN_vk##name grVk##name =                                                      \
-            reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device)); \
-    do {                                                                           \
-        if (grVk##name == nullptr) {                                               \
-            SkDebugf("Function ptr for vk%s could not be acquired\n", #name);      \
-            if (device != VK_NULL_HANDLE) {                                        \
-                destroy_instance(getProc, inst, debugCallback, hasDebugExtension); \
-            }                                                                      \
-            return false;                                                          \
-        }                                                                          \
+#define ACQUIRE_VK_PROC(name, instance, device)                                        \
+    PFN_vk##name grVk##name =                                                          \
+            reinterpret_cast<PFN_vk##name>(getProc("vk" #name, instance, device));     \
+    do {                                                                               \
+        if (grVk##name == nullptr) {                                                   \
+            SkDebugf("Function ptr for vk%s could not be acquired\n", #name);          \
+            if (inst != VK_NULL_HANDLE) {                                              \
+                destroy_instance(getInstProc, inst, debugCallback, hasDebugExtension); \
+            }                                                                          \
+            return false;                                                              \
+        }                                                                              \
     } while (0)
 
 #define ACQUIRE_VK_PROC_LOCAL(name, instance, device)                              \
@@ -339,19 +355,19 @@
     do {                                                                           \
         if (grVk##name == nullptr) {                                               \
             SkDebugf("Function ptr for vk%s could not be acquired\n", #name);      \
-            return false;                                                                \
+            return false;                                                          \
         }                                                                          \
     } while (0)
 
-static bool destroy_instance(GrVkGetProc getProc, VkInstance inst,
+static bool destroy_instance(PFN_vkGetInstanceProcAddr getInstProc, VkInstance inst,
                              VkDebugReportCallbackEXT* debugCallback,
                              bool hasDebugExtension) {
     if (hasDebugExtension && *debugCallback != VK_NULL_HANDLE) {
-        ACQUIRE_VK_PROC_LOCAL(DestroyDebugReportCallbackEXT, inst, VK_NULL_HANDLE);
+        ACQUIRE_VK_INST_PROC_LOCAL(DestroyDebugReportCallbackEXT, inst);
         grVkDestroyDebugReportCallbackEXT(inst, *debugCallback, nullptr);
         *debugCallback = VK_NULL_HANDLE;
     }
-    ACQUIRE_VK_PROC_LOCAL(DestroyInstance, inst, VK_NULL_HANDLE);
+    ACQUIRE_VK_INST_PROC_LOCAL(DestroyInstance, inst);
     grVkDestroyInstance(inst, nullptr);
     return true;
 }
@@ -420,7 +436,7 @@
     // If we want to disable any extension features do so here.
 }
 
-bool CreateVkBackendContext(GrVkGetProc getProc,
+bool CreateVkBackendContext(PFN_vkGetInstanceProcAddr getInstProc,
                             GrVkBackendContext* ctx,
                             GrVkExtensions* extensions,
                             VkPhysicalDeviceFeatures2* features,
@@ -430,7 +446,7 @@
                             bool isProtected) {
     VkResult err;
 
-    ACQUIRE_VK_PROC_NOCHECK(EnumerateInstanceVersion, VK_NULL_HANDLE, VK_NULL_HANDLE);
+    ACQUIRE_VK_INST_PROC_NOCHECK(EnumerateInstanceVersion, VK_NULL_HANDLE);
     uint32_t instanceVersion = 0;
     if (!grVkEnumerateInstanceVersion) {
         instanceVersion = VK_MAKE_VERSION(1, 0, 0);
@@ -460,7 +476,7 @@
 
     VkPhysicalDevice physDev;
     VkDevice device;
-    VkInstance inst;
+    VkInstance inst = VK_NULL_HANDLE;
 
     const VkApplicationInfo app_info = {
         VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType
@@ -475,7 +491,7 @@
     SkTArray<VkLayerProperties> instanceLayers;
     SkTArray<VkExtensionProperties> instanceExtensions;
 
-    if (!init_instance_extensions_and_layers(getProc, instanceVersion,
+    if (!init_instance_extensions_and_layers(getInstProc, instanceVersion,
                                              &instanceExtensions,
                                              &instanceLayers)) {
         return false;
@@ -505,13 +521,22 @@
 
     bool hasDebugExtension = false;
 
-    ACQUIRE_VK_PROC(CreateInstance, VK_NULL_HANDLE, VK_NULL_HANDLE);
+    ACQUIRE_VK_INST_PROC(CreateInstance, VK_NULL_HANDLE);
     err = grVkCreateInstance(&instance_create, nullptr, &inst);
     if (err < 0) {
         SkDebugf("vkCreateInstance failed: %d\n", err);
         return false;
     }
 
+    ACQUIRE_VK_INST_PROC(GetDeviceProcAddr, inst);
+    auto getProc = [getInstProc, grVkGetDeviceProcAddr](const char* proc_name,
+                                                        VkInstance instance, VkDevice device) {
+        if (device != VK_NULL_HANDLE) {
+            return grVkGetDeviceProcAddr(device, proc_name);
+        }
+        return getInstProc(instance, proc_name);
+    };
+
 #ifdef SK_ENABLE_VK_LAYERS
     *debugCallback = VK_NULL_HANDLE;
     for (int i = 0; i < instanceExtensionNames.count() && !hasDebugExtension; ++i) {
@@ -551,12 +576,12 @@
     err = grVkEnumeratePhysicalDevices(inst, &gpuCount, nullptr);
     if (err) {
         SkDebugf("vkEnumeratePhysicalDevices failed: %d\n", err);
-        destroy_instance(getProc, inst, debugCallback, hasDebugExtension);
+        destroy_instance(getInstProc, inst, debugCallback, hasDebugExtension);
         return false;
     }
     if (!gpuCount) {
         SkDebugf("vkEnumeratePhysicalDevices returned no supported devices.\n");
-        destroy_instance(getProc, inst, debugCallback, hasDebugExtension);
+        destroy_instance(getInstProc, inst, debugCallback, hasDebugExtension);
         return false;
     }
     // Just returning the first physical device instead of getting the whole array.
@@ -566,7 +591,7 @@
     // VK_INCOMPLETE is returned when the count we provide is less than the total device count.
     if (err && VK_INCOMPLETE != err) {
         SkDebugf("vkEnumeratePhysicalDevices failed: %d\n", err);
-        destroy_instance(getProc, inst, debugCallback, hasDebugExtension);
+        destroy_instance(getInstProc, inst, debugCallback, hasDebugExtension);
         return false;
     }
 
@@ -576,7 +601,7 @@
 
     if (isProtected && physDeviceVersion < VK_MAKE_VERSION(1, 1, 0)) {
         SkDebugf("protected requires vk physical device version 1.1\n");
-        destroy_instance(getProc, inst, debugCallback, hasDebugExtension);
+        destroy_instance(getInstProc, inst, debugCallback, hasDebugExtension);
         return false;
     }
 
@@ -585,7 +610,7 @@
     grVkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, nullptr);
     if (!queueCount) {
         SkDebugf("vkGetPhysicalDeviceQueueFamilyProperties returned no queues.\n");
-        destroy_instance(getProc, inst, debugCallback, hasDebugExtension);
+        destroy_instance(getInstProc, inst, debugCallback, hasDebugExtension);
         return false;
     }
 
@@ -605,7 +630,7 @@
     }
     if (graphicsQueueIndex == queueCount) {
         SkDebugf("Could not find any supported graphics queues.\n");
-        destroy_instance(getProc, inst, debugCallback, hasDebugExtension);
+        destroy_instance(getInstProc, inst, debugCallback, hasDebugExtension);
         return false;
     }
 
@@ -620,7 +645,7 @@
         }
         if (presentQueueIndex == queueCount) {
             SkDebugf("Could not find any supported present queues.\n");
-            destroy_instance(getProc, inst, debugCallback, hasDebugExtension);
+            destroy_instance(getInstProc, inst, debugCallback, hasDebugExtension);
             return false;
         }
         *presentQueueIndexPtr = presentQueueIndex;
@@ -636,7 +661,7 @@
                                            inst, physDev,
                                            &deviceExtensions,
                                            &deviceLayers)) {
-        destroy_instance(getProc, inst, debugCallback, hasDebugExtension);
+        destroy_instance(getInstProc, inst, debugCallback, hasDebugExtension);
         return false;
     }
 
@@ -695,8 +720,8 @@
     if (physDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
         extensions->hasExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 1)) {
         if (!setup_features(getProc, inst, physDev, physDeviceVersion, extensions, features,
-                          isProtected)) {
-            destroy_instance(getProc, inst, debugCallback, hasDebugExtension);
+                            isProtected)) {
+            destroy_instance(getInstProc, inst, debugCallback, hasDebugExtension);
             return false;
         }
 
@@ -758,7 +783,7 @@
     }
     if (err) {
         SkDebugf("CreateDevice failed: %d\n", err);
-        destroy_instance(getProc, inst, debugCallback, hasDebugExtension);
+        destroy_instance(getInstProc, inst, debugCallback, hasDebugExtension);
         return false;
     }
 
diff --git a/tools/gpu/vk/VkTestUtils.h b/tools/gpu/vk/VkTestUtils.h
index ed7d389..300fbfb 100644
--- a/tools/gpu/vk/VkTestUtils.h
+++ b/tools/gpu/vk/VkTestUtils.h
@@ -21,12 +21,12 @@
 struct GrVkBackendContext;
 
 namespace sk_gpu_test {
-    bool LoadVkLibraryAndGetProcAddrFuncs(PFN_vkGetInstanceProcAddr*, PFN_vkGetDeviceProcAddr*);
+    bool LoadVkLibraryAndGetProcAddrFuncs(PFN_vkGetInstanceProcAddr*);
 
     using CanPresentFn = std::function<bool(VkInstance, VkPhysicalDevice,
                                             uint32_t queueFamilyIndex)>;
 
-    bool CreateVkBackendContext(GrVkGetProc getProc,
+    bool CreateVkBackendContext(PFN_vkGetInstanceProcAddr getInstProc,
                                 GrVkBackendContext* ctx,
                                 GrVkExtensions*,
                                 VkPhysicalDeviceFeatures2*,
diff --git a/tools/sk_app/VulkanWindowContext.cpp b/tools/sk_app/VulkanWindowContext.cpp
index d07d5a4..0ba31b5 100644
--- a/tools/sk_app/VulkanWindowContext.cpp
+++ b/tools/sk_app/VulkanWindowContext.cpp
@@ -24,16 +24,17 @@
 #undef CreateSemaphore
 #endif
 
-#define GET_PROC(F) f ## F = (PFN_vk ## F) fGetInstanceProcAddr(fInstance, "vk" #F)
-#define GET_DEV_PROC(F) f ## F = (PFN_vk ## F) fGetDeviceProcAddr(fDevice, "vk" #F)
+#define GET_PROC(F) f ## F = \
+    (PFN_vk ## F) backendContext.fGetProc("vk" #F, fInstance, VK_NULL_HANDLE)
+#define GET_DEV_PROC(F) f ## F = \
+    (PFN_vk ## F) backendContext.fGetProc("vk" #F, VK_NULL_HANDLE, fDevice)
 
 namespace sk_app {
 
 VulkanWindowContext::VulkanWindowContext(const DisplayParams& params,
                                          CreateVkSurfaceFn createVkSurface,
                                          CanPresentFn canPresent,
-                                         PFN_vkGetInstanceProcAddr instProc,
-                                         PFN_vkGetDeviceProcAddr devProc)
+                                         PFN_vkGetInstanceProcAddr instProc)
     : WindowContext(params)
     , fCreateVkSurfaceFn(createVkSurface)
     , fCanPresentFn(canPresent)
@@ -44,7 +45,6 @@
     , fSurfaces(nullptr)
     , fBackbuffers(nullptr) {
     fGetInstanceProcAddr = instProc;
-    fGetDeviceProcAddr = devProc;
     this->initializeContext();
 }
 
@@ -53,19 +53,12 @@
     // any config code here (particularly for msaa)?
 
     PFN_vkGetInstanceProcAddr getInstanceProc = fGetInstanceProcAddr;
-    PFN_vkGetDeviceProcAddr getDeviceProc = fGetDeviceProcAddr;
-    auto getProc = [getInstanceProc, getDeviceProc](const char* proc_name,
-                                                    VkInstance instance, VkDevice device) {
-        if (device != VK_NULL_HANDLE) {
-            return getDeviceProc(device, proc_name);
-        }
-        return getInstanceProc(instance, proc_name);
-    };
     GrVkBackendContext backendContext;
     GrVkExtensions extensions;
     VkPhysicalDeviceFeatures2 features;
-    if (!sk_gpu_test::CreateVkBackendContext(getProc, &backendContext, &extensions, &features,
-                                             &fDebugCallback, &fPresentQueueIndex, fCanPresentFn)) {
+    if (!sk_gpu_test::CreateVkBackendContext(getInstanceProc, &backendContext, &extensions,
+                                             &features, &fDebugCallback, &fPresentQueueIndex,
+                                             fCanPresentFn)) {
         sk_gpu_test::FreeVulkanFeaturesStructs(&features);
         return;
     }
diff --git a/tools/sk_app/VulkanWindowContext.h b/tools/sk_app/VulkanWindowContext.h
index 580dba2..1ba293a 100644
--- a/tools/sk_app/VulkanWindowContext.h
+++ b/tools/sk_app/VulkanWindowContext.h
@@ -48,7 +48,7 @@
     using CanPresentFn = sk_gpu_test::CanPresentFn;
 
     VulkanWindowContext(const DisplayParams&, CreateVkSurfaceFn, CanPresentFn,
-                        PFN_vkGetInstanceProcAddr, PFN_vkGetDeviceProcAddr);
+                        PFN_vkGetInstanceProcAddr);
 
 private:
     void initializeContext();
@@ -73,9 +73,7 @@
     CreateVkSurfaceFn fCreateVkSurfaceFn;
     CanPresentFn      fCanPresentFn;
 
-    // Vulkan GetProcAddr functions
     PFN_vkGetInstanceProcAddr fGetInstanceProcAddr = nullptr;
-    PFN_vkGetDeviceProcAddr fGetDeviceProcAddr = nullptr;
 
     // WSI interface functions
     PFN_vkDestroySurfaceKHR fDestroySurfaceKHR = nullptr;
diff --git a/tools/sk_app/android/VulkanWindowContext_android.cpp b/tools/sk_app/android/VulkanWindowContext_android.cpp
index 90466ad..ebe8915 100644
--- a/tools/sk_app/android/VulkanWindowContext_android.cpp
+++ b/tools/sk_app/android/VulkanWindowContext_android.cpp
@@ -21,8 +21,7 @@
 std::unique_ptr<WindowContext> MakeVulkanForAndroid(ANativeWindow* window,
                                                     const DisplayParams& params) {
     PFN_vkGetInstanceProcAddr instProc;
-    PFN_vkGetDeviceProcAddr devProc;
-    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
+    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc)) {
         return nullptr;
     }
 
@@ -50,7 +49,7 @@
     auto canPresent = [](VkInstance, VkPhysicalDevice, uint32_t) { return true; };
 
     std::unique_ptr<WindowContext> ctx(
-            new VulkanWindowContext(params, createVkSurface, canPresent, instProc, devProc));
+            new VulkanWindowContext(params, createVkSurface, canPresent, instProc));
     if (!ctx->isValid()) {
         return nullptr;
     }
diff --git a/tools/sk_app/unix/VulkanWindowContext_unix.cpp b/tools/sk_app/unix/VulkanWindowContext_unix.cpp
index 34f6640..a7fd09d 100644
--- a/tools/sk_app/unix/VulkanWindowContext_unix.cpp
+++ b/tools/sk_app/unix/VulkanWindowContext_unix.cpp
@@ -25,8 +25,7 @@
 std::unique_ptr<WindowContext> MakeVulkanForXlib(const XlibWindowInfo& info,
                                                  const DisplayParams& displayParams) {
     PFN_vkGetInstanceProcAddr instProc;
-    PFN_vkGetDeviceProcAddr devProc;
-    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
+    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc)) {
         return nullptr;
     }
 
@@ -75,7 +74,7 @@
         return (VK_FALSE != check);
     };
     std::unique_ptr<WindowContext> ctx(
-            new VulkanWindowContext(displayParams, createVkSurface, canPresent, instProc, devProc));
+            new VulkanWindowContext(displayParams, createVkSurface, canPresent, instProc));
     if (!ctx->isValid()) {
         return nullptr;
     }
diff --git a/tools/sk_app/win/VulkanWindowContext_win.cpp b/tools/sk_app/win/VulkanWindowContext_win.cpp
index 909c961..8875888 100644
--- a/tools/sk_app/win/VulkanWindowContext_win.cpp
+++ b/tools/sk_app/win/VulkanWindowContext_win.cpp
@@ -25,8 +25,7 @@
 
 std::unique_ptr<WindowContext> MakeVulkanForWin(HWND hwnd, const DisplayParams& params) {
     PFN_vkGetInstanceProcAddr instProc;
-    PFN_vkGetDeviceProcAddr devProc;
-    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc, &devProc)) {
+    if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc)) {
         return nullptr;
     }
 
@@ -70,7 +69,7 @@
     };
 
     std::unique_ptr<WindowContext> ctx(
-            new VulkanWindowContext(params, createVkSurface, canPresent, instProc, devProc));
+            new VulkanWindowContext(params, createVkSurface, canPresent, instProc));
     if (!ctx->isValid()) {
         return nullptr;
     }