Add a test to verify that VK_INSTANCE_LAYERS behaves properly
authorMark Young <marky@lunarg.com>
Tue, 15 Feb 2022 17:42:06 +0000 (10:42 -0700)
committerMark Young <marky@lunarg.com>
Tue, 15 Feb 2022 18:24:56 +0000 (11:24 -0700)
tests/framework/layer/test_layer.cpp
tests/loader_layer_tests.cpp

index 37cd4e193ffd7a2a74c94933fd0f96961cfb2974..1efa6a4bad0ebb6ef73f6a2b42175a248b30c093 100644 (file)
@@ -104,6 +104,7 @@ VkLayerDeviceCreateInfo* get_chain_info(const VkDeviceCreateInfo* pCreateInfo, V
 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceLayerProperties(uint32_t* pPropertyCount, VkLayerProperties* pProperties) {
     return VK_SUCCESS;
 }
+
 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pPropertyCount,
                                                                            VkExtensionProperties* pProperties) {
     if (pLayerName && string_eq(pLayerName, layer.unique_name.c_str())) {
@@ -117,6 +118,7 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceLayerProperties(VkPhysicalD
                                                                      VkLayerProperties* pProperties) {
     return VK_SUCCESS;
 }
+
 VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName,
                                                                          uint32_t* pPropertyCount,
                                                                          VkExtensionProperties* pProperties) {
@@ -172,6 +174,7 @@ VKAPI_ATTR VkResult VKAPI_CALL test_override_vkCreateInstance(const VkInstanceCr
                                                      const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) {
     return VK_ERROR_INVALID_SHADER_NV;
 }
+
 VKAPI_ATTR void VKAPI_CALL test_vkDestroyInstance(VkInstance instance, const VkAllocationCallbacks* pAllocator) {
     layer.instance_dispatch_table.DestroyInstance(instance, pAllocator);
 }
@@ -330,7 +333,7 @@ FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_layer_GetInstance
     return get_instance_func(instance, pName);
 }
 FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_override_vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
-    if (string_eq(pName, "vkCreateInstance")) return TO_VOID_PFN(test_override_vkCreateInstance);
+    if (string_eq(pName, "vkCreateInstance")) return to_vkVoidFunction(test_override_vkCreateInstance);
     return get_instance_func(instance, pName);
 }
 #endif
index 4c0aa1b458420b38cce41a54df756f52458cbd17..d083b57cfcc67ab3b46e4678dec6a90c6a341193 100644 (file)
@@ -2541,3 +2541,98 @@ TEST(TestLayers, ImplicitLayerPre10APIVersion) {
         ASSERT_EQ(0, count);
     }
 }
+
+// Verify that VK_INSTANCE_LAYERS work.  To test this, make sure that an explicit layer does not affect an instance until
+// it is set with VK_INSTANCE_LAYERS
+TEST(TestLayers, EnvironEnableExplicitLayer) {
+    FrameworkEnvironment env;
+    env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_6, VK_MAKE_API_VERSION(0, 1, 2, 0)));
+    env.get_test_icd().icd_api_version = VK_MAKE_API_VERSION(0, 1, 2, 0);
+    VkPhysicalDeviceProperties properties{};
+    properties.apiVersion = VK_MAKE_API_VERSION(0, 1, 2, 0);
+    env.get_test_icd().add_physical_device({});
+    env.get_test_icd().physical_devices.back().set_properties(properties);
+
+    const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
+    env.add_explicit_layer(
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}
+                .set_name(explicit_layer_name)
+                .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
+                .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
+                .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})
+                .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})),
+        "explicit_wrap_layer_both_dev.json");
+
+    // First, test an instance/device without the layer forced on.  The extensions shouldn't be present and
+    // the function pointers should be NULL.
+    InstWrapper inst1{env.vulkan_functions};
+    inst1.CheckCreate();
+    VkPhysicalDevice phys_dev1 = inst1.GetPhysDev();
+
+    // Make sure the extensions in the layer aren't present
+    uint32_t extension_count = 40;
+    std::array<VkExtensionProperties, 40> extensions;
+    EXPECT_EQ(VK_SUCCESS,
+              env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev1, nullptr, &extension_count, extensions.data()));
+    for (uint32_t ext = 0; ext < extension_count; ++ext) {
+        if (string_eq(extensions[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME) ||
+            string_eq(extensions[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)) {
+            ASSERT_EQ(false, true);
+        }
+    }
+
+    // Create a device and query the function pointers
+    DeviceWrapper dev1{inst1};
+    dev1.create_info.add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
+    dev1.CheckCreate(phys_dev1);
+    PFN_vkTrimCommandPoolKHR pfn_TrimCommandPoolBefore =
+        reinterpret_cast<PFN_vkTrimCommandPoolKHR>(dev1->vkGetDeviceProcAddr(dev1.dev, "vkTrimCommandPoolKHR"));
+    PFN_vkGetSwapchainStatusKHR pfn_GetSwapchainStatusBefore =
+        reinterpret_cast<PFN_vkGetSwapchainStatusKHR>(dev1->vkGetDeviceProcAddr(dev1.dev, "vkGetSwapchainStatusKHR"));
+    handle_assert_null(pfn_TrimCommandPoolBefore);
+    handle_assert_null(pfn_GetSwapchainStatusBefore);
+
+    // Now setup the instance layer
+    set_env_var("VK_INSTANCE_LAYERS", explicit_layer_name);
+
+    // Now, test an instance/device with the layer forced on.  The extensions should be present and
+    // the function pointers should be valid.
+    InstWrapper inst2{env.vulkan_functions};
+    inst2.CheckCreate();
+    VkPhysicalDevice phys_dev2 = inst2.GetPhysDev();
+
+    // Make sure the extensions in the layer aren't present
+    extension_count = 40;
+    EXPECT_EQ(VK_SUCCESS,
+              env.vulkan_functions.vkEnumerateDeviceExtensionProperties(phys_dev2, nullptr, &extension_count, extensions.data()));
+    bool maint_found = false;
+    bool pres_found = false;
+    for (uint32_t ext = 0; ext < extension_count; ++ext) {
+        if (string_eq(extensions[ext].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
+            maint_found = true;
+        }
+        if (string_eq(extensions[ext].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)) {
+            pres_found = true;
+        }
+    }
+    ASSERT_EQ(true, maint_found);
+    ASSERT_EQ(true, pres_found);
+
+    DeviceWrapper dev2{inst2};
+    dev2.create_info.add_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME)
+        .add_extension(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)
+        .add_device_queue(DeviceQueueCreateInfo{}.add_priority(0.0f));
+    dev2.CheckCreate(phys_dev2);
+
+    PFN_vkTrimCommandPoolKHR pfn_TrimCommandPoolAfter =
+        reinterpret_cast<PFN_vkTrimCommandPoolKHR>(dev2->vkGetDeviceProcAddr(dev2.dev, "vkTrimCommandPoolKHR"));
+    PFN_vkGetSwapchainStatusKHR pfn_GetSwapchainStatusAfter =
+        reinterpret_cast<PFN_vkGetSwapchainStatusKHR>(dev2->vkGetDeviceProcAddr(dev2.dev, "vkGetSwapchainStatusKHR"));
+    handle_assert_has_value(pfn_TrimCommandPoolAfter);
+    handle_assert_has_value(pfn_GetSwapchainStatusAfter);
+
+    ASSERT_EQ(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, pfn_GetSwapchainStatusAfter(dev2.dev, VK_NULL_HANDLE));
+
+    remove_env_var("VK_INSTANCE_LAYERS");
+}