Make vkGetInstanceProcAddr able to get itself
authorCharles Giessen <charles@lunarg.com>
Sun, 6 Feb 2022 01:40:14 +0000 (18:40 -0700)
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>
Sun, 6 Feb 2022 02:04:36 +0000 (19:04 -0700)
There was a regression with 1.3 that meant vkGetInstanceProcAddr wouldn't be
able to query itself if instance was set for 1.3. This commit makes it possible
to query for vkGetInstanceProcAddr with itself no matter the value of instance.

loader/gpa_helper.c
loader/trampoline.c
tests/loader_get_proc_addr_tests.cpp

index 496b1f227ac72e8cfc4d7616a714eca3afd6d88a..602e682f5438f12771c5de67ea2243ea057b8e25 100644 (file)
@@ -273,7 +273,6 @@ void *globalGetProcAddr(const char *name) {
     if (!strcmp(name, "EnumerateInstanceExtensionProperties")) return vkEnumerateInstanceExtensionProperties;
     if (!strcmp(name, "EnumerateInstanceLayerProperties")) return vkEnumerateInstanceLayerProperties;
     if (!strcmp(name, "EnumerateInstanceVersion")) return vkEnumerateInstanceVersion;
-    if (!strcmp(name, "GetInstanceProcAddr")) return vkGetInstanceProcAddr;
 
     return NULL;
 }
index 73b38364ea2d6b0ca8edf81fc93bd83f9fb4f7ea..0e45b1a80dbae773350c83f14285e25523b42472 100644 (file)
@@ -61,6 +61,9 @@
  * instances with a newer version will get the new behavior.
  */
 LOADER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *pName) {
+    // Always should be able to get vkGetInstanceProcAddr if queried, regardless of the value of instance
+    if (!strcmp(pName, "vkGetInstanceProcAddr")) return (PFN_vkVoidFunction)vkGetInstanceProcAddr;
+
     // Get entrypoint addresses that are global (no dispatchable object)
     void *addr = globalGetProcAddr(pName);
     if (addr != VK_NULL_HANDLE) {
index 959c101cf7dcc00de84b1bcedb195857d73605cb..9348c5451d78ff4ad84311cab17ee9fb44ae278c 100644 (file)
@@ -32,17 +32,31 @@ TEST(GetProcAddr, VerifyGetInstanceProcAddr) {
     FrameworkEnvironment env{};
     env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6));
     env.get_test_icd().physical_devices.emplace_back("physical_device_0");
+    {
+        InstWrapper inst{env.vulkan_functions};
+        inst.create_info.set_api_version(VK_API_VERSION_1_1);
+        inst.CheckCreate();
 
-    InstWrapper inst{env.vulkan_functions};
-    inst.create_info.set_api_version(VK_API_VERSION_1_1);
-    inst.CheckCreate();
+        // NOTE: The vulkan_functions are queried using the platform get proc addr from the loader.  So we'll compare
+        //       that to what is returned by asking it what the various Vulkan get proc addr functions are.
+        PFN_vkGetInstanceProcAddr gipa_loader = env.vulkan_functions.vkGetInstanceProcAddr;
+        PFN_vkGetInstanceProcAddr gipa_queried = reinterpret_cast<PFN_vkGetInstanceProcAddr>(
+            env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetInstanceProcAddr"));
+        ASSERT_EQ(gipa_loader, gipa_queried);
+    }
 
-    // NOTE: The vulkan_functions are queried using the platform get proc addr from the loader.  So we'll compare
-    //       that to what is returned by asking it what the various Vulkan get proc addr functions are.
-    PFN_vkGetInstanceProcAddr gipa_loader = env.vulkan_functions.vkGetInstanceProcAddr;
-    PFN_vkGetInstanceProcAddr gipa_queried =
-        reinterpret_cast<PFN_vkGetInstanceProcAddr>(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetInstanceProcAddr"));
-    ASSERT_EQ(gipa_loader, gipa_queried);
+    {
+        InstWrapper inst{env.vulkan_functions};
+        inst.create_info.set_api_version(VK_API_VERSION_1_3);
+        inst.CheckCreate();
+
+        // NOTE: The vulkan_functions are queried using the platform get proc addr from the loader.  So we'll compare
+        //       that to what is returned by asking it what the various Vulkan get proc addr functions are.
+        PFN_vkGetInstanceProcAddr gipa_loader = env.vulkan_functions.vkGetInstanceProcAddr;
+        PFN_vkGetInstanceProcAddr gipa_queried = reinterpret_cast<PFN_vkGetInstanceProcAddr>(
+            env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetInstanceProcAddr"));
+        ASSERT_EQ(gipa_loader, gipa_queried);
+    }
 }
 
 // Verify that the various ways to get vkGetDeviceProcAddr return the same value
@@ -100,8 +114,8 @@ TEST(GetProcAddr, GlobalFunctions) {
         EnumerateInstanceVersion(&api_version);
 
         auto GetInstanceProcAddr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(gipa(NULL, "vkGetInstanceProcAddr"));
-        handle_assert_has_value(GetInstanceProcAddr);
-        GetInstanceProcAddr(NULL, "vkGetInstanceProcAddr");
+        ASSERT_EQ(GetInstanceProcAddr,
+                  reinterpret_cast<PFN_vkGetInstanceProcAddr>(GetInstanceProcAddr(NULL, "vkGetInstanceProcAddr")));
 
         auto CreateInstance = reinterpret_cast<PFN_vkCreateInstance>(gipa(NULL, "vkCreateInstance"));
         handle_assert_has_value(CreateInstance);
@@ -131,7 +145,8 @@ TEST(GetProcAddr, GlobalFunctions) {
 
         auto GetInstanceProcAddr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(gipa(inst, "vkGetInstanceProcAddr"));
         handle_assert_has_value(GetInstanceProcAddr);
-        GetInstanceProcAddr(NULL, "vkGetInstanceProcAddr");
+        ASSERT_EQ(GetInstanceProcAddr,
+                  reinterpret_cast<PFN_vkGetInstanceProcAddr>(GetInstanceProcAddr(inst, "vkGetInstanceProcAddr")));
 
         auto CreateInstance = reinterpret_cast<PFN_vkCreateInstance>(gipa(inst, "vkCreateInstance"));
         handle_assert_has_value(CreateInstance);
@@ -157,8 +172,11 @@ TEST(GetProcAddr, GlobalFunctions) {
         handle_assert_null(CreateInstance);
 
         auto GetInstanceProcAddr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(gipa(inst, "vkGetInstanceProcAddr"));
-        handle_assert_null(GetInstanceProcAddr);
-
+        handle_assert_equal(env.vulkan_functions.vkGetInstanceProcAddr, GetInstanceProcAddr);
+        ASSERT_EQ(GetInstanceProcAddr,
+                  reinterpret_cast<PFN_vkGetInstanceProcAddr>(GetInstanceProcAddr(inst, "vkGetInstanceProcAddr")));
+        ASSERT_EQ(GetInstanceProcAddr,
+                  reinterpret_cast<PFN_vkGetInstanceProcAddr>(GetInstanceProcAddr(NULL, "vkGetInstanceProcAddr")));
         // get a non pre-instance function pointer
         auto EnumeratePhysicalDevices = reinterpret_cast<PFN_vkGetInstanceProcAddr>(gipa(inst, "vkEnumeratePhysicalDevices"));
         handle_assert_has_value(EnumeratePhysicalDevices);