Add layer tests for instance extension support
authorMark Young <marky@lunarg.com>
Mon, 3 Jan 2022 22:16:45 +0000 (15:16 -0700)
committerMark Young <marky@lunarg.com>
Fri, 7 Jan 2022 23:56:38 +0000 (16:56 -0700)
Verify that the loader properly handles instance extensions defined
in a layer (both implicit and explicit).

tests/framework/layer/CMakeLists.txt
tests/framework/layer/wrap_objects.cpp
tests/loader_layer_tests.cpp

index d1274a76aecfc204ad228ec1157a9c754cf0cb60..d5af270a19608f46486c1f9d03d1e9fd1f6580ed 100644 (file)
@@ -53,9 +53,20 @@ target_link_libraries(test_layer_export_version_2 PRIVATE test_layer_deps)
 target_compile_definitions(test_layer_export_version_2 PRIVATE
     ${TEST_LAYER_VERSION_0_EXPORTS} ${TEST_LAYER_VERSION_1_EXPORTS} ${TEST_LAYER_VERSION_2_EXPORTS} )
 
-set(WRAP_LAYER_VERSION_1_EXPORTS TEST_LAYER_EXPORT_MAINT_1=1)
-set(WRAP_LAYER_VERSION_2_EXPORTS TEST_LAYER_EXPORT_PRESENT_IMAGE=1)
-set(WRAP_LAYER_VERSION_3_EXPORTS TEST_LAYER_EXPORT_MAINT_1=1 TEST_LAYER_EXPORT_PRESENT_IMAGE=1)
+set(WRAP_LAYER_VERSION_1_EXPORTS
+        TEST_LAYER_EXPORT_DIRECT_DISP=1
+        TEST_LAYER_EXPORT_MAINT_1=1
+    )
+set(WRAP_LAYER_VERSION_2_EXPORTS
+        TEST_LAYER_EXPORT_DISP_SURF_COUNT=1
+        TEST_LAYER_EXPORT_PRESENT_IMAGE=1
+    )
+set(WRAP_LAYER_VERSION_3_EXPORTS
+        TEST_LAYER_EXPORT_DIRECT_DISP=1
+        TEST_LAYER_EXPORT_DISP_SURF_COUNT=1
+        TEST_LAYER_EXPORT_MAINT_1=1
+        TEST_LAYER_EXPORT_PRESENT_IMAGE=1
+    )
 
 add_library(test_layer_wrap_objects SHARED wrap_objects)
 target_link_libraries(test_layer_wrap_objects PRIVATE test_layer_deps)
index 76f4fd0fb9ff6ebff14a604bdc563555c571bff4..3be868d39bfa6eb6b968c68e85d20e1cb387c3c4 100644 (file)
 #include "loader/generated/vk_dispatch_table_helper.h"
 #include "loader/vk_loader_layer.h"
 
-// Export full support of VK_KHR_maintenance1 extension
+// Export full support of instance extension VK_EXT_direct_mode_display extension
+#ifndef TEST_LAYER_EXPORT_DIRECT_DISP
+#define TEST_LAYER_EXPORT_DIRECT_DISP 0
+#endif
+
+// Export full support of instance extension VK_EXT_display_surface_counter extension
+#ifndef TEST_LAYER_EXPORT_DISP_SURF_COUNT
+#define TEST_LAYER_EXPORT_DISP_SURF_COUNT 0
+#endif
+
+// Export full support of device extension VK_KHR_maintenance1 extension
 #ifndef TEST_LAYER_EXPORT_MAINT_1
 #define TEST_LAYER_EXPORT_MAINT_1 0
 #endif
 
-// Export full support of VK_KHR_shared_presentable_image extension
+// Export full support of device extension VK_KHR_shared_presentable_image extension
 #ifndef TEST_LAYER_EXPORT_PRESENT_IMAGE
 #define TEST_LAYER_EXPORT_PRESENT_IMAGE 0
 #endif
@@ -62,8 +72,11 @@ struct wrapped_inst_obj {
     struct wrapped_phys_dev_obj *ptr_phys_devs;  // any enumerated phys devs
     VkInstance obj;
     bool layer_is_implicit;
+    bool direct_display_enabled;
+    bool display_surf_counter_enabled;
 };
 
+
 struct wrapped_dev_obj {
     VkLayerDispatchTable *loader_disp;
     VkLayerDispatchTable disp;
@@ -171,6 +184,20 @@ VKAPI_ATTR VkResult VKAPI_CALL wrap_vkCreateInstance(const VkInstanceCreateInfo
     if (!found) {
         inst->layer_is_implicit = true;
     }
+
+    for (uint32_t ext = 0; ext < pCreateInfo->enabledExtensionCount; ++ext) {
+        if (!strcmp(pCreateInfo->ppEnabledExtensionNames[ext], VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)) {
+#if TEST_LAYER_EXPORT_DIRECT_DISP
+            inst->direct_display_enabled = true;
+#endif
+        }
+        if (!strcmp(pCreateInfo->ppEnabledExtensionNames[ext], VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) {
+#if TEST_LAYER_EXPORT_DISP_SURF_COUNT
+            inst->display_surf_counter_enabled = true;
+#endif
+        }
+    }
+
     return result;
 }
 
@@ -485,6 +512,17 @@ VKAPI_ATTR void VKAPI_CALL wrap_vkDestroyDevice(VkDevice device, const VkAllocat
     delete dev;
 }
 
+// Fake instance extension support
+VKAPI_ATTR VkResult VKAPI_CALL wrap_vkReleaseDisplayEXT(
+    VkPhysicalDevice                            physicalDevice,
+    VkDisplayKHR                                display) { return VK_SUCCESS; }
+
+VKAPI_ATTR VkResult VKAPI_CALL wrap_vkGetPhysicalDeviceSurfaceCapabilities2EXT(
+    VkPhysicalDevice                            physicalDevice,
+    VkSurfaceKHR                                surface,
+    VkSurfaceCapabilities2EXT*                  pSurfaceCapabilities) { return VK_SUCCESS; }
+
+// Fake device extension support
 VKAPI_ATTR void VKAPI_CALL wrap_vkTrimCommandPoolKHR(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags) {}
 
 VKAPI_ATTR VkResult VKAPI_CALL wrap_vkGetSwapchainStatusKHR(VkDevice device, VkSwapchainKHR swapchain) { return VK_SUCCESS; }
@@ -523,7 +561,7 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL wrap_vkGetDeviceProcAddr(VkDevice devic
     return dev->pfn_get_dev_proc_addr(dev->obj, funcName);
 }
 
-PFN_vkVoidFunction layer_intercept_instance_proc(const char *name) {
+PFN_vkVoidFunction layer_intercept_instance_proc(wrapped_inst_obj *inst, const char *name) {
     if (!name || name[0] != 'v' || name[1] != 'k') return NULL;
 
     name += 2;
@@ -585,6 +623,10 @@ PFN_vkVoidFunction layer_intercept_instance_proc(const char *name) {
 #endif  // VK_USE_PLATFORM_SCREEN_QNX
     if (!strcmp(name, "DestroySurfaceKHR")) return (PFN_vkVoidFunction)wrap_vkDestroySurfaceKHR;
 
+    if (inst->direct_display_enabled && !strcmp(name, "ReleaseDisplayEXT")) return (PFN_vkVoidFunction)wrap_vkReleaseDisplayEXT;
+    if (inst->display_surf_counter_enabled && !strcmp(name, "GetPhysicalDeviceSurfaceCapabilities2EXT"))
+        return (PFN_vkVoidFunction)wrap_vkGetPhysicalDeviceSurfaceCapabilities2EXT;
+
     return NULL;
 }
 
@@ -598,11 +640,12 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL wrap_vkGetInstanceProcAddr(VkInstance i
         return NULL;
     }
 
-    addr = layer_intercept_instance_proc(funcName);
-    if (addr) return addr;
-
     wrapped_inst_obj *inst;
     (void)unwrap_instance(instance, &inst);
+
+    addr = layer_intercept_instance_proc(inst, funcName);
+    if (addr) return addr;
+
     VkLayerInstanceDispatchTable *pTable = &inst->layer_disp;
 
     if (pTable->GetInstanceProcAddr == NULL) return NULL;
index fe1c6525e824f9b38591e86152b987dbfebe9bf0..46457a05ea3d8300417e1d03d23262cfa763ea15 100644 (file)
@@ -366,6 +366,522 @@ TEST_F(ExplicitLayers, WrapObjects) {
     }
 }
 
+TEST_F(LayerExtensions, ImplicitNoAdditionalInstanceExtension) {
+    auto& driver = env->get_test_icd();
+    MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
+
+    driver.physical_devices.emplace_back("physical_device_0");
+    driver.physical_devices.back().queue_family_properties.push_back(family_props);
+
+    const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
+    const char* enable_env_var = "ENABLE_ME";
+    const char* disable_env_var = "DISABLE_ME";
+
+    env->add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
+                                                          .set_name(implicit_layer_name)
+                                                          .set_lib_path(TEST_LAYER_WRAP_OBJECTS)
+                                                          .set_disable_environment(disable_env_var)
+                                                          .set_enable_environment(enable_env_var)),
+                            "implicit_wrap_layer_no_ext.json");
+
+    uint32_t count = 0;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
+    ASSERT_EQ(count, 1);
+
+    // // set enable env-var, layer should load
+    set_env_var(enable_env_var, "1");
+    CheckLogForLayerString(*env, implicit_layer_name, true);
+
+    uint32_t extension_count = 0;
+    std::vector<VkExtensionProperties> extension_props;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
+    if (extension_count > 0) {
+        extension_props.resize(extension_count);
+        ASSERT_EQ(VK_SUCCESS,
+                  env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_props.data()));
+
+        // Make sure the extensions that are implemented only in the test layers is not present.
+        for (uint32_t ext = 0; ext < extension_count; ++ext) {
+            ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
+            ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
+        }
+    }
+
+    InstWrapper inst{env->vulkan_functions};
+    inst.CheckCreate();
+
+    // Make sure all the function pointers are NULL as well
+    ASSERT_EQ(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkReleaseDisplayEXT"));
+    ASSERT_EQ(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
+
+    remove_env_var(enable_env_var);
+}
+
+TEST_F(LayerExtensions, ImplicitDirDispModeInstanceExtension) {
+    auto& driver = env->get_test_icd();
+    MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
+
+    driver.physical_devices.emplace_back("physical_device_0");
+    driver.physical_devices.back().queue_family_properties.push_back(family_props);
+
+    const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
+    const char* enable_env_var = "ENABLE_ME";
+    const char* disable_env_var = "DISABLE_ME";
+
+    env->add_implicit_layer(
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}
+                .set_name(implicit_layer_name)
+                .set_lib_path(TEST_LAYER_WRAP_OBJECTS_1)
+                .set_disable_environment(disable_env_var)
+                .set_enable_environment(enable_env_var)
+                .add_instance_extension({VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 1, {"vkReleaseDisplayEXT"}})),
+        "implicit_wrap_layer_dir_disp_mode.json");
+
+    uint32_t count = 0;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
+    ASSERT_EQ(count, 1);
+
+    // // set enable env-var, layer should load
+    set_env_var(enable_env_var, "1");
+    CheckLogForLayerString(*env, implicit_layer_name, true);
+
+    uint32_t extension_count = 0;
+    std::vector<VkExtensionProperties> extension_props;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
+    ASSERT_GE(extension_count, 1);
+    extension_props.resize(extension_count);
+    ASSERT_EQ(VK_SUCCESS,
+              env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_props.data()));
+
+    // Make sure the extensions that are implemented only in the test layers is not present.
+    bool found = false;
+    for (uint32_t ext = 0; ext < extension_count; ++ext) {
+        if (!strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)) {
+            found = true;
+        }
+        ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
+    }
+    ASSERT_EQ(true, found);
+
+    InstWrapper inst{env->vulkan_functions};
+    inst.create_info.add_extension(VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME);
+    inst.CheckCreate();
+
+    // Make sure only the appropriate function pointers are NULL as well
+    ASSERT_NE(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkReleaseDisplayEXT"));
+    ASSERT_EQ(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
+
+    remove_env_var(enable_env_var);
+}
+
+TEST_F(LayerExtensions, ImplicitDispSurfCountInstanceExtension) {
+    auto& driver = env->get_test_icd();
+    MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
+
+    driver.physical_devices.emplace_back("physical_device_0");
+    driver.physical_devices.back().queue_family_properties.push_back(family_props);
+
+    const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
+    const char* enable_env_var = "ENABLE_ME";
+    const char* disable_env_var = "DISABLE_ME";
+
+    env->add_implicit_layer(
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}
+                .set_name(implicit_layer_name)
+                .set_lib_path(TEST_LAYER_WRAP_OBJECTS_2)
+                .set_disable_environment(disable_env_var)
+                .set_enable_environment(enable_env_var)
+                .add_instance_extension(
+                    {VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, 1, {"vkGetPhysicalDeviceSurfaceCapabilities2EXT"}})),
+        "implicit_wrap_layer_disp_surf_count.json");
+
+    uint32_t count = 0;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
+    ASSERT_EQ(count, 1);
+
+    // // set enable env-var, layer should load
+    set_env_var(enable_env_var, "1");
+    CheckLogForLayerString(*env, implicit_layer_name, true);
+
+    uint32_t extension_count = 0;
+    std::vector<VkExtensionProperties> extension_props;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
+    ASSERT_GE(extension_count, 1);
+    extension_props.resize(extension_count);
+    ASSERT_EQ(VK_SUCCESS,
+              env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_props.data()));
+
+    // Make sure the extensions that are implemented only in the test layers is not present.
+    bool found = false;
+    for (uint32_t ext = 0; ext < extension_count; ++ext) {
+        if (!strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) {
+            found = true;
+        }
+        ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
+    }
+    ASSERT_EQ(true, found);
+
+    InstWrapper inst{env->vulkan_functions};
+    inst.create_info.add_extension(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME);
+    inst.CheckCreate();
+
+    // Make sure only the appropriate function pointers are NULL as well
+    ASSERT_EQ(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkReleaseDisplayEXT"));
+    ASSERT_NE(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
+
+    remove_env_var(enable_env_var);
+}
+
+TEST_F(LayerExtensions, ImplicitBothInstanceExtensions) {
+    auto& driver = env->get_test_icd();
+    MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
+
+    driver.physical_devices.emplace_back("physical_device_0");
+    driver.physical_devices.back().queue_family_properties.push_back(family_props);
+
+    const char* implicit_layer_name = "VK_LAYER_LUNARG_wrap_objects";
+    const char* enable_env_var = "ENABLE_ME";
+    const char* disable_env_var = "DISABLE_ME";
+
+    env->add_implicit_layer(
+        ManifestLayer{}.add_layer(
+            ManifestLayer::LayerDescription{}
+                .set_name(implicit_layer_name)
+                .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
+                .set_disable_environment(disable_env_var)
+                .set_enable_environment(enable_env_var)
+                .add_instance_extension({VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 1, {"vkReleaseDisplayEXT"}})
+                .add_instance_extension(
+                    {VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, 1, {"vkGetPhysicalDeviceSurfaceCapabilities2EXT"}})),
+        "implicit_wrap_layer_both_inst.json");
+
+    uint32_t count = 0;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
+    ASSERT_EQ(count, 1);
+
+    // // set enable env-var, layer should load
+    set_env_var(enable_env_var, "1");
+    CheckLogForLayerString(*env, implicit_layer_name, true);
+
+    uint32_t extension_count = 0;
+    std::vector<VkExtensionProperties> extension_props;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
+    ASSERT_GE(extension_count, 2);
+    extension_props.resize(extension_count);
+    ASSERT_EQ(VK_SUCCESS,
+              env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_props.data()));
+
+    // Make sure the extensions that are implemented only in the test layers is not present.
+    bool found[2] = {false, false};
+    for (uint32_t ext = 0; ext < extension_count; ++ext) {
+        if (!strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) {
+            found[0] = true;
+        }
+        if (!strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)) {
+            found[1] = true;
+        }
+    }
+    for (uint32_t ext = 0; ext < 2; ++ext) {
+        ASSERT_EQ(true, found[ext]);
+    }
+
+    InstWrapper inst{env->vulkan_functions};
+    inst.create_info.add_extension(VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)
+        .add_extension(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME);
+    inst.CheckCreate();
+
+    // Make sure only the appropriate function pointers are NULL as well
+    ASSERT_NE(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkReleaseDisplayEXT"));
+    ASSERT_NE(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
+
+    remove_env_var(enable_env_var);
+}
+
+TEST_F(LayerExtensions, ExplicitNoAdditionalInstanceExtension) {
+    auto& driver = env->get_test_icd();
+    MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
+
+    driver.physical_devices.emplace_back("physical_device_0");
+    driver.physical_devices.back().queue_family_properties.push_back(family_props);
+
+    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)),
+        "explicit_wrap_layer_no_ext.json");
+
+    uint32_t count = 0;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
+    ASSERT_EQ(count, 1);
+
+    uint32_t extension_count = 0;
+    std::vector<VkExtensionProperties> extension_props;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
+    if (extension_count > 0) {
+        extension_props.resize(extension_count);
+        ASSERT_EQ(VK_SUCCESS,
+                  env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_props.data()));
+
+        // Make sure the extensions are not present
+        for (uint32_t ext = 0; ext < extension_count; ++ext) {
+            ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
+            ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
+        }
+    }
+
+    // Now query by layer name.
+    extension_count = 0;
+    extension_props.clear();
+    ASSERT_EQ(VK_SUCCESS,
+              env->vulkan_functions.vkEnumerateInstanceExtensionProperties(explicit_layer_name, &extension_count, nullptr));
+    if (extension_count > 0) {
+        extension_props.resize(extension_count);
+        ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties(explicit_layer_name, &extension_count,
+                                                                                           extension_props.data()));
+
+        // Make sure the extensions still aren't present in this layer
+        for (uint32_t ext = 0; ext < extension_count; ++ext) {
+            ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
+            ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
+        }
+    }
+
+    InstWrapper inst{env->vulkan_functions};
+    inst.CheckCreate();
+
+    // Make sure all the function pointers are NULL as well
+    ASSERT_EQ(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkReleaseDisplayEXT"));
+    ASSERT_EQ(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
+}
+
+TEST_F(LayerExtensions, ExplicitDirDispModeInstanceExtension) {
+    auto& driver = env->get_test_icd();
+    MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
+
+    driver.physical_devices.emplace_back("physical_device_0");
+    driver.physical_devices.back().queue_family_properties.push_back(family_props);
+
+    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_1)
+                .add_instance_extension({VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 1, {"vkReleaseDisplayEXT"}})),
+        "explicit_wrap_layer_dir_disp_mode.json");
+
+    uint32_t count = 0;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
+    ASSERT_EQ(count, 1);
+
+    uint32_t extension_count = 0;
+    std::vector<VkExtensionProperties> extension_props;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
+    if (extension_count > 0) {
+        extension_props.resize(extension_count);
+        ASSERT_EQ(VK_SUCCESS,
+                  env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_props.data()));
+
+        // Make sure the extensions are not present
+        for (uint32_t ext = 0; ext < extension_count; ++ext) {
+            ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
+            ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
+        }
+    }
+
+    // Now query by layer name.
+    extension_count = 0;
+    extension_props.clear();
+    ASSERT_EQ(VK_SUCCESS,
+              env->vulkan_functions.vkEnumerateInstanceExtensionProperties(explicit_layer_name, &extension_count, nullptr));
+    ASSERT_GE(extension_count, 1);
+    extension_props.resize(extension_count);
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties(explicit_layer_name, &extension_count,
+                                                                                       extension_props.data()));
+
+    // Make sure the extensions still aren't present in this layer
+    bool found = false;
+    for (uint32_t ext = 0; ext < extension_count; ++ext) {
+        if (!strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)) {
+            found = true;
+        }
+        ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
+    }
+    ASSERT_EQ(true, found);
+
+    InstWrapper inst1{env->vulkan_functions};
+    inst1.create_info.add_extension(VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME);
+    inst1.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT);
+
+    // Make sure only the appropriate function pointers are NULL as well
+    ASSERT_EQ(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst1.inst, "vkReleaseDisplayEXT"));
+    ASSERT_EQ(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst1.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
+
+    InstWrapper inst2{env->vulkan_functions};
+    inst2.create_info.add_layer(explicit_layer_name).add_extension(VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME);
+    inst2.CheckCreate();
+
+    // Make sure only the appropriate function pointers are NULL as well
+    ASSERT_NE(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkReleaseDisplayEXT"));
+    ASSERT_EQ(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
+}
+
+TEST_F(LayerExtensions, ExplicitDispSurfCountInstanceExtension) {
+    auto& driver = env->get_test_icd();
+    MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
+
+    driver.physical_devices.emplace_back("physical_device_0");
+    driver.physical_devices.back().queue_family_properties.push_back(family_props);
+
+    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_2)
+                .add_instance_extension(
+                    {VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, 1, {"vkGetPhysicalDeviceSurfaceCapabilities2EXT"}})),
+        "explicit_wrap_layer_disp_surf_count.json");
+
+    uint32_t count = 0;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
+    ASSERT_EQ(count, 1);
+
+    uint32_t extension_count = 0;
+    std::vector<VkExtensionProperties> extension_props;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
+    if (extension_count > 0) {
+        extension_props.resize(extension_count);
+        ASSERT_EQ(VK_SUCCESS,
+                  env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_props.data()));
+
+        // Make sure the extensions are not present
+        for (uint32_t ext = 0; ext < extension_count; ++ext) {
+            ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
+            ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
+        }
+    }
+
+    // Now query by layer name.
+    extension_count = 0;
+    extension_props.clear();
+    ASSERT_EQ(VK_SUCCESS,
+              env->vulkan_functions.vkEnumerateInstanceExtensionProperties(explicit_layer_name, &extension_count, nullptr));
+    ASSERT_GE(extension_count, 1);
+    extension_props.resize(extension_count);
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties(explicit_layer_name, &extension_count,
+                                                                                       extension_props.data()));
+
+    // Make sure the extensions still aren't present in this layer
+    bool found = false;
+    for (uint32_t ext = 0; ext < extension_count; ++ext) {
+        if (!strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) {
+            found = true;
+        }
+        ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
+    }
+    ASSERT_EQ(true, found);
+
+    InstWrapper inst1{env->vulkan_functions};
+    inst1.create_info.add_extension(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME);
+    inst1.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT);
+
+    // Make sure only the appropriate function pointers are NULL as well
+    ASSERT_EQ(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst1.inst, "vkReleaseDisplayEXT"));
+    ASSERT_EQ(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst1.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
+
+    InstWrapper inst2{env->vulkan_functions};
+    inst2.create_info.add_layer(explicit_layer_name).add_extension(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME);
+    inst2.CheckCreate();
+
+    // Make sure only the appropriate function pointers are NULL as well
+    ASSERT_EQ(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkReleaseDisplayEXT"));
+    ASSERT_NE(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
+}
+
+TEST_F(LayerExtensions, ExplicitBothInstanceExtensions) {
+    auto& driver = env->get_test_icd();
+    MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
+
+    driver.physical_devices.emplace_back("physical_device_0");
+    driver.physical_devices.back().queue_family_properties.push_back(family_props);
+
+    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)
+                .add_instance_extension({VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME, 1, {"vkReleaseDisplayEXT"}})
+                .add_instance_extension(
+                    {VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME, 1, {"vkGetPhysicalDeviceSurfaceCapabilities2EXT"}})),
+        "explicit_wrap_layer_both_inst.json");
+
+    uint32_t count = 0;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
+    ASSERT_EQ(count, 1);
+
+    uint32_t extension_count = 0;
+    std::vector<VkExtensionProperties> extension_props;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr));
+    if (extension_count > 0) {
+        extension_props.resize(extension_count);
+        ASSERT_EQ(VK_SUCCESS,
+                  env->vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extension_props.data()));
+
+        // Make sure the extensions are not present
+        for (uint32_t ext = 0; ext < extension_count; ++ext) {
+            ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME));
+            ASSERT_NE(0, strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME));
+        }
+    }
+
+    // Now query by layer name.
+    extension_count = 0;
+    extension_props.clear();
+    ASSERT_EQ(VK_SUCCESS,
+              env->vulkan_functions.vkEnumerateInstanceExtensionProperties(explicit_layer_name, &extension_count, nullptr));
+    ASSERT_GE(extension_count, 2);
+    extension_props.resize(extension_count);
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceExtensionProperties(explicit_layer_name, &extension_count,
+                                                                                       extension_props.data()));
+
+    // Make sure the extensions still aren't present in this layer
+    bool found[2] = {false, false};
+    for (uint32_t ext = 0; ext < extension_count; ++ext) {
+        if (!strcmp(extension_props[ext].extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)) {
+            found[0] = true;
+        }
+        if (!strcmp(extension_props[ext].extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) {
+            found[1] = true;
+        }
+    }
+    for (uint32_t ext = 0; ext < 2; ++ext) {
+        ASSERT_EQ(true, found[ext]);
+    }
+
+    InstWrapper inst1{env->vulkan_functions};
+    inst1.create_info.add_extension(VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)
+        .add_extension(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME);
+    inst1.CheckCreate(VK_ERROR_EXTENSION_NOT_PRESENT);
+
+    // Make sure only the appropriate function pointers are NULL as well
+    ASSERT_EQ(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst1.inst, "vkReleaseDisplayEXT"));
+    ASSERT_EQ(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst1.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
+
+    InstWrapper inst2{env->vulkan_functions};
+    inst2.create_info.add_layer(explicit_layer_name)
+        .add_extension(VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)
+        .add_extension(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME);
+    inst2.CheckCreate();
+
+    // Make sure only the appropriate function pointers are NULL as well
+    ASSERT_NE(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkReleaseDisplayEXT"));
+    ASSERT_NE(nullptr, env->vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"));
+}
+
 TEST_F(LayerExtensions, ImplicitNoAdditionalDeviceExtension) {
     auto& driver = env->get_test_icd();
     MockQueueFamilyProperties family_props{{VK_QUEUE_GRAPHICS_BIT, 1, 0, {1, 1, 1}}, true};
@@ -498,7 +1014,7 @@ TEST_F(LayerExtensions, ImplicitPresentImageDeviceExtension) {
                                                           .set_lib_path(TEST_LAYER_WRAP_OBJECTS_2)
                                                           .set_disable_environment(disable_env_var)
                                                           .set_enable_environment(enable_env_var)),
-                            "implicit_wrap_layer_maint.json");
+                            "implicit_wrap_layer_pres.json");
 
     uint32_t count = 0;
     ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
@@ -558,7 +1074,7 @@ TEST_F(LayerExtensions, ImplicitBothDeviceExtensions) {
                                                           .set_lib_path(TEST_LAYER_WRAP_OBJECTS_3)
                                                           .set_disable_environment(disable_env_var)
                                                           .set_enable_environment(enable_env_var)),
-                            "implicit_wrap_layer_maint.json");
+                            "implicit_wrap_layer_both_dev.json");
 
     uint32_t count = 0;
     ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
@@ -755,7 +1271,7 @@ TEST_F(LayerExtensions, ExplicitPresentImageDeviceExtension) {
                 .set_lib_path(TEST_LAYER_WRAP_OBJECTS_2)
                 .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))
                 .add_device_extension({VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME, 1, {"vkGetSwapchainStatusKHR"}})),
-        "explicit_wrap_layer_maint.json");
+        "explicit_wrap_layer_pres.json");
 
     uint32_t count = 0;
     ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));
@@ -827,7 +1343,7 @@ TEST_F(LayerExtensions, ExplicitBothDeviceExtensions) {
                 .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_maint.json");
+        "explicit_wrap_layer_both_dev.json");
 
     uint32_t count = 0;
     ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr));