/* * Copyright (c) 2021-2023 The Khronos Group Inc. * Copyright (c) 2021-2023 Valve Corporation * Copyright (c) 2021-2023 LunarG, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and/or associated documentation files (the "Materials"), to * deal in the Materials without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Materials, and to permit persons to whom the Materials are * furnished to do so, subject to the following conditions: * * The above copyright notice(s) and this permission notice shall be included in * all copies or substantial portions of the Materials. * * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE * USE OR OTHER DEALINGS IN THE MATERIALS. * * Author: Charles Giessen */ #include "test_environment.h" void CheckLogForLayerString(FrameworkEnvironment& env, const char* implicit_layer_name, bool check_for_enable) { { InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); if (check_for_enable) { ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + implicit_layer_name)); } else { ASSERT_FALSE(env.debug_log.find(std::string("Insert instance layer \"") + implicit_layer_name)); } } env.debug_log.clear(); } const char* lunarg_meta_layer_name = "VK_LAYER_LUNARG_override"; TEST(ImplicitLayers, WithEnableAndDisableEnvVar) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer"; EnvVarWrapper enable_env_var{"ENABLE_ME"}; EnvVarWrapper disable_env_var{"DISABLE_ME"}; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(implicit_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment(disable_env_var.get()) .set_enable_environment(enable_env_var.get())), "implicit_test_layer.json"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name)); // didn't set enable env-var, layer should not load CheckLogForLayerString(env, implicit_layer_name, false); // set enable env-var to 0, no layer should be found enable_env_var.set_new_value("0"); CheckLogForLayerString(env, implicit_layer_name, false); // set enable env-var, layer should load enable_env_var.set_new_value("1"); CheckLogForLayerString(env, implicit_layer_name, true); // remove enable env var, so we can check what happens when only disable is present enable_env_var.remove_value(); // set disable env-var to 0, layer should not load disable_env_var.set_new_value("0"); CheckLogForLayerString(env, implicit_layer_name, false); // set disable env-var to 1, layer should not load disable_env_var.set_new_value("1"); CheckLogForLayerString(env, implicit_layer_name, false); // set both enable and disable env-var, layer should not load enable_env_var.set_new_value("1"); disable_env_var.set_new_value("1"); CheckLogForLayerString(env, implicit_layer_name, false); } TEST(ImplicitLayers, OnlyDisableEnvVar) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer"; EnvVarWrapper disable_env_var{"DISABLE_ME"}; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(implicit_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment(disable_env_var.get())), "implicit_test_layer.json"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name)); // don't set disable env-var, layer should load CheckLogForLayerString(env, implicit_layer_name, true); // set disable env-var to 0, layer should load disable_env_var.set_new_value("0"); CheckLogForLayerString(env, implicit_layer_name, false); // set disable env-var to 1, layer should not load disable_env_var.set_new_value("1"); CheckLogForLayerString(env, implicit_layer_name, false); { InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.create_info.add_layer(implicit_layer_name); inst.CheckCreate(); ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + implicit_layer_name)); } } TEST(ImplicitLayers, PreInstanceEnumInstLayerProps) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer"; EnvVarWrapper disable_env_var{"DISABLE_ME"}; env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer( ManifestLayer::LayerDescription{} .set_name(implicit_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment(disable_env_var.get()) .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{} .set_vk_func("vkEnumerateInstanceLayerProperties") .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties"))), "implicit_test_layer.json"); uint32_t layer_props = 43; auto& layer = env.get_test_layer(0); layer.set_reported_layer_props(layer_props); uint32_t count = 0; ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr)); ASSERT_EQ(count, layer_props); // set disable env-var to 1, layer should not load disable_env_var.set_new_value("1"); count = 0; ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr)); ASSERT_NE(count, 0U); ASSERT_NE(count, layer_props); } TEST(ImplicitLayers, PreInstanceEnumInstExtProps) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer"; EnvVarWrapper disable_env_var{"DISABLE_ME"}; env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer( ManifestLayer::LayerDescription{} .set_name(implicit_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment(disable_env_var.get()) .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{} .set_vk_func("vkEnumerateInstanceExtensionProperties") .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties"))), "implicit_test_layer.json"); uint32_t ext_props = 52; auto& layer = env.get_test_layer(0); layer.set_reported_extension_props(ext_props); uint32_t count = 0; ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr)); ASSERT_EQ(count, ext_props); // set disable env-var to 1, layer should not load disable_env_var.set_new_value("1"); count = 0; ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr)); ASSERT_NE(count, 0U); ASSERT_NE(count, ext_props); } TEST(ImplicitLayers, PreInstanceVersion) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)) .add_physical_device({}) .set_icd_api_version(VK_MAKE_API_VERSION(0, 1, 2, 3)); const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer"; EnvVarWrapper disable_env_var{"DISABLE_ME"}; env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer( ManifestLayer::LayerDescription{} .set_name(implicit_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 2, 3)) .set_disable_environment(disable_env_var.get()) .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{} .set_vk_func("vkEnumerateInstanceVersion") .set_override_name("test_preinst_vkEnumerateInstanceVersion"))), "implicit_test_layer.json"); uint32_t layer_version = VK_MAKE_API_VERSION(1, 2, 3, 4); auto& layer = env.get_test_layer(0); layer.set_reported_instance_version(layer_version); uint32_t version = 0; ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version)); ASSERT_EQ(version, layer_version); // set disable env-var to 1, layer should not load disable_env_var.set_new_value("1"); version = 0; ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version)); ASSERT_NE(version, 0U); ASSERT_NE(version, layer_version); } // Run with a pre-Negotiate function version of the layer so that it has to query vkCreateInstance using the // renamed vkGetInstanceProcAddr function which returns one that intentionally fails. Then disable the // layer and verify it works. The non-override version of vkCreateInstance in the layer also works (and is // tested through behavior above). TEST(ImplicitLayers, OverrideGetInstanceProcAddr) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* implicit_layer_name = "VK_LAYER_ImplicitTestLayer"; EnvVarWrapper disable_env_var{"DISABLE_ME"}; env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 0, 0}).add_layer( ManifestLayer::LayerDescription{} .set_name(implicit_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_1) .set_disable_environment(disable_env_var.get()) .add_function(ManifestLayer::LayerDescription::FunctionOverride{} .set_vk_func("vkGetInstanceProcAddr") .set_override_name("test_override_vkGetInstanceProcAddr"))), "implicit_test_layer.json"); { InstWrapper inst1{env.vulkan_functions}; inst1.CheckCreate(VK_ERROR_INVALID_SHADER_NV); } { // set disable env-var to 1, layer should not load disable_env_var.set_new_value("1"); InstWrapper inst2{env.vulkan_functions}; inst2.CheckCreate(); } } // Force enable with filter env var TEST(ImplicitLayers, EnableWithFilter) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)) .add_physical_device({}) .set_icd_api_version(VK_API_VERSION_1_2); const char* implicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer"; const char* implicit_json_name_1 = "First_layer.json"; const char* disable_layer_name_1 = "DISABLE_FIRST"; const char* enable_layer_name_1 = "ENABLE_FIRST"; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(implicit_layer_name_1) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_enable_environment(enable_layer_name_1) .set_disable_environment(disable_layer_name_1) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), implicit_json_name_1); const char* implicit_layer_name_2 = "VK_LAYER_LUNARG_Second_layer"; const char* implicit_json_name_2 = "Second_layer.json"; const char* disable_layer_name_2 = "DISABLE_SECOND"; const char* enable_layer_name_2 = "ENABLE_SECOND"; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(implicit_layer_name_2) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_enable_environment(enable_layer_name_2) .set_disable_environment(disable_layer_name_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), implicit_json_name_2); const char* implicit_layer_name_3 = "VK_LAYER_LUNARG_Second_test_layer"; const char* implicit_json_name_3 = "Second_test_layer.json"; const char* disable_layer_name_3 = "DISABLE_THIRD"; const char* enable_layer_name_3 = "ENABLE_THIRD"; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(implicit_layer_name_3) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_enable_environment(enable_layer_name_3) .set_disable_environment(disable_layer_name_3) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), implicit_json_name_3); EnvVarWrapper layers_enable_env_var{"VK_LOADER_LAYERS_ENABLE"}; EnvVarWrapper layer_1_enable_env_var{enable_layer_name_1}; // First, test an instance/device without the layer forced on. InstWrapper inst1{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log); inst1.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Now force on one layer with its full name // ------------------------------------------ env.debug_log.clear(); layers_enable_env_var.set_new_value(implicit_layer_name_1); InstWrapper inst2{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log); inst2.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Match prefix // ------------------------------------------ env.debug_log.clear(); layers_enable_env_var.set_new_value("VK_LAYER_LUNARG_*"); InstWrapper inst3{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst3.create_info, env.debug_log); inst3.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Match suffix // ------------------------------------------ env.debug_log.clear(); layers_enable_env_var.set_new_value("*Second_layer"); InstWrapper inst4{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst4.create_info, env.debug_log); inst4.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Match substring // ------------------------------------------ env.debug_log.clear(); layers_enable_env_var.set_new_value("*Second*"); InstWrapper inst5{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst5.create_info, env.debug_log); inst5.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Match all with star '*' // ------------------------------------------ env.debug_log.clear(); layers_enable_env_var.set_new_value("*"); InstWrapper inst6{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst6.create_info, env.debug_log); inst6.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Match all with special name // ------------------------------------------ env.debug_log.clear(); layers_enable_env_var.set_new_value("~all~"); InstWrapper inst7{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst7.create_info, env.debug_log); inst7.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Match substring, but enable the other layer manually // ------------------------------------------ env.debug_log.clear(); layer_1_enable_env_var.set_new_value("1"); layers_enable_env_var.set_new_value("*Second*"); InstWrapper inst8{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst8.create_info, env.debug_log); inst8.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); } // Force disabled with new filter env var TEST(ImplicitLayers, DisableWithFilter) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2)) .set_icd_api_version(VK_API_VERSION_1_2); const char* implicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer"; const char* implicit_json_name_1 = "First_layer.json"; const char* disable_layer_name_1 = "DISABLE_FIRST"; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(implicit_layer_name_1) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment(disable_layer_name_1) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), implicit_json_name_1); const char* implicit_layer_name_2 = "VK_LAYER_LUNARG_Second_layer"; const char* implicit_json_name_2 = "Second_layer.json"; const char* disable_layer_name_2 = "DISABLE_SECOND"; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(implicit_layer_name_2) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment(disable_layer_name_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), implicit_json_name_2); const char* implicit_layer_name_3 = "VK_LAYER_LUNARG_Second_test_layer"; const char* implicit_json_name_3 = "Second_test_layer.json"; const char* disable_layer_name_3 = "DISABLE_THIRD"; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(implicit_layer_name_3) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment(disable_layer_name_3) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), implicit_json_name_3); EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE"}; // First, test an instance/device InstWrapper inst1{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log); inst1.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Now force off one layer with its full name // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value(implicit_layer_name_1); InstWrapper inst2{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log); inst2.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Match prefix // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("VK_LAYER_LUNARG_*"); InstWrapper inst3{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst3.create_info, env.debug_log); inst3.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Match suffix // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("*Second_layer"); InstWrapper inst4{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst4.create_info, env.debug_log); inst4.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Match substring // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("*Second*"); InstWrapper inst5{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst5.create_info, env.debug_log); inst5.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Match all with star '*' // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("*"); InstWrapper inst6{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst6.create_info, env.debug_log); inst6.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Match all with special name // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("~all~"); InstWrapper inst7{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst7.create_info, env.debug_log); inst7.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); } // Force disabled with new filter env var TEST(ImplicitLayers, DisableWithFilterWhenLayersEnableEnvVarIsActive) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2)) .set_icd_api_version(VK_API_VERSION_1_2); const char* implicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer"; const char* implicit_json_name_1 = "First_layer.json"; const char* disable_layer_name_1 = "DISABLE_FIRST"; const char* enable_layer_name_1 = "ENABLE_FIRST"; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(implicit_layer_name_1) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment(disable_layer_name_1) .set_enable_environment(enable_layer_name_1) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), implicit_json_name_1); const char* implicit_layer_name_2 = "VK_LAYER_LUNARG_Second_layer"; const char* implicit_json_name_2 = "Second_layer.json"; const char* disable_layer_name_2 = "DISABLE_SECOND"; const char* enable_layer_name_2 = "ENABLE_SECOND"; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(implicit_layer_name_2) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment(disable_layer_name_2) .set_enable_environment(enable_layer_name_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), implicit_json_name_2); EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE"}; EnvVarWrapper layer_1_enable_env_var{enable_layer_name_1}; EnvVarWrapper layer_2_enable_env_var{enable_layer_name_2}; // First, test an instance/device InstWrapper inst1{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log); inst1.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); // Set the layers enable env-var // ------------------------------------------ env.debug_log.clear(); layer_1_enable_env_var.set_new_value("1"); layer_2_enable_env_var.set_new_value("1"); InstWrapper inst2{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log); inst2.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); // Now force off one layer with its full name // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value(implicit_layer_name_1); InstWrapper inst3{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst3.create_info, env.debug_log); inst3.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); // Now force off both layers // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("~implicit~"); InstWrapper inst4{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst4.create_info, env.debug_log); inst4.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); } // Test interaction between both the enable and disable filter environment variables. The enable should always // override the disable. TEST(ImplicitLayers, EnableAndDisableWithFilter) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2)) .set_icd_api_version(VK_API_VERSION_1_2); const char* implicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer"; const char* implicit_json_name_1 = "First_layer.json"; const char* disable_layer_name_1 = "DISABLE_FIRST"; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(implicit_layer_name_1) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment(disable_layer_name_1) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), implicit_json_name_1); const char* implicit_layer_name_2 = "VK_LAYER_LUNARG_Second_layer"; const char* implicit_json_name_2 = "Second_layer.json"; const char* disable_layer_name_2 = "DISABLE_SECOND"; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(implicit_layer_name_2) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment(disable_layer_name_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), implicit_json_name_2); const char* implicit_layer_name_3 = "VK_LAYER_LUNARG_Second_test_layer"; const char* implicit_json_name_3 = "Second_test_layer.json"; const char* disable_layer_name_3 = "DISABLE_THIRD"; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(implicit_layer_name_3) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment(disable_layer_name_3) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), implicit_json_name_3); EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE"}; EnvVarWrapper layers_enable_env_var{"VK_LOADER_LAYERS_ENABLE"}; // Disable 2 but enable 1 // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("*Second*"); layers_enable_env_var.set_new_value("*test_layer"); InstWrapper inst1{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log); inst1.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Disable all but enable 2 // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("*"); layers_enable_env_var.set_new_value("*Second*"); InstWrapper inst2{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log); inst2.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Disable all but enable 2 // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("~all~"); layers_enable_env_var.set_new_value("*Second*"); InstWrapper inst3{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst3.create_info, env.debug_log); inst3.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Disable implicit but enable 2 // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("~implicit~"); layers_enable_env_var.set_new_value("*Second*"); InstWrapper inst4{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst4.create_info, env.debug_log); inst4.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Disable explicit but enable 2 (should still be everything) // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("~explicit~"); layers_enable_env_var.set_new_value("*Second*"); InstWrapper inst5{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst5.create_info, env.debug_log); inst5.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); // Disable implicit but enable all // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("~implicit~"); layers_enable_env_var.set_new_value("*"); InstWrapper inst6{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst6.create_info, env.debug_log); inst6.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", implicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", implicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(implicit_layer_name_3, "disabled because name matches filter of env var")); } // Add 2 implicit layers with the same layer name and expect only one to be loaded. // Expect the second layer to be found first, because it'll be in a path that is searched first. TEST(ImplicitLayers, DuplicateLayers) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* same_layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(same_layer_name_1) .set_description("actually_layer_1") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment("if_you_can")), "regular_layer_1.json")); auto& layer1 = env.get_test_layer(0); layer1.set_description("actually_layer_1"); layer1.set_make_spurious_log_in_create_instance("actually_layer_1"); env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(same_layer_name_1) .set_description("actually_layer_2") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment("if_you_can")), "regular_layer_1.json") // use override folder as just a folder and manually add it to the implicit layer search paths .set_discovery_type(ManifestDiscoveryType::override_folder)); auto& layer2 = env.get_test_layer(1); layer2.set_description("actually_layer_2"); layer2.set_make_spurious_log_in_create_instance("actually_layer_2"); #if defined(WIN32) env.platform_shim->add_manifest(ManifestCategory::implicit_layer, env.get_folder(ManifestLocation::override_layer).location()); #elif COMMON_UNIX_PLATFORMS env.platform_shim->redirect_path(std::filesystem::path(USER_LOCAL_SHARE_DIR "/vulkan/implicit_layer.d"), env.get_folder(ManifestLocation::override_layer).location()); #endif auto layer_props = env.GetLayerProperties(2); ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[0].layerName)); ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[1].layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description)); ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description)); InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(same_layer_name_1, enabled_layer_props.at(0).layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props.at(0).description)); ASSERT_TRUE(env.debug_log.find("actually_layer_1")); ASSERT_FALSE(env.debug_log.find("actually_layer_2")); } TEST(ImplicitLayers, VkImplicitLayerPathEnvVar) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); // verify layer loads successfully when setting VK_IMPLICIT_LAYER_PATH to a full filepath const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name_1) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment("Yikes")), "regular_layer_1.json") .set_discovery_type(ManifestDiscoveryType::env_var) .set_is_dir(false)); InstWrapper inst(env.vulkan_functions); inst.CheckCreate(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name_1)); } TEST(ImplicitLayers, VkImplicitLayerPathEnvVarContainsMultipleFilePaths) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); // verify layers load successfully when setting VK_IMPLICIT_LAYER_PATH to multiple full filepaths const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name_1) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment("Yikes")), "regular_layer_1.json") .set_discovery_type(ManifestDiscoveryType::env_var) .set_is_dir(false)); const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2"; env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name_2) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment("Yikes")), "regular_layer_2.json") .set_discovery_type(ManifestDiscoveryType::env_var) .set_is_dir(false)); InstWrapper inst(env.vulkan_functions); inst.CheckCreate(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); EXPECT_TRUE(check_permutation({regular_layer_name_1, regular_layer_name_2}, layer_props)); } TEST(ImplicitLayers, VkImplicitLayerPathEnvVarIsDirectory) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); // verify layers load successfully when setting VK_IMPLICIT_LAYER_PATH to a directory const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name_1) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment("Yikes")), "regular_layer_1.json") .set_discovery_type(ManifestDiscoveryType::env_var)); const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2"; env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name_2) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment("Yikes")), "regular_layer_2.json") .set_discovery_type(ManifestDiscoveryType::env_var)); InstWrapper inst(env.vulkan_functions); inst.CheckCreate(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); EXPECT_TRUE(check_permutation({regular_layer_name_1, regular_layer_name_2}, layer_props)); } // Test to make sure order layers are found in VK_IMPLICIT_LAYER_PATH is what decides which layer is loaded TEST(ImplicitLayers, DuplicateLayersInVkImplicitLayerPath) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* layer_name = "VK_LAYER_RegularLayer1"; env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name) .set_description("actually_layer_1") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment("Boo!")), "layer.json") .set_discovery_type(ManifestDiscoveryType::env_var) .set_is_dir(true)); auto& layer1 = env.get_test_layer(0); layer1.set_description("actually_layer_1"); env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name) .set_description("actually_layer_2") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment("Ah!")), "layer.json") // putting it in a separate folder then manually adding the folder to VK_IMPLICIT_LAYER_PATH .set_discovery_type(ManifestDiscoveryType::override_folder) .set_is_dir(true)); auto& layer2 = env.get_test_layer(1); layer2.set_description("actually_layer_2"); env.env_var_vk_implicit_layer_paths.add_to_list(env.get_folder(ManifestLocation::override_layer).location().string()); auto layer_props = env.GetLayerProperties(2); ASSERT_TRUE(string_eq(layer_name, layer_props[0].layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description)); ASSERT_TRUE(string_eq(layer_name, layer_props[1].layerName)); ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description)); EnvVarWrapper inst_layers_env_var{"VK_INSTANCE_LAYERS"}; inst_layers_env_var.add_to_list(layer_name); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); // Expect the first layer added to be found auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layer_name, enabled_layer_props[0].layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props[0].description)); } TEST(ImplicitLayers, DuplicateLayersInVK_ADD_IMPLICIT_LAYER_PATH) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* same_layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(same_layer_name_1) .set_description("actually_layer_1") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment("Red")), "regular_layer_1.json") // use override folder as just a folder and manually set the VK_ADD_IMPLICIT_LAYER_PATH env-var to it .set_discovery_type(ManifestDiscoveryType::override_folder) .set_is_dir(true)); auto& layer1 = env.get_test_layer(0); layer1.set_description("actually_layer_1"); layer1.set_make_spurious_log_in_create_instance("actually_layer_1"); env.add_env_var_vk_implicit_layer_paths.add_to_list(narrow(env.get_folder(ManifestLocation::override_layer).location())); env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(same_layer_name_1) .set_description("actually_layer_2") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment("Blue")), "regular_layer_1.json") .set_discovery_type(ManifestDiscoveryType::add_env_var) .set_is_dir(true)); auto& layer2 = env.get_test_layer(1); layer2.set_description("actually_layer_2"); layer2.set_make_spurious_log_in_create_instance("actually_layer_2"); auto layer_props = env.GetLayerProperties(2); ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[0].layerName)); ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[1].layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description)); ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description)); InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(same_layer_name_1, enabled_layer_props.at(0).layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props.at(0).description)); ASSERT_TRUE(env.debug_log.find("actually_layer_1")); ASSERT_FALSE(env.debug_log.find("actually_layer_2")); } // Meta layer which contains component layers that do not exist. TEST(MetaLayers, InvalidComponentLayer) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); const char* meta_layer_name = "VK_LAYER_MetaTestLayer"; const char* invalid_layer_name_1 = "VK_LAYER_InvalidLayer1"; const char* invalid_layer_name_2 = "VK_LAYER_InvalidLayer2"; env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer( ManifestLayer::LayerDescription{} .set_name(meta_layer_name) .add_component_layers({invalid_layer_name_1, invalid_layer_name_2}) .set_disable_environment("NotGonnaWork") .add_instance_extension({"NeverGonnaGiveYouUp"}) .add_device_extension({"NeverGonnaLetYouDown"})), "meta_test_layer.json"); const char* regular_layer_name = "TestLayer"; env.add_explicit_layer( ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_test_layer.json"); // should find 1, the 'regular' layer auto layer_props = env.GetLayerProperties(1); EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name)); auto extensions = env.GetInstanceExtensions(4); EXPECT_TRUE(string_eq(extensions.at(0).extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(1).extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(2).extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(3).extensionName, VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME)); InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(meta_layer_name); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT); ASSERT_TRUE(env.debug_log.find(std::string("verify_meta_layer_component_layers: Meta-layer ") + meta_layer_name + " can't find component layer " + invalid_layer_name_1 + " at index 0. Skipping this layer.")); } // Meta layer that is an explicit layer TEST(MetaLayers, ExplicitMetaLayer) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* meta_layer_name = "VK_LAYER_MetaTestLayer"; const char* regular_layer_name = "VK_LAYER_TestLayer"; env.add_explicit_layer( ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer( ManifestLayer::LayerDescription{}.set_name(meta_layer_name).add_component_layers({regular_layer_name})), "meta_test_layer.json"); env.add_explicit_layer( ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_test_layer.json"); { // global functions // should find 1, the 'regular' layer auto layer_props = env.GetLayerProperties(2); EXPECT_TRUE(check_permutation({regular_layer_name, meta_layer_name}, layer_props)); auto extensions = env.GetInstanceExtensions(4); EXPECT_TRUE(string_eq(extensions.at(0).extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(1).extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(2).extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(3).extensionName, VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME)); } { // don't enable the layer, shouldn't find any layers when calling vkEnumerateDeviceLayerProperties InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(meta_layer_name); inst.CheckCreate(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); EXPECT_TRUE(check_permutation({regular_layer_name, meta_layer_name}, layer_props)); } } // Meta layer which adds itself in its list of component layers TEST(MetaLayers, MetaLayerNameInComponentLayers) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); const char* meta_layer_name = "VK_LAYER_MetaTestLayer"; const char* regular_layer_name = "VK_LAYER_TestLayer"; env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer( ManifestLayer::LayerDescription{} .set_name(meta_layer_name) .add_component_layers({meta_layer_name, regular_layer_name}) .set_disable_environment("NotGonnaWork") .add_instance_extension({"NeverGonnaGiveYouUp"}) .add_device_extension({"NeverGonnaLetYouDown"})), "meta_test_layer.json"); env.add_explicit_layer( ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_test_layer.json"); // should find 1, the 'regular' layer auto layer_props = env.GetLayerProperties(1); EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name)); auto extensions = env.GetInstanceExtensions(4); EXPECT_TRUE(string_eq(extensions.at(0).extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(1).extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(2).extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(3).extensionName, VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME)); InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(meta_layer_name); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT); ASSERT_TRUE(env.debug_log.find(std::string("verify_meta_layer_component_layers: Meta-layer ") + meta_layer_name + " lists itself in its component layer " + "list at index 0. Skipping this layer.")); } // Meta layer which adds another meta layer as a component layer TEST(MetaLayers, MetaLayerWhichAddsMetaLayer) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); const char* meta_layer_name = "VK_LAYER_MetaTestLayer"; const char* meta_meta_layer_name = "VK_LAYER_MetaMetaTestLayer"; const char* regular_layer_name = "VK_LAYER_TestLayer"; env.add_explicit_layer( ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_test_layer.json"); env.add_explicit_layer( ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer( ManifestLayer::LayerDescription{}.set_name(meta_layer_name).add_component_layers({regular_layer_name})), "meta_test_layer.json"); env.add_explicit_layer(ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer( ManifestLayer::LayerDescription{} .set_name(meta_meta_layer_name) .add_component_layers({meta_layer_name, regular_layer_name})), "meta_meta_test_layer.json"); auto layer_props = env.GetLayerProperties(3); EXPECT_TRUE(check_permutation({regular_layer_name, meta_layer_name, meta_meta_layer_name}, layer_props)); auto extensions = env.GetInstanceExtensions(4); EXPECT_TRUE(string_eq(extensions.at(0).extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(1).extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(2).extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(3).extensionName, VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME)); InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(meta_layer_name); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); ASSERT_TRUE(env.debug_log.find(std::string("verify_meta_layer_component_layers: Adding meta-layer ") + meta_meta_layer_name + " which also contains meta-layer " + meta_layer_name)); } TEST(MetaLayers, InstanceExtensionInComponentLayer) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* meta_layer_name = "VK_LAYER_MetaTestLayer"; const char* regular_layer_name = "VK_LAYER_TestLayer"; const char* instance_ext_name = "VK_EXT_headless_surface"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .add_instance_extension({instance_ext_name})), "regular_test_layer.json"); env.add_explicit_layer( ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer( ManifestLayer::LayerDescription{}.set_name(meta_layer_name).add_component_layers({regular_layer_name})), "meta_test_layer.json"); auto extensions = env.GetInstanceExtensions(1, meta_layer_name); EXPECT_TRUE(string_eq(extensions[0].extensionName, instance_ext_name)); } TEST(MetaLayers, DeviceExtensionInComponentLayer) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* meta_layer_name = "VK_LAYER_MetaTestLayer"; const char* regular_layer_name = "VK_LAYER_TestLayer"; const char* device_ext_name = "VK_EXT_fake_dev_ext"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .add_device_extension({device_ext_name})), "regular_test_layer.json"); env.add_explicit_layer( ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer( ManifestLayer::LayerDescription{}.set_name(meta_layer_name).add_component_layers({regular_layer_name})), "meta_test_layer.json"); ASSERT_NO_FATAL_FAILURE(env.GetInstanceExtensions(0, meta_layer_name)); { // layer is not enabled InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); ASSERT_TRUE(env.debug_log.find(std::string("Meta-layer ") + meta_layer_name + " component layer " + regular_layer_name + " adding device extension " + device_ext_name)); auto extensions = inst.EnumerateLayerDeviceExtensions(inst.GetPhysDev(), meta_layer_name, 1); EXPECT_TRUE(string_eq(extensions.at(0).extensionName, device_ext_name)); } { // layer is enabled InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(meta_layer_name); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); ASSERT_TRUE(env.debug_log.find(std::string("Meta-layer ") + meta_layer_name + " component layer " + regular_layer_name + " adding device extension " + device_ext_name)); auto extensions = inst.EnumerateLayerDeviceExtensions(inst.GetPhysDev(), meta_layer_name, 1); EXPECT_TRUE(string_eq(extensions.at(0).extensionName, device_ext_name)); } } // Override meta layer missing disable environment variable still enables the layer TEST(OverrideMetaLayer, InvalidDisableEnvironment) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* regular_layer_name = "VK_LAYER_TestLayer"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_device_extension({"NeverGonnaLetYouDown"})), "regular_test_layer.json"); env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_component_layers({regular_layer_name})), "meta_test_layer.json"); auto layer_props = env.GetLayerProperties(1); EXPECT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name)); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); } // Override meta layer whose version is less than the api version of the instance TEST(OverrideMetaLayer, OlderVersionThanInstance) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* regular_layer_name = "VK_LAYER_TestLayer"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_device_extension({"NeverGonnaLetYouDown"})), "regular_test_layer.json"); env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .set_disable_environment("DisableMeIfYouCan") .add_component_layers({regular_layer_name})), "meta_test_layer.json"); { // global functions auto layer_props = env.GetLayerProperties(2); EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props)); } { // 1.1 instance InstWrapper inst{env.vulkan_functions}; inst.create_info.api_version = VK_API_VERSION_1_1; inst.CheckCreate(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); ASSERT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name)); ASSERT_TRUE(string_eq(layer_props[1].layerName, lunarg_meta_layer_name)); } { // 1.3 instance InstWrapper inst{env.vulkan_functions}; inst.create_info.api_version = VK_API_VERSION_1_3; inst.CheckCreate(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); ASSERT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name)); ASSERT_TRUE(string_eq(layer_props[1].layerName, lunarg_meta_layer_name)); } } TEST(OverrideMetaLayer, OlderMetaLayerWithNewerInstanceVersion) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* regular_layer_name = "VK_LAYER_TestLayer"; env.add_explicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))), "regular_test_layer.json"); env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_component_layers({regular_layer_name}) .set_disable_environment("DisableMeIfYouCan")), "meta_test_layer.json"); { // global functions auto layer_props = env.GetLayerProperties(2); EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props)); } { // 1.1 instance InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(1, 1, 0); inst.CheckCreate(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); ASSERT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name)); ASSERT_TRUE(string_eq(layer_props[1].layerName, lunarg_meta_layer_name)); } { // 1.3 instance InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(1, 3, 0); inst.CheckCreate(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); ASSERT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name)); ASSERT_TRUE(string_eq(layer_props[1].layerName, lunarg_meta_layer_name)); } } TEST(OverrideMetaLayer, NewerComponentLayerInMetaLayer) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* regular_layer_name = "VK_LAYER_TestLayer"; env.add_explicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_API_VERSION_1_2)), "regular_test_layer.json"); env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_component_layers({regular_layer_name}) .set_disable_environment("DisableMeIfYouCan")), "meta_test_layer.json"); { // global functions auto layer_props = env.GetLayerProperties(2); // Expect the explicit layer to still be found EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props)); } { // 1.1 instance InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.create_info.set_api_version(1, 1, 0); inst.CheckCreate(); // Newer component is allowed now EXPECT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name)); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props)); } env.debug_log.clear(); { // 1.3 instance InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.create_info.set_api_version(1, 3, 0); inst.CheckCreate(); // Newer component is allowed now EXPECT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name)); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props)); } } TEST(OverrideMetaLayer, OlderComponentLayerInMetaLayer) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* regular_layer_name = "VK_LAYER_TestLayer"; env.add_explicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), "regular_test_layer.json"); env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_component_layers({regular_layer_name}) .set_disable_environment("DisableMeIfYouCan")), "meta_test_layer.json"); { // global functions auto layer_props = env.GetLayerProperties(1); EXPECT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name)); } { // 1.1 instance InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.create_info.set_api_version(1, 1, 0); inst.CheckCreate(); EXPECT_TRUE( env.debug_log.find("verify_meta_layer_component_layers: Meta-layer uses API version 1.1, but component layer 0 has API " "version 1.0 that is lower. Skipping this layer.")); env.debug_log.clear(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { // 1.2 instance InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.create_info.set_api_version(1, 2, 0); inst.CheckCreate(); ASSERT_TRUE( env.debug_log.find("verify_meta_layer_component_layers: Meta-layer uses API version 1.1, but component layer 0 has API " "version 1.0 that is lower. Skipping this layer.")); env.debug_log.clear(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } } TEST(OverrideMetaLayer, ApplicationEnabledLayerInBlacklist) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* automatic_regular_layer_name = "VK_LAYER_TestLayer_1"; const char* manual_regular_layer_name = "VK_LAYER_TestLayer_2"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(automatic_regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))), "regular_test_layer_1.json"); env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(manual_regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))), "regular_test_layer_2.json"); env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_component_layer(automatic_regular_layer_name) .add_blacklisted_layer(manual_regular_layer_name) .set_disable_environment("DisableMeIfYouCan")), "meta_test_layer.json"); { // Check that enumerating the layers returns only the non-blacklisted layers + override layer auto layer_props = env.GetLayerProperties(2); ASSERT_TRUE(check_permutation({automatic_regular_layer_name, lunarg_meta_layer_name}, layer_props)); } { // enable the layer in the blacklist InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.create_info.add_layer(manual_regular_layer_name); inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT); ASSERT_TRUE(env.debug_log.find(std::string("loader_remove_layers_in_blacklist: Override layer is active and layer ") + manual_regular_layer_name + " is in the blacklist inside of it. Removing that layer from current layer list.")); env.debug_log.clear(); } { // dont enable the layer in the blacklist InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); ASSERT_TRUE(env.debug_log.find(std::string("loader_remove_layers_in_blacklist: Override layer is active and layer ") + manual_regular_layer_name + " is in the blacklist inside of it. Removing that layer from current layer list.")); env.debug_log.clear(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); ASSERT_TRUE(check_permutation({automatic_regular_layer_name, lunarg_meta_layer_name}, layer_props)); } } TEST(OverrideMetaLayer, BasicOverridePaths) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); fs::FolderManager override_layer_folder{FRAMEWORK_BUILD_DIRECTORY, "override_layer_folder"}; const char* regular_layer_name = "VK_LAYER_TestLayer_1"; override_layer_folder.write_manifest("regular_test_layer.json", ManifestLayer{} .add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))) .get_manifest_str()); env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_component_layer(regular_layer_name) .set_disable_environment("DisableMeIfYouCan") .add_override_path(override_layer_folder.location())), "meta_test_layer.json"); InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(1, 1, 0); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name)); env.layers.clear(); } TEST(OverrideMetaLayer, BasicOverridePathsIgnoreOtherLayers) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); fs::FolderManager override_layer_folder{FRAMEWORK_BUILD_DIRECTORY, "override_layer_folder"}; const char* regular_layer_name = "VK_LAYER_TestLayer"; env.add_explicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), "regular_test_layer.json"); const char* special_layer_name = "VK_LAYER_TestLayer_1"; override_layer_folder.write_manifest("regular_test_layer.json", ManifestLayer{} .add_layer(ManifestLayer::LayerDescription{} .set_name(special_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))) .get_manifest_str()); env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_component_layer(special_layer_name) .set_disable_environment("DisableMeIfYouCan") .add_override_path(override_layer_folder.location())), "meta_test_layer.json"); InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(1, 1, 0); inst.create_info.add_layer(regular_layer_name); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT); ASSERT_FALSE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name)); env.layers.clear(); } TEST(OverrideMetaLayer, OverridePathsInteractionWithVK_LAYER_PATH) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); // add explicit layer to VK_LAYER_PATH folder const char* env_var_layer_name = "VK_LAYER_env_var_set_path"; env.add_explicit_layer(TestLayerDetails{ ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(env_var_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), "regular_test_layer.json"} .set_discovery_type(ManifestDiscoveryType::env_var)); // add layer to regular explicit layer folder const char* regular_layer_name = "VK_LAYER_regular_layer_path"; env.add_explicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))), "regular_test_layer.json"} .set_discovery_type(ManifestDiscoveryType::override_folder)); env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer( ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_component_layer(regular_layer_name) .set_disable_environment("DisableMeIfYouCan") .add_override_path(env.get_folder(ManifestLocation::override_layer).location())), "meta_test_layer.json"); auto meta_layer_path = env.get_folder(ManifestLocation::override_layer).location(); InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(1, 1, 0); inst.create_info.add_layer(env_var_layer_name); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT); ASSERT_FALSE(env.debug_log.find(std::string("Insert instance layer \"") + env_var_layer_name)); ASSERT_TRUE(env.debug_log.find( std::string("Ignoring VK_LAYER_PATH. The Override layer is active and has override paths set, which takes priority. " "VK_LAYER_PATH is set to ") + env.env_var_vk_layer_paths.value())); ASSERT_TRUE(env.debug_log.find("Override layer has override paths set to " + meta_layer_path.string())); env.layers.clear(); } // Make sure that implicit layers not in the override paths aren't found by mistake TEST(OverrideMetaLayer, OverridePathsEnableImplicitLayerInDefaultPaths) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); fs::FolderManager override_layer_folder{FRAMEWORK_BUILD_DIRECTORY, "override_layer_folder"}; const char* implicit_layer_name = "VK_LAYER_ImplicitLayer"; env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(implicit_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), "implicit_test_layer.json"); const char* regular_layer_name = "VK_LAYER_TestLayer_1"; override_layer_folder.write_manifest("regular_test_layer.json", ManifestLayer{} .add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))) .get_manifest_str()); env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer( ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_component_layers({regular_layer_name, implicit_layer_name}) .set_disable_environment("DisableMeIfYouCan") .add_override_path(override_layer_folder.location())), "meta_test_layer.json"); InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.create_info.set_api_version(1, 1, 0); inst.CheckCreate(); ASSERT_FALSE(env.debug_log.find(std::string("Insert instance layer \"") + implicit_layer_name)); ASSERT_TRUE( env.debug_log.find("Removing meta-layer VK_LAYER_LUNARG_override from instance layer list since it appears invalid.")); env.layers.clear(); } TEST(OverrideMetaLayer, ManifestFileFormatVersionTooOld) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); fs::FolderManager override_layer_folder{FRAMEWORK_BUILD_DIRECTORY, "override_layer_folder"}; const char* regular_layer_name = "VK_LAYER_TestLayer_1"; override_layer_folder.write_manifest("regular_test_layer.json", ManifestLayer{} .add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))) .get_manifest_str()); env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 0, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_component_layer(regular_layer_name) .set_disable_environment("DisableMeIfYouCan") .add_override_path(override_layer_folder.location())), "meta_test_layer.json"); InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(1, 1, 0); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name)); ASSERT_TRUE(env.debug_log.find("Indicating meta-layer-specific override paths, but using older JSON file version.")); env.layers.clear(); } // app_key contains test executable name, should activate the override layer TEST(OverrideMetaLayer, AppKeysDoesContainCurrentApplication) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* regular_layer_name = "VK_LAYER_TestLayer"; env.add_explicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_test_layer.json"); std::string cur_path = test_platform_executable_path(); env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .add_component_layers({regular_layer_name}) .set_disable_environment("DisableMeIfYouCan") .add_app_key(cur_path)), "meta_test_layer.json"); { // global functions auto layer_props = env.GetLayerProperties(2); EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props)); } { // instance InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props)); } } // app_key contains random strings, should not activate the override layer TEST(OverrideMetaLayer, AppKeysDoesNotContainCurrentApplication) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* regular_layer_name = "VK_LAYER_TestLayer"; env.add_explicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_test_layer.json"); env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer( ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .add_component_layers({regular_layer_name}) .set_disable_environment("DisableMeIfYouCan") .add_app_keys({"/Hello", "Hi", "./../Uh-oh", "C:/Windows/Only"})), "meta_test_layer.json"); { // global functions auto layer_props = env.GetLayerProperties(1); EXPECT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name)); } { // instance InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } } TEST(OverrideMetaLayer, RunningWithElevatedPrivilegesFromSecureLocation) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); fs::FolderManager override_layer_folder{FRAMEWORK_BUILD_DIRECTORY, "override_layer_folder"}; const char* regular_layer_name = "VK_LAYER_TestLayer_1"; override_layer_folder.write_manifest("regular_test_layer.json", ManifestLayer{} .add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))) .get_manifest_str()); auto override_folder_location = override_layer_folder.location().string(); env.add_implicit_layer(TestLayerDetails{ ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_component_layer(regular_layer_name) .set_disable_environment("DisableMeIfYouCan") .add_override_path(override_layer_folder.location())), "meta_test_layer.json"}); { // try with no elevated privileges auto layer_props = env.GetLayerProperties(2); EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props)); InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(1, 1, 0); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name)); auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props)); env.debug_log.clear(); } env.platform_shim->set_elevated_privilege(true); { // try with elevated privileges auto layer_props = env.GetLayerProperties(2); EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props)); InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(1, 1, 0); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name)); auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, active_layer_props)); } } // Override layer should not be found and thus not loaded when running with elevated privileges TEST(OverrideMetaLayer, RunningWithElevatedPrivilegesFromUnsecureLocation) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); fs::FolderManager override_layer_folder{FRAMEWORK_BUILD_DIRECTORY, "override_layer_folder"}; const char* regular_layer_name = "VK_LAYER_TestLayer_1"; override_layer_folder.write_manifest("regular_test_layer.json", ManifestLayer{} .add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))) .get_manifest_str()); env.add_implicit_layer(TestLayerDetails{ ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_component_layer(regular_layer_name) .set_disable_environment("DisableMeIfYouCan") .add_override_path(override_layer_folder.location())), "meta_test_layer.json"} .set_discovery_type(ManifestDiscoveryType::unsecured_generic)); { // try with no elevated privileges auto layer_props = env.GetLayerProperties(2); EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, layer_props)); InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(1, 1, 0); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); ASSERT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name)); env.debug_log.clear(); auto active_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); EXPECT_TRUE(check_permutation({regular_layer_name, lunarg_meta_layer_name}, active_layer_props)); } env.platform_shim->set_elevated_privilege(true); { // try with no elevated privileges ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0)); InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(1, 1, 0); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); ASSERT_FALSE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name)); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } } // Makes sure explicit layers can't override pre-instance functions even if enabled by the override layer TEST(ExplicitLayers, OverridePreInstanceFunctions) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* explicit_layer_name = "VK_LAYER_enabled_by_override"; const char* disable_env_var = "DISABLE_ME"; env.add_explicit_layer( ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer( ManifestLayer::LayerDescription{} .set_name(explicit_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{} .set_vk_func("vkEnumerateInstanceLayerProperties") .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties")) .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{} .set_vk_func("vkEnumerateInstanceExtensionProperties") .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties")) .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{} .set_vk_func("vkEnumerateInstanceVersion") .set_override_name("test_preinst_vkEnumerateInstanceVersion"))), "explicit_test_layer.json"); auto& layer = env.get_test_layer(0); layer.set_reported_layer_props(34); layer.set_reported_extension_props(22); layer.set_reported_instance_version(VK_MAKE_API_VERSION(1, 0, 0, 1)); env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer(ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .add_component_layers({explicit_layer_name}) .set_disable_environment(disable_env_var)), "override_meta_layer.json"); uint32_t count = 0; ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr)); ASSERT_EQ(count, 2U); count = 0; ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr)); ASSERT_EQ(count, 4U); uint32_t version = 0; ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version)); ASSERT_EQ(version, VK_HEADER_VERSION_COMPLETE); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2); ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name)); ASSERT_TRUE(string_eq(layers.at(1).layerName, lunarg_meta_layer_name)); } TEST(ExplicitLayers, LayerSettingsPreInstanceFunctions) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* explicit_layer_name = "VK_LAYER_enabled_by_override"; env.add_explicit_layer( ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer( ManifestLayer::LayerDescription{} .set_name(explicit_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{} .set_vk_func("vkEnumerateInstanceLayerProperties") .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties")) .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{} .set_vk_func("vkEnumerateInstanceExtensionProperties") .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties")) .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{} .set_vk_func("vkEnumerateInstanceVersion") .set_override_name("test_preinst_vkEnumerateInstanceVersion"))), "explicit_test_layer.json"); env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration( LoaderSettingsLayerConfiguration{} .set_name(explicit_layer_name) .set_control("on") .set_path(env.get_shimmed_layer_manifest_path(0)) .set_treat_as_implicit_manifest(false))); env.update_loader_settings(env.loader_settings); auto& layer = env.get_test_layer(0); layer.set_reported_layer_props(34); layer.set_reported_extension_props(22); layer.set_reported_instance_version(VK_MAKE_API_VERSION(1, 0, 0, 1)); uint32_t count = 0; ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr)); ASSERT_EQ(count, 1U); count = 0; ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr)); ASSERT_EQ(count, 4U); uint32_t version = 0; ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version)); ASSERT_EQ(version, VK_HEADER_VERSION_COMPLETE); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name)); } TEST(ExplicitLayers, ContainsPreInstanceFunctions) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* explicit_layer_name = "VK_LAYER_enabled_by_override"; env.add_explicit_layer( ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer( ManifestLayer::LayerDescription{} .set_name(explicit_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{} .set_vk_func("vkEnumerateInstanceLayerProperties") .set_override_name("test_preinst_vkEnumerateInstanceLayerProperties")) .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{} .set_vk_func("vkEnumerateInstanceExtensionProperties") .set_override_name("test_preinst_vkEnumerateInstanceExtensionProperties")) .add_pre_instance_function(ManifestLayer::LayerDescription::FunctionOverride{} .set_vk_func("vkEnumerateInstanceVersion") .set_override_name("test_preinst_vkEnumerateInstanceVersion"))), "explicit_test_layer.json"); auto& layer = env.get_test_layer(0); layer.set_reported_layer_props(34); layer.set_reported_extension_props(22); layer.set_reported_instance_version(VK_MAKE_API_VERSION(1, 0, 0, 1)); uint32_t count = 0; ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&count, nullptr)); ASSERT_EQ(count, 1U); count = 0; ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr)); ASSERT_EQ(count, 4U); uint32_t version = 0; ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceVersion(&version)); ASSERT_EQ(version, VK_HEADER_VERSION_COMPLETE); InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(explicit_layer_name); inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name)); } TEST(ExplicitLayers, CallsPreInstanceFunctionsInCreateInstance) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* explicit_layer_name = "VK_LAYER_enabled_by_override"; env.add_explicit_layer( ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer( ManifestLayer::LayerDescription{}.set_name(explicit_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "explicit_test_layer.json"); auto& layer = env.get_test_layer(0); layer.set_query_vkEnumerateInstanceLayerProperties(true); layer.set_query_vkEnumerateInstanceExtensionProperties(true); layer.set_query_vkEnumerateInstanceVersion(true); InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(explicit_layer_name); inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, explicit_layer_name)); } // This test makes sure that any layer calling GetPhysicalDeviceProperties2 inside of CreateInstance // succeeds and doesn't crash. TEST(LayerCreateInstance, GetPhysicalDeviceProperties2) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)) .add_physical_device({}) .set_icd_api_version(VK_API_VERSION_1_1); const char* regular_layer_name = "VK_LAYER_TestLayer"; env.add_explicit_layer( ManifestLayer{}.set_file_format_version({1, 1, 2}).add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_test_layer.json"); auto& layer_handle = env.get_test_layer(0); layer_handle.set_create_instance_callback([](TestLayer& layer) -> VkResult { uint32_t phys_dev_count = 0; VkResult res = layer.instance_dispatch_table.EnumeratePhysicalDevices(layer.instance_handle, &phys_dev_count, nullptr); if (res != VK_SUCCESS || phys_dev_count > 1) { return VK_ERROR_INITIALIZATION_FAILED; // expecting only a single physical device. } VkPhysicalDevice phys_dev{}; res = layer.instance_dispatch_table.EnumeratePhysicalDevices(layer.instance_handle, &phys_dev_count, &phys_dev); if (res != VK_SUCCESS) { return VK_ERROR_INITIALIZATION_FAILED; } VkPhysicalDeviceProperties2 props2{}; props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; layer.instance_dispatch_table.GetPhysicalDeviceProperties2(phys_dev, &props2); VkPhysicalDeviceFeatures2 features2{}; features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; layer.instance_dispatch_table.GetPhysicalDeviceFeatures2(phys_dev, &features2); return VK_SUCCESS; }); InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(regular_layer_name).set_api_version(1, 1, 0); inst.CheckCreate(); } TEST(LayerCreateInstance, GetPhysicalDeviceProperties2KHR) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)) .add_physical_device({}) .add_instance_extension({"VK_KHR_get_physical_device_properties2", 0}); const char* regular_layer_name = "VK_LAYER_TestLayer"; env.add_explicit_layer( ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_test_layer.json"); auto& layer_handle = env.get_test_layer(0); layer_handle.set_create_instance_callback([](TestLayer& layer) -> VkResult { uint32_t phys_dev_count = 1; VkPhysicalDevice phys_dev{}; layer.instance_dispatch_table.EnumeratePhysicalDevices(layer.instance_handle, &phys_dev_count, &phys_dev); VkPhysicalDeviceProperties2KHR props2{}; props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; layer.instance_dispatch_table.GetPhysicalDeviceProperties2KHR(phys_dev, &props2); VkPhysicalDeviceFeatures2KHR features2{}; features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; layer.instance_dispatch_table.GetPhysicalDeviceFeatures2KHR(phys_dev, &features2); return VK_SUCCESS; }); InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(regular_layer_name).add_extension("VK_KHR_get_physical_device_properties2"); inst.CheckCreate(); } TEST(ExplicitLayers, MultipleLayersInSingleManifest) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2"; const char* regular_layer_name_3 = "VK_LAYER_RegularLayer3"; env.add_explicit_layer(TestLayerDetails( ManifestLayer{} .set_file_format_version({1, 0, 1}) .add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)) .add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)) .add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name_3).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "multi_layer_manifest.json")); auto layer_props = env.GetLayerProperties(3); ASSERT_TRUE(string_eq(regular_layer_name_1, layer_props[0].layerName)); ASSERT_TRUE(string_eq(regular_layer_name_2, layer_props[1].layerName)); ASSERT_TRUE(string_eq(regular_layer_name_3, layer_props[2].layerName)); } TEST(ExplicitLayers, WrapObjects) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device("physical_device_0"); const char* wrap_objects_name = "VK_LAYER_LUNARG_wrap_objects"; env.add_explicit_layer(ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(wrap_objects_name).set_lib_path(TEST_LAYER_WRAP_OBJECTS)), "wrap_objects_layer.json"); const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_explicit_layer( ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_1.json"); const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2"; env.add_explicit_layer( ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_2.json"); { // just the wrap layer InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(wrap_objects_name); inst.CheckCreate(); VkPhysicalDevice phys_dev = inst.GetPhysDev(); DeviceWrapper dev{inst}; dev.CheckCreate(phys_dev); } { // wrap layer first InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(wrap_objects_name).add_layer(regular_layer_name_1); inst.CheckCreate(); VkPhysicalDevice phys_dev = inst.GetPhysDev(); DeviceWrapper dev{inst}; dev.CheckCreate(phys_dev); } { // wrap layer last InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(regular_layer_name_1).add_layer(wrap_objects_name); inst.CheckCreate(); VkPhysicalDevice phys_dev = inst.GetPhysDev(); DeviceWrapper dev{inst}; dev.CheckCreate(phys_dev); } { // wrap layer last InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(regular_layer_name_1).add_layer(wrap_objects_name).add_layer(regular_layer_name_2); inst.CheckCreate(); VkPhysicalDevice phys_dev = inst.GetPhysDev(); DeviceWrapper dev{inst}; dev.CheckCreate(phys_dev); } } TEST(ExplicitLayers, VkLayerPathEnvVar) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); // verify layer loads successfully when setting VK_LAYER_PATH to a full filepath const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_explicit_layer( TestLayerDetails( ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_1.json") .set_discovery_type(ManifestDiscoveryType::env_var) .set_is_dir(false)); InstWrapper inst(env.vulkan_functions); inst.create_info.add_layer(regular_layer_name_1); inst.CheckCreate(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); EXPECT_TRUE(string_eq(layer_props.at(0).layerName, regular_layer_name_1)); } TEST(ExplicitLayers, VkLayerPathEnvVarContainsMultipleFilepaths) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); // verify layers load successfully when setting VK_LAYER_PATH to multiple full filepaths const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_explicit_layer( TestLayerDetails( ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_1.json") .set_discovery_type(ManifestDiscoveryType::env_var) .set_is_dir(false)); const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2"; env.add_explicit_layer( TestLayerDetails( ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_2.json") .set_discovery_type(ManifestDiscoveryType::env_var) .set_is_dir(false)); InstWrapper inst(env.vulkan_functions); inst.create_info.add_layer(regular_layer_name_1); inst.create_info.add_layer(regular_layer_name_2); inst.CheckCreate(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); EXPECT_TRUE(check_permutation({regular_layer_name_1, regular_layer_name_2}, layer_props)); } TEST(ExplicitLayers, VkLayerPathEnvVarIsDirectory) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); // verify layers load successfully when setting VK_LAYER_PATH to a directory const char* regular_layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_explicit_layer( TestLayerDetails( ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name_1).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_1.json") .set_discovery_type(ManifestDiscoveryType::env_var)); const char* regular_layer_name_2 = "VK_LAYER_RegularLayer2"; env.add_explicit_layer( TestLayerDetails( ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(regular_layer_name_2).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_2.json") .set_discovery_type(ManifestDiscoveryType::env_var)); InstWrapper inst(env.vulkan_functions); inst.create_info.add_layer(regular_layer_name_1); inst.create_info.add_layer(regular_layer_name_2); inst.CheckCreate(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); EXPECT_TRUE(check_permutation({regular_layer_name_1, regular_layer_name_2}, layer_props)); } TEST(ExplicitLayers, DuplicateLayersInVK_LAYER_PATH) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); // verify layer loads successfully when setting VK_LAYER_PATH to a full filepath const char* same_layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(same_layer_name_1) .set_description("actually_layer_1") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_1.json") // use override folder as just a folder and manually set the VK_LAYER_PATH env-var to it .set_discovery_type(ManifestDiscoveryType::override_folder) .set_is_dir(true)); auto& layer1 = env.get_test_layer(0); layer1.set_description("actually_layer_1"); layer1.set_make_spurious_log_in_create_instance("actually_layer_1"); env.env_var_vk_layer_paths.add_to_list(narrow(env.get_folder(ManifestLocation::override_layer).location())); env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(same_layer_name_1) .set_description("actually_layer_2") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_1.json") .set_discovery_type(ManifestDiscoveryType::env_var) .set_is_dir(true)); auto& layer2 = env.get_test_layer(1); layer2.set_description("actually_layer_2"); layer2.set_make_spurious_log_in_create_instance("actually_layer_2"); auto layer_props = env.GetLayerProperties(2); ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[0].layerName)); ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[1].layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description)); ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description)); { InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(same_layer_name_1); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(same_layer_name_1, enabled_layer_props.at(0).layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props.at(0).description)); ASSERT_TRUE(env.debug_log.find("actually_layer_1")); ASSERT_FALSE(env.debug_log.find("actually_layer_2")); } env.debug_log.clear(); { EnvVarWrapper layers_enable_env_var{"VK_INSTANCE_LAYERS", same_layer_name_1}; InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(same_layer_name_1, enabled_layer_props.at(0).layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props.at(0).description)); ASSERT_TRUE(env.debug_log.find("actually_layer_1")); ASSERT_FALSE(env.debug_log.find("actually_layer_2")); } env.debug_log.clear(); { EnvVarWrapper layers_enable_env_var{"VK_LOADER_LAYERS_ENABLE", same_layer_name_1}; InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(same_layer_name_1, enabled_layer_props.at(0).layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props.at(0).description)); ASSERT_TRUE(env.debug_log.find("actually_layer_1")); ASSERT_FALSE(env.debug_log.find("actually_layer_2")); } env.debug_log.clear(); } TEST(ExplicitLayers, DuplicateLayersInVK_ADD_LAYER_PATH) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* same_layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(same_layer_name_1) .set_description("actually_layer_1") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_1.json") // use override folder as just a folder and manually set the VK_ADD_LAYER_PATH env-var to it .set_discovery_type(ManifestDiscoveryType::override_folder) .set_is_dir(true)); auto& layer1 = env.get_test_layer(0); layer1.set_description("actually_layer_1"); layer1.set_make_spurious_log_in_create_instance("actually_layer_1"); env.add_env_var_vk_layer_paths.add_to_list(narrow(env.get_folder(ManifestLocation::override_layer).location())); env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(same_layer_name_1) .set_description("actually_layer_2") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_1.json") .set_discovery_type(ManifestDiscoveryType::add_env_var) .set_is_dir(true)); auto& layer2 = env.get_test_layer(1); layer2.set_description("actually_layer_2"); layer2.set_make_spurious_log_in_create_instance("actually_layer_2"); auto layer_props = env.GetLayerProperties(2); ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[0].layerName)); ASSERT_TRUE(string_eq(same_layer_name_1, layer_props[1].layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description)); ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description)); { InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(same_layer_name_1); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(same_layer_name_1, enabled_layer_props.at(0).layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props.at(0).description)); ASSERT_TRUE(env.debug_log.find("actually_layer_1")); ASSERT_FALSE(env.debug_log.find("actually_layer_2")); } env.debug_log.clear(); { EnvVarWrapper layers_enable_env_var{"VK_INSTANCE_LAYERS", same_layer_name_1}; InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(same_layer_name_1, enabled_layer_props.at(0).layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props.at(0).description)); ASSERT_TRUE(env.debug_log.find("actually_layer_1")); ASSERT_FALSE(env.debug_log.find("actually_layer_2")); } env.debug_log.clear(); { EnvVarWrapper layers_enable_env_var{"VK_LOADER_LAYERS_ENABLE", same_layer_name_1}; InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(same_layer_name_1, enabled_layer_props.at(0).layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props.at(0).description)); ASSERT_TRUE(env.debug_log.find("actually_layer_1")); ASSERT_FALSE(env.debug_log.find("actually_layer_2")); } env.debug_log.clear(); } TEST(ExplicitLayers, CorrectOrderOfEnvVarEnabledLayers) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name_1) .set_description("actually_layer_1") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_1.json") .set_discovery_type(ManifestDiscoveryType::env_var) .set_is_dir(true)); auto& layer1 = env.get_test_layer(0); layer1.set_description("actually_layer_1"); const char* layer_name_2 = "VK_LAYER_RegularLayer2"; env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name_2) .set_description("actually_layer_2") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_2.json") .set_discovery_type(ManifestDiscoveryType::env_var) .set_is_dir(true)); auto& layer2 = env.get_test_layer(1); layer2.set_description("actually_layer_2"); auto layer_props = env.GetLayerProperties(2); ASSERT_TRUE(string_eq(layer_name_1, layer_props[0].layerName)); ASSERT_TRUE(string_eq(layer_name_2, layer_props[1].layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description)); ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description)); // 1 then 2 { EnvVarWrapper inst_layers_env_var{"VK_INSTANCE_LAYERS"}; inst_layers_env_var.add_to_list(layer_name_1); inst_layers_env_var.add_to_list(layer_name_2); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); // Expect the env-var layer to be first auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props[0].description)); ASSERT_TRUE(string_eq(layer2.description.c_str(), enabled_layer_props[1].description)); ASSERT_TRUE(string_eq(layer_name_1, enabled_layer_props[0].layerName)); ASSERT_TRUE(string_eq(layer_name_2, enabled_layer_props[1].layerName)); } // 2 then 1 { EnvVarWrapper inst_layers_env_var{"VK_INSTANCE_LAYERS"}; inst_layers_env_var.add_to_list(layer_name_2); inst_layers_env_var.add_to_list(layer_name_1); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); // Expect the env-var layer to be first auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); ASSERT_TRUE(string_eq(layer2.description.c_str(), enabled_layer_props[0].description)); ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props[1].description)); ASSERT_TRUE(string_eq(layer_name_2, enabled_layer_props[0].layerName)); ASSERT_TRUE(string_eq(layer_name_1, enabled_layer_props[1].layerName)); } } // Test to make sure order layers are found in VK_LAYER_PATH is what decides which layer is loaded TEST(ExplicitLayers, DuplicateLayersInVkLayerPath) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* layer_name = "VK_LAYER_RegularLayer1"; env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name) .set_description("actually_layer_1") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "layer.json") .set_discovery_type(ManifestDiscoveryType::env_var) .set_is_dir(true)); auto& layer1 = env.get_test_layer(0); layer1.set_description("actually_layer_1"); env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name) .set_description("actually_layer_2") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "layer.json") // putting it in a separate folder then manually adding the folder to VK_LAYER_PATH .set_discovery_type(ManifestDiscoveryType::override_folder) .set_is_dir(true)); auto& layer2 = env.get_test_layer(1); layer2.set_description("actually_layer_2"); env.env_var_vk_layer_paths.add_to_list(env.get_folder(ManifestLocation::override_layer).location().string()); auto layer_props = env.GetLayerProperties(2); ASSERT_TRUE(string_eq(layer_name, layer_props[0].layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description)); ASSERT_TRUE(string_eq(layer_name, layer_props[1].layerName)); ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description)); EnvVarWrapper inst_layers_env_var{"VK_INSTANCE_LAYERS"}; inst_layers_env_var.add_to_list(layer_name); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); // Expect the first layer added to be found auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layer_name, enabled_layer_props[0].layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props[0].description)); } TEST(ExplicitLayers, CorrectOrderOfEnvVarEnabledLayersFromSystemLocations) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name_1) .set_description("actually_layer_1") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_1.json")); auto& layer1 = env.get_test_layer(0); layer1.set_description("actually_layer_1"); const char* layer_name_2 = "VK_LAYER_RegularLayer2"; env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name_2) .set_description("actually_layer_2") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_2.json")); auto& layer2 = env.get_test_layer(1); layer2.set_description("actually_layer_2"); auto layer_props = env.GetLayerProperties(2); ASSERT_TRUE(string_eq(layer_name_1, layer_props[0].layerName)); ASSERT_TRUE(string_eq(layer_name_2, layer_props[1].layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description)); ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description)); // 1 then 2 { EnvVarWrapper inst_layers_env_var{"VK_INSTANCE_LAYERS"}; inst_layers_env_var.add_to_list(layer_name_1); inst_layers_env_var.add_to_list(layer_name_2); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props[0].description)); ASSERT_TRUE(string_eq(layer2.description.c_str(), enabled_layer_props[1].description)); ASSERT_TRUE(string_eq(layer_name_1, enabled_layer_props[0].layerName)); ASSERT_TRUE(string_eq(layer_name_2, enabled_layer_props[1].layerName)); } // 2 then 1 { EnvVarWrapper inst_layers_env_var{"VK_INSTANCE_LAYERS"}; inst_layers_env_var.add_to_list(layer_name_2); inst_layers_env_var.add_to_list(layer_name_1); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); // Expect the env-var layer to be first auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); ASSERT_TRUE(string_eq(layer2.description.c_str(), enabled_layer_props[0].description)); ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props[1].description)); ASSERT_TRUE(string_eq(layer_name_2, enabled_layer_props[0].layerName)); ASSERT_TRUE(string_eq(layer_name_1, enabled_layer_props[1].layerName)); } } TEST(ExplicitLayers, CorrectOrderOfApplicationEnabledLayers) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* layer_name_1 = "VK_LAYER_RegularLayer1"; env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name_1) .set_description("actually_layer_1") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_1.json")); auto& layer1 = env.get_test_layer(0); layer1.set_description("actually_layer_1"); layer1.set_make_spurious_log_in_create_instance("actually_layer_1"); const char* layer_name_2 = "VK_LAYER_RegularLayer2"; env.add_explicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name_2) .set_description("actually_layer_2") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "regular_layer_2.json")); auto& layer2 = env.get_test_layer(1); layer2.set_description("actually_layer_2"); layer2.set_make_spurious_log_in_create_instance("actually_layer_2"); auto layer_props = env.GetLayerProperties(2); ASSERT_TRUE(string_eq(layer_name_1, layer_props[0].layerName)); ASSERT_TRUE(string_eq(layer_name_2, layer_props[1].layerName)); ASSERT_TRUE(string_eq(layer1.description.c_str(), layer_props[0].description)); ASSERT_TRUE(string_eq(layer2.description.c_str(), layer_props[1].description)); // 1 then 2 { InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(layer_name_1); inst.create_info.add_layer(layer_name_2); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); // Expect the env-var layer to be first auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props[0].description)); ASSERT_TRUE(string_eq(layer2.description.c_str(), enabled_layer_props[1].description)); ASSERT_TRUE(string_eq(layer_name_1, enabled_layer_props[0].layerName)); ASSERT_TRUE(string_eq(layer_name_2, enabled_layer_props[1].layerName)); } // 2 then 1 { InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(layer_name_2); inst.create_info.add_layer(layer_name_1); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); // Expect the env-var layer to be first auto enabled_layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 2); ASSERT_TRUE(string_eq(layer2.description.c_str(), enabled_layer_props[0].description)); ASSERT_TRUE(string_eq(layer1.description.c_str(), enabled_layer_props[1].description)); ASSERT_TRUE(string_eq(layer_name_2, enabled_layer_props[0].layerName)); ASSERT_TRUE(string_eq(layer_name_1, enabled_layer_props[1].layerName)); } } TEST(LayerExtensions, ImplicitNoAdditionalInstanceExtension) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); 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"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name)); // set enable env-var, layer should load EnvVarWrapper wrap_enable_env_var{enable_env_var, "1"}; CheckLogForLayerString(env, implicit_layer_name, true); auto extensions = env.GetInstanceExtensions(4); EXPECT_TRUE(string_eq(extensions.at(0).extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(1).extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(2).extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(3).extensionName, VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME)); // Make sure the extensions that are implemented only in the test layers is not present. ASSERT_FALSE(contains(extensions, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)); ASSERT_FALSE(contains(extensions, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); // Make sure all the function pointers are NULL as well handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkReleaseDisplayEXT")); handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT")); } TEST(LayerExtensions, ImplicitDirDispModeInstanceExtension) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); 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"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name)); // set enable env-var, layer should load EnvVarWrapper wrap_enable_env_var{enable_env_var, "1"}; CheckLogForLayerString(env, implicit_layer_name, true); auto extensions = env.GetInstanceExtensions(5); EXPECT_TRUE(string_eq(extensions.at(0).extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(1).extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(2).extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(3).extensionName, VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(4).extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)); // Make sure the extensions that are implemented only in the test layers is not present. ASSERT_FALSE(contains(extensions, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)); 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 handle_assert_has_value(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkReleaseDisplayEXT")); handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT")); } TEST(LayerExtensions, ImplicitDispSurfCountInstanceExtension) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); 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"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name)); // set enable env-var, layer should load EnvVarWrapper wrap_enable_env_var{enable_env_var, "1"}; CheckLogForLayerString(env, implicit_layer_name, true); auto extensions = env.GetInstanceExtensions(5); EXPECT_TRUE(string_eq(extensions.at(0).extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(1).extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(2).extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(3).extensionName, VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(4).extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)); 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 handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkReleaseDisplayEXT")); handle_assert_has_value(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT")); } TEST(LayerExtensions, ImplicitBothInstanceExtensions) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); 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"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name)); // set enable env-var, layer should load EnvVarWrapper wrap_enable_env_var{enable_env_var, "1"}; CheckLogForLayerString(env, implicit_layer_name, true); auto extensions = env.GetInstanceExtensions(6); EXPECT_TRUE(string_eq(extensions.at(0).extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(1).extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(2).extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(3).extensionName, VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(4).extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(5).extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)); 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 handle_assert_has_value(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkReleaseDisplayEXT")); handle_assert_has_value(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT")); } TEST(LayerExtensions, ExplicitNoAdditionalInstanceExtension) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); 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"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, explicit_layer_name)); auto extensions = env.GetInstanceExtensions(4); EXPECT_TRUE(string_eq(extensions.at(0).extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(1).extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(2).extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(3).extensionName, VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME)); // Now query by layer name. ASSERT_NO_FATAL_FAILURE(env.GetInstanceExtensions(0, explicit_layer_name)); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); // Make sure all the function pointers are NULL as well handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkReleaseDisplayEXT")); handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT")); } TEST(LayerExtensions, ExplicitDirDispModeInstanceExtension) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); 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"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, explicit_layer_name)); auto extensions = env.GetInstanceExtensions(4); EXPECT_TRUE(string_eq(extensions.at(0).extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(1).extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(2).extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(3).extensionName, VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME)); // Now query by layer name. auto layer_extensions = env.GetInstanceExtensions(1, explicit_layer_name); EXPECT_TRUE(string_eq(layer_extensions.at(0).extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)); 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 handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst1.inst, "vkReleaseDisplayEXT")); handle_assert_null(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 handle_assert_has_value(env.vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkReleaseDisplayEXT")); handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT")); } TEST(LayerExtensions, ExplicitDispSurfCountInstanceExtension) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); 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"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, explicit_layer_name)); auto extensions = env.GetInstanceExtensions(4); EXPECT_TRUE(string_eq(extensions.at(0).extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(1).extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(2).extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(3).extensionName, VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME)); // Now query by layer name. auto layer_extensions = env.GetInstanceExtensions(1, explicit_layer_name); EXPECT_TRUE(string_eq(layer_extensions.at(0).extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)); 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 handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst1.inst, "vkReleaseDisplayEXT")); handle_assert_null(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 handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkReleaseDisplayEXT")); handle_assert_has_value(env.vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkGetPhysicalDeviceSurfaceCapabilities2EXT")); } TEST(LayerExtensions, ExplicitBothInstanceExtensions) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); 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"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, explicit_layer_name)); auto extensions = env.GetInstanceExtensions(4); EXPECT_TRUE(string_eq(extensions.at(0).extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(1).extensionName, VK_EXT_DEBUG_UTILS_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(2).extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)); EXPECT_TRUE(string_eq(extensions.at(3).extensionName, VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME)); // Make sure the extensions still aren't present in this layer auto layer_extensions = env.GetInstanceExtensions(2, explicit_layer_name); EXPECT_TRUE(string_eq(layer_extensions.at(0).extensionName, VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME)); EXPECT_TRUE(string_eq(layer_extensions.at(1).extensionName, VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)); 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 handle_assert_null(env.vulkan_functions.vkGetInstanceProcAddr(inst1.inst, "vkReleaseDisplayEXT")); handle_assert_null(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(); VkPhysicalDevice phys_dev = inst2.GetPhysDev(); // Make sure only the appropriate function pointers are NULL as well handle_assert_has_value(env.vulkan_functions.vkGetInstanceProcAddr(inst2.inst, "vkReleaseDisplayEXT")); PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT pfnGetPhysicalDeviceSurfaceCapabilities2EXT = inst2.load("vkGetPhysicalDeviceSurfaceCapabilities2EXT"); handle_assert_has_value(pfnGetPhysicalDeviceSurfaceCapabilities2EXT); VkSurfaceCapabilities2EXT surf_caps{VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT}; // Call and then check a few things ASSERT_EQ(VK_SUCCESS, pfnGetPhysicalDeviceSurfaceCapabilities2EXT(phys_dev, VK_NULL_HANDLE, &surf_caps)); ASSERT_EQ(7U, surf_caps.minImageCount); ASSERT_EQ(12U, surf_caps.maxImageCount); ASSERT_EQ(365U, surf_caps.maxImageArrayLayers); } TEST(LayerExtensions, ImplicitNoAdditionalDeviceExtension) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); 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"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name)); // set enable env-var, layer should load EnvVarWrapper wrap_enable_env_var{enable_env_var, "1"}; CheckLogForLayerString(env, implicit_layer_name, true); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); VkPhysicalDevice phys_dev = inst.GetPhysDev(); ASSERT_NO_FATAL_FAILURE(inst.EnumerateDeviceExtensions(phys_dev, 0)); // Device functions queried using vkGetInstanceProcAddr should be non-NULL since this could be available for any attached // physical device. PFN_vkTrimCommandPoolKHR pfn_vkTrimCommandPool = inst.load("vkTrimCommandPoolKHR"); PFN_vkGetSwapchainStatusKHR pfn_vkGetSwapchainStatus = inst.load("vkGetSwapchainStatusKHR"); PFN_vkSetDeviceMemoryPriorityEXT pfn_vkSetDeviceMemoryPriority = inst.load("vkSetDeviceMemoryPriorityEXT"); handle_assert_has_value(pfn_vkTrimCommandPool); handle_assert_has_value(pfn_vkGetSwapchainStatus); handle_assert_has_value(pfn_vkSetDeviceMemoryPriority); DeviceWrapper dev{inst}; dev.CheckCreate(phys_dev); // Query again after create device to make sure the value returned by vkGetInstanceProcAddr did not change PFN_vkTrimCommandPoolKHR pfn_vkTrimCommandPool2 = inst.load("vkTrimCommandPoolKHR"); PFN_vkGetSwapchainStatusKHR pfn_vkGetSwapchainStatus2 = inst.load("vkGetSwapchainStatusKHR"); PFN_vkSetDeviceMemoryPriorityEXT pfn_vkSetDeviceMemoryPriority2 = inst.load("vkSetDeviceMemoryPriorityEXT"); ASSERT_EQ(pfn_vkTrimCommandPool, pfn_vkTrimCommandPool2); ASSERT_EQ(pfn_vkGetSwapchainStatus, pfn_vkGetSwapchainStatus2); ASSERT_EQ(pfn_vkSetDeviceMemoryPriority, pfn_vkSetDeviceMemoryPriority2); // Make sure all the function pointers returned by vkGetDeviceProcAddr for non-enabled extensions are NULL handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkTrimCommandPoolKHR")); handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkGetSwapchainStatusKHR")); handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkSetDeviceMemoryPriorityEXT")); // Even though the instance functions returned are non-NULL. They should not work if we haven't enabled the extensions. ASSERT_DEATH(pfn_vkTrimCommandPool(dev.dev, VK_NULL_HANDLE, 0), ""); ASSERT_DEATH(pfn_vkGetSwapchainStatus(dev.dev, VK_NULL_HANDLE), ""); ASSERT_DEATH(pfn_vkSetDeviceMemoryPriority(dev.dev, VK_NULL_HANDLE, 0.f), ""); } TEST(LayerExtensions, ImplicitMaintenanceDeviceExtension) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); 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)), "implicit_wrap_layer_maint.json"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name)); // set enable env-var, layer should load EnvVarWrapper wrap_enable_env_var{enable_env_var, "1"}; CheckLogForLayerString(env, implicit_layer_name, true); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); VkPhysicalDevice phys_dev = inst.GetPhysDev(); auto device_extensions = inst.EnumerateDeviceExtensions(phys_dev, 1); ASSERT_TRUE(string_eq(device_extensions.at(0).extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME)); DeviceWrapper dev{inst}; dev.create_info.add_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME); dev.CheckCreate(phys_dev); // Make sure only the appropriate function pointers are NULL as well handle_assert_has_value(dev->vkGetDeviceProcAddr(dev.dev, "vkTrimCommandPoolKHR")); handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkGetSwapchainStatusKHR")); } TEST(LayerExtensions, ImplicitPresentImageDeviceExtension) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); 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)), "implicit_wrap_layer_pres.json"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name)); // set enable env-var, layer should load EnvVarWrapper wrap_enable_env_var{enable_env_var, "1"}; CheckLogForLayerString(env, implicit_layer_name, true); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); VkPhysicalDevice phys_dev = inst.GetPhysDev(); auto device_extensions = inst.EnumerateDeviceExtensions(phys_dev, 1); ASSERT_TRUE(string_eq(device_extensions.at(0).extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)); DeviceWrapper dev{inst}; dev.create_info.add_extension(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME); dev.CheckCreate(phys_dev); // Make sure only the appropriate function pointers are NULL as well handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkTrimCommandPoolKHR")); handle_assert_has_value(dev->vkGetDeviceProcAddr(dev.dev, "vkGetSwapchainStatusKHR")); } TEST(LayerExtensions, ImplicitBothDeviceExtensions) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); 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)), "implicit_wrap_layer_both_dev.json"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, implicit_layer_name)); // set enable env-var, layer should load EnvVarWrapper wrap_enable_env_var{enable_env_var, "1"}; CheckLogForLayerString(env, implicit_layer_name, true); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); VkPhysicalDevice phys_dev = inst.GetPhysDev(); auto device_extensions = inst.EnumerateDeviceExtensions(phys_dev, 2); ASSERT_TRUE(string_eq(device_extensions.at(0).extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME)); ASSERT_TRUE(string_eq(device_extensions.at(1).extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)); DeviceWrapper dev{inst}; dev.create_info.add_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME).add_extension(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME); dev.CheckCreate(phys_dev); // Make sure only the appropriate function pointers are NULL as well handle_assert_has_value(dev->vkGetDeviceProcAddr(dev.dev, "vkTrimCommandPoolKHR")); handle_assert_has_value(dev->vkGetDeviceProcAddr(dev.dev, "vkGetSwapchainStatusKHR")); } TEST(LayerExtensions, ExplicitNoAdditionalDeviceExtension) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); 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"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, explicit_layer_name)); InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(explicit_layer_name); inst.CheckCreate(); VkPhysicalDevice phys_dev = inst.GetPhysDev(); ASSERT_NO_FATAL_FAILURE(inst.EnumerateDeviceExtensions(phys_dev, 0)); ASSERT_NO_FATAL_FAILURE(inst.EnumerateLayerDeviceExtensions(phys_dev, explicit_layer_name, 0)); DeviceWrapper dev{inst}; dev.CheckCreate(phys_dev); // Make sure all the function pointers are NULL as well handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkTrimCommandPoolKHR")); handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkGetSwapchainStatusKHR")); handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkSetDeviceMemoryPriorityEXT")); } TEST(LayerExtensions, ExplicitMaintenanceDeviceExtension) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); 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) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0)) .add_device_extension({VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1, {"vkTrimCommandPoolKHR"}})), "explicit_wrap_layer_maint.json"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, explicit_layer_name)); InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(explicit_layer_name); inst.CheckCreate(); VkPhysicalDevice phys_dev = inst.GetPhysDev(); ASSERT_NO_FATAL_FAILURE(inst.EnumerateDeviceExtensions(phys_dev, 0)); auto layer_extensions = inst.EnumerateLayerDeviceExtensions(phys_dev, explicit_layer_name, 1); ASSERT_TRUE(string_eq(layer_extensions.at(0).extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME)); DeviceWrapper dev{inst}; dev.create_info.add_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME); dev.CheckCreate(phys_dev); // Make sure only the appropriate function pointers are NULL as well handle_assert_has_value(dev->vkGetDeviceProcAddr(dev.dev, "vkTrimCommandPoolKHR")); handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkGetSwapchainStatusKHR")); } TEST(LayerExtensions, ExplicitPresentImageDeviceExtension) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); 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) .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_pres.json"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, explicit_layer_name)); InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(explicit_layer_name); inst.CheckCreate(); VkPhysicalDevice phys_dev = inst.GetPhysDev(); ASSERT_NO_FATAL_FAILURE(inst.EnumerateDeviceExtensions(phys_dev, 0)); auto layer_extensions = inst.EnumerateLayerDeviceExtensions(phys_dev, explicit_layer_name, 1); ASSERT_TRUE(string_eq(layer_extensions.at(0).extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)); DeviceWrapper dev{inst}; dev.create_info.add_extension(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME); dev.CheckCreate(phys_dev); // Make sure only the appropriate function pointers are NULL as well handle_assert_null(dev->vkGetDeviceProcAddr(dev.dev, "vkTrimCommandPoolKHR")); handle_assert_has_value(dev->vkGetDeviceProcAddr(dev.dev, "vkGetSwapchainStatusKHR")); } TEST(LayerExtensions, ExplicitBothDeviceExtensions) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); 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"); auto layers = env.GetLayerProperties(1); ASSERT_TRUE(string_eq(layers[0].layerName, explicit_layer_name)); InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(explicit_layer_name); inst.CheckCreate(); VkPhysicalDevice phys_dev = inst.GetPhysDev(); handle_assert_has_value(phys_dev); ASSERT_NO_FATAL_FAILURE(inst.EnumerateDeviceExtensions(phys_dev, 0)); auto layer_extensions = inst.EnumerateLayerDeviceExtensions(phys_dev, explicit_layer_name, 2); ASSERT_TRUE(string_eq(layer_extensions.at(0).extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME)); ASSERT_TRUE(string_eq(layer_extensions.at(1).extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)); DeviceWrapper dev{inst}; dev.create_info.add_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME).add_extension(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME); dev.CheckCreate(phys_dev); // Make sure only the appropriate function pointers are NULL as well handle_assert_has_value(dev->vkGetDeviceProcAddr(dev.dev, "vkTrimCommandPoolKHR")); PFN_vkGetSwapchainStatusKHR gipa_pfnGetSwapchainStatusKHR = inst.load("vkGetSwapchainStatusKHR"); PFN_vkGetSwapchainStatusKHR gdpa_pfnGetSwapchainStatusKHR = dev.load("vkGetSwapchainStatusKHR"); handle_assert_has_value(gipa_pfnGetSwapchainStatusKHR); handle_assert_has_value(gdpa_pfnGetSwapchainStatusKHR); // Make sure both versions (from vkGetInstanceProcAddr and vkGetDeviceProcAddr) return the same value. ASSERT_EQ(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, gipa_pfnGetSwapchainStatusKHR(dev.dev, VK_NULL_HANDLE)); ASSERT_EQ(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, gdpa_pfnGetSwapchainStatusKHR(dev.dev, VK_NULL_HANDLE)); } TEST(TestLayers, ExplicitlyEnableImplicitLayer) { FrameworkEnvironment env; uint32_t api_version = VK_API_VERSION_1_2; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, api_version)) .set_icd_api_version(api_version) .add_physical_device(PhysicalDevice{}.set_api_version(api_version).finish()); const char* regular_layer_name = "VK_LAYER_TestLayer1"; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .set_disable_environment("DisableMeIfYouCan")), "regular_test_layer.json"); { // 1.1 instance InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(regular_layer_name); inst.create_info.set_api_version(1, 1, 0); inst.CheckCreate(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(regular_layer_name, layer_props.at(0).layerName)); } { // 1.2 instance InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(regular_layer_name); inst.create_info.set_api_version(1, 2, 0); inst.CheckCreate(); inst.GetActiveLayers(inst.GetPhysDev(), 1); } } TEST(TestLayers, NewerInstanceVersionThanImplicitLayer) { FrameworkEnvironment env; uint32_t api_version = VK_API_VERSION_1_2; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, api_version)) .set_icd_api_version(api_version) .add_physical_device(PhysicalDevice{}.set_api_version(api_version).finish()); const char* regular_layer_name = "VK_LAYER_TestLayer1"; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .set_disable_environment("DisableMeIfYouCan")), "regular_test_layer.json"); { // global functions auto layer_props = env.GetLayerProperties(1); EXPECT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name)); } { // 1.1 instance - should find the implicit layer InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(1, 1, 0); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); EXPECT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name)); env.debug_log.clear(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(regular_layer_name, layer_props.at(0).layerName)); } { // 1.2 instance -- instance layer should be found InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(1, 2, 0); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); EXPECT_TRUE(env.debug_log.find(std::string("Insert instance layer \"") + regular_layer_name)); env.debug_log.clear(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(regular_layer_name, layer_props.at(0).layerName)); } } TEST(TestLayers, ImplicitLayerPre10APIVersion) { FrameworkEnvironment env; uint32_t api_version = VK_API_VERSION_1_2; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, api_version)) .set_icd_api_version(api_version) .add_physical_device(PhysicalDevice{}.set_api_version(api_version).finish()); const char* regular_layer_name = "VK_LAYER_TestLayer1"; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(regular_layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 0, 1, 0)) .set_disable_environment("DisableMeIfYouCan")), "regular_test_layer.json"); { // global functions auto layer_props = env.GetLayerProperties(1); EXPECT_TRUE(string_eq(layer_props[0].layerName, regular_layer_name)); } { // 1.0 instance DebugUtilsLogger log; InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(1, 0, 0); FillDebugUtilsCreateDetails(inst.create_info, log); inst.CheckCreate(); EXPECT_TRUE(log.find(std::string("Insert instance layer \"") + regular_layer_name)); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(regular_layer_name, layer_props.at(0).layerName)); } { // 1.1 instance DebugUtilsLogger log; InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(1, 1, 0); FillDebugUtilsCreateDetails(inst.create_info, log); inst.CheckCreate(); EXPECT_TRUE(log.find(std::string("Insert instance layer \"") + regular_layer_name)); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(regular_layer_name, layer_props.at(0).layerName)); } { // 1.2 instance DebugUtilsLogger log; InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(1, 2, 0); FillDebugUtilsCreateDetails(inst.create_info, log); inst.CheckCreate(); EXPECT_TRUE(log.find(std::string("Insert instance layer \"") + regular_layer_name)); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(regular_layer_name, layer_props.at(0).layerName)); } { // application sets its API version to 0 DebugUtilsLogger log; InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(0); FillDebugUtilsCreateDetails(inst.create_info, log); inst.CheckCreate(); EXPECT_TRUE(log.find(std::string("Insert instance layer \"") + regular_layer_name)); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(regular_layer_name, layer_props.at(0).layerName)); } } // 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, InstEnvironEnableExplicitLayer) { FrameworkEnvironment env; uint32_t api_version = VK_API_VERSION_1_2; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, api_version)) .set_icd_api_version(api_version) .add_physical_device(PhysicalDevice{}.set_api_version(api_version).finish()); 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(); ASSERT_NO_FATAL_FAILURE(inst1.EnumerateDeviceExtensions(phys_dev1, 0)); // Create a device and query the function pointers DeviceWrapper dev1{inst1}; dev1.CheckCreate(phys_dev1); PFN_vkTrimCommandPoolKHR pfn_TrimCommandPoolBefore = dev1.load("vkTrimCommandPoolKHR"); PFN_vkGetSwapchainStatusKHR pfn_GetSwapchainStatusBefore = dev1.load("vkGetSwapchainStatusKHR"); handle_assert_null(pfn_TrimCommandPoolBefore); handle_assert_null(pfn_GetSwapchainStatusBefore); // Now setup the instance layer EnvVarWrapper instance_layers_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(); auto layer_extensions = inst2.EnumerateLayerDeviceExtensions(phys_dev2, explicit_layer_name, 2); ASSERT_TRUE(string_eq(layer_extensions.at(0).extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME)); ASSERT_TRUE(string_eq(layer_extensions.at(1).extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME)); DeviceWrapper dev2{inst2}; dev2.create_info.add_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME) .add_extension(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME); dev2.CheckCreate(phys_dev2); PFN_vkTrimCommandPoolKHR pfn_TrimCommandPoolAfter = dev2.load("vkTrimCommandPoolKHR"); PFN_vkGetSwapchainStatusKHR pfn_GetSwapchainStatusAfter = dev2.load("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)); } // Verify that VK_LOADER_LAYERS_ENABLE work. To test this, make sure that an explicit layer does not affect an instance until // it is set with VK_LOADER_LAYERS_ENABLE TEST(TestLayers, EnvironLayerEnableExplicitLayer) { FrameworkEnvironment env; uint32_t api_version = VK_API_VERSION_1_2; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, api_version)) .set_icd_api_version(api_version) .add_physical_device(PhysicalDevice{}); const char* explicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer"; const char* explicit_json_name_1 = "First_layer.json"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(explicit_layer_name_1) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), explicit_json_name_1); const char* explicit_layer_name_2 = "VK_LAYER_LUNARG_Second_layer"; const char* explicit_json_name_2 = "Second_layer.json"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(explicit_layer_name_2) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), explicit_json_name_2); const char* explicit_layer_name_3 = "VK_LAYER_LUNARG_second_test_layer"; const char* explicit_json_name_3 = "second_test_layer.json"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(explicit_layer_name_3) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), explicit_json_name_3); EnvVarWrapper layers_enable_env_var{"VK_LOADER_LAYERS_ENABLE"}; // First, test an instance/device without the layer forced on. InstWrapper inst1{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log); inst1.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Now force on one layer with its full name // ------------------------------------------ env.debug_log.clear(); layers_enable_env_var.set_new_value(explicit_layer_name_1); InstWrapper inst2{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log); inst2.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Match prefix // ------------------------------------------ env.debug_log.clear(); layers_enable_env_var.set_new_value("VK_LAYER_LUNARG_*"); InstWrapper inst3{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst3.create_info, env.debug_log); inst3.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Match suffix // ------------------------------------------ env.debug_log.clear(); layers_enable_env_var.set_new_value("*Second_layer"); InstWrapper inst4{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst4.create_info, env.debug_log); inst4.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Match substring // ------------------------------------------ env.debug_log.clear(); layers_enable_env_var.set_new_value("*Second*"); InstWrapper inst5{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst5.create_info, env.debug_log); inst5.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Match all with star '*' // ------------------------------------------ env.debug_log.clear(); layers_enable_env_var.set_new_value("*"); InstWrapper inst6{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst6.create_info, env.debug_log); inst6.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Match all with special name // ------------------------------------------ env.debug_log.clear(); layers_enable_env_var.set_new_value("~all~"); InstWrapper inst7{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst7.create_info, env.debug_log); inst7.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); } // Verify that VK_LOADER_LAYERS_DISABLE work. To test this, make sure that an explicit layer does not affect an instance until // it is set with VK_LOADER_LAYERS_DISABLE TEST(TestLayers, EnvironLayerDisableExplicitLayer) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2)) .set_icd_api_version(VK_API_VERSION_1_2) .add_physical_device(PhysicalDevice{}); const char* explicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer"; const char* explicit_json_name_1 = "First_layer.json"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(explicit_layer_name_1) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), explicit_json_name_1); const char* explicit_layer_name_2 = "VK_LAYER_LUNARG_Second_layer"; const char* explicit_json_name_2 = "Second_layer.json"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(explicit_layer_name_2) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), explicit_json_name_2); const char* explicit_layer_name_3 = "VK_LAYER_LUNARG_Second_test_layer"; const char* explicit_json_name_3 = "Second_test_layer.json"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(explicit_layer_name_3) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), explicit_json_name_3); EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE"}; // First, test an instance/device without the layer forced on. InstWrapper inst1{env.vulkan_functions}; inst1.create_info.add_layer(explicit_layer_name_1).add_layer(explicit_layer_name_2).add_layer(explicit_layer_name_3); FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst1.CheckCreate()); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Now force on one layer with its full name // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value(explicit_layer_name_1); InstWrapper inst2{env.vulkan_functions}; inst2.create_info.add_layer(explicit_layer_name_1).add_layer(explicit_layer_name_2).add_layer(explicit_layer_name_3); FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst2.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Match prefix // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("VK_LAYER_LUNARG_*"); InstWrapper inst3{env.vulkan_functions}; inst3.create_info.add_layer(explicit_layer_name_1).add_layer(explicit_layer_name_2).add_layer(explicit_layer_name_3); FillDebugUtilsCreateDetails(inst3.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst3.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Match suffix // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("*Second_layer"); InstWrapper inst4{env.vulkan_functions}; inst4.create_info.add_layer(explicit_layer_name_1).add_layer(explicit_layer_name_2).add_layer(explicit_layer_name_3); FillDebugUtilsCreateDetails(inst4.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst4.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Match substring // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("*Second*"); InstWrapper inst5{env.vulkan_functions}; inst5.create_info.add_layer(explicit_layer_name_1).add_layer(explicit_layer_name_2).add_layer(explicit_layer_name_3); FillDebugUtilsCreateDetails(inst5.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst5.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Match all with star '*' // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("*"); InstWrapper inst6{env.vulkan_functions}; inst6.create_info.add_layer(explicit_layer_name_1).add_layer(explicit_layer_name_2).add_layer(explicit_layer_name_3); FillDebugUtilsCreateDetails(inst6.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst6.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Match all with special name // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("~all~"); InstWrapper inst7{env.vulkan_functions}; inst7.create_info.add_layer(explicit_layer_name_1).add_layer(explicit_layer_name_2).add_layer(explicit_layer_name_3); FillDebugUtilsCreateDetails(inst7.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst7.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Match explicit special name // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("~explicit~"); InstWrapper inst8{env.vulkan_functions}; inst8.create_info.add_layer(explicit_layer_name_1).add_layer(explicit_layer_name_2).add_layer(explicit_layer_name_3); FillDebugUtilsCreateDetails(inst8.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst8.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // No match implicit special name // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("~implicit~"); InstWrapper inst9{env.vulkan_functions}; inst9.create_info.add_layer(explicit_layer_name_1).add_layer(explicit_layer_name_2).add_layer(explicit_layer_name_3); FillDebugUtilsCreateDetails(inst9.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst9.CheckCreate()); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); } // Verify that VK_LOADER_LAYERS_ENABLE + VK_LOADER_LAYERS_DISABLE work.(results in the layer still being // enabled) TEST(TestLayers, EnvironLayerEnableDisableExplicitLayer) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2)) .set_icd_api_version(VK_API_VERSION_1_2); const char* explicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer"; const char* explicit_json_name_1 = "First_layer.json"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(explicit_layer_name_1) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), explicit_json_name_1); const char* explicit_layer_name_2 = "VK_LAYER_LUNARG_Second_layer"; const char* explicit_json_name_2 = "Second_layer.json"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(explicit_layer_name_2) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), explicit_json_name_2); const char* explicit_layer_name_3 = "VK_LAYER_LUNARG_Second_test_layer"; const char* explicit_json_name_3 = "Second_test_layer.json"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(explicit_layer_name_3) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), explicit_json_name_3); EnvVarWrapper layers_enable_env_var{"VK_LOADER_LAYERS_ENABLE"}; EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE"}; // First, test an instance/device without the layer forced on. InstWrapper inst1{env.vulkan_functions}; inst1.create_info.add_layer(explicit_layer_name_1).add_layer(explicit_layer_name_2).add_layer(explicit_layer_name_3); FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst1.CheckCreate()); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Disable 2 but enable 1 // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("*Second*"); layers_enable_env_var.set_new_value("*test_layer"); InstWrapper inst2{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst2.CheckCreate()); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Disable all but enable 2 // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("*"); layers_enable_env_var.set_new_value("*Second*"); InstWrapper inst3{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst3.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst3.CheckCreate()); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Disable all but enable 2 // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("~all~"); layers_enable_env_var.set_new_value("*Second*"); InstWrapper inst4{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst4.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst4.CheckCreate()); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Disable explicit but enable 2 // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("~explicit~"); layers_enable_env_var.set_new_value("*Second*"); InstWrapper inst5{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst5.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst5.CheckCreate()); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Disable implicit but enable 2 (should still be everything) // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("~implicit~"); layers_enable_env_var.set_new_value("*Second*"); InstWrapper inst6{env.vulkan_functions}; inst6.create_info.add_layer(explicit_layer_name_1).add_layer(explicit_layer_name_2).add_layer(explicit_layer_name_3); FillDebugUtilsCreateDetails(inst6.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst6.CheckCreate()); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); // Disable explicit but enable all // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("~explicit~"); layers_enable_env_var.set_new_value("*"); InstWrapper inst7{env.vulkan_functions}; inst7.create_info.add_layer(explicit_layer_name_1).add_layer(explicit_layer_name_2).add_layer(explicit_layer_name_3); FillDebugUtilsCreateDetails(inst7.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst7.CheckCreate()); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_3)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_3, "disabled because name matches filter of env var")); } // Verify that VK_INSTANCE_LAYERS + VK_LOADER_LAYERS_DISABLE work.(results in the layer still being // enabled) TEST(TestLayers, EnvironVkInstanceLayersAndDisableFilters) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2)) .set_icd_api_version(VK_API_VERSION_1_2); const char* explicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer"; const char* explicit_json_name_1 = "First_layer.json"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(explicit_layer_name_1) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), explicit_json_name_1); const char* explicit_layer_name_2 = "VK_LAYER_LUNARG_Second_layer"; const char* explicit_json_name_2 = "Second_layer.json"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(explicit_layer_name_2) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), explicit_json_name_2); EnvVarWrapper layers_enable_env_var{"VK_INSTANCE_LAYERS"}; EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE"}; // First, test an instance/device without the layer forced on. InstWrapper inst1{env.vulkan_functions}; inst1.create_info.add_layer(explicit_layer_name_1); FillDebugUtilsCreateDetails(inst1.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst1.CheckCreate()); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); // Enable the non-default enabled layer with VK_INSTANCE_LAYERS // ------------------------------------------ env.debug_log.clear(); layers_enable_env_var.set_new_value(explicit_layer_name_2); InstWrapper inst2{env.vulkan_functions}; inst2.create_info.add_layer(explicit_layer_name_1); FillDebugUtilsCreateDetails(inst2.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst2.CheckCreate()); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); // Try to disable all // ------------------------------------------ env.debug_log.clear(); layers_disable_env_var.set_new_value("*"); InstWrapper inst3{env.vulkan_functions}; inst3.create_info.add_layer(explicit_layer_name_1); FillDebugUtilsCreateDetails(inst3.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst3.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer", explicit_layer_name_2)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_2, "disabled because name matches filter of env var")); } // Verify that layers enabled through VK_INSTANCE_LAYERS which were not found get the proper error message TEST(TestLayers, NonExistantLayerInVK_INSTANCE_LAYERS) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* layer_name = "VK_LAYER_test_layer"; env.add_explicit_layer( ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "test_layer.json"); EnvVarWrapper layers_enable_env_var{"VK_INSTANCE_LAYERS", "VK_LAYER_I_dont_exist"}; { InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); ASSERT_TRUE( env.debug_log.find("Layer \"VK_LAYER_I_dont_exist\" was not found but was requested by env var VK_INSTANCE_LAYERS!")); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } // Make sure layers that do exist are loaded env.debug_log.clear(); layers_enable_env_var.add_to_list(layer_name); { InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); ASSERT_TRUE( env.debug_log.find("Layer \"VK_LAYER_I_dont_exist\" was not found but was requested by env var VK_INSTANCE_LAYERS!")); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layer_props.at(0).layerName, layer_name)); } // Make sure that if the layer appears twice in the env-var nothing bad happens env.debug_log.clear(); layers_enable_env_var.add_to_list("VK_LAYER_I_dont_exist"); { InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); ASSERT_TRUE( env.debug_log.find("Layer \"VK_LAYER_I_dont_exist\" was not found but was requested by env var VK_INSTANCE_LAYERS!")); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layer_props.at(0).layerName, layer_name)); } } // Verify that if the same layer appears twice in VK_INSTANCE_LAYERS nothing bad happens TEST(TestLayers, DuplicatesInEnvironVK_INSTANCE_LAYERS) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)).add_physical_device({}); const char* layer_name = "VK_LAYER_test_layer"; env.add_explicit_layer( ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "test_layer.json"); EnvVarWrapper layers_enable_env_var{"VK_INSTANCE_LAYERS"}; layers_enable_env_var.add_to_list(layer_name); layers_enable_env_var.add_to_list(layer_name); InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); auto layer_props = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layer_props.at(0).layerName, layer_name)); } TEST(TestLayers, AppEnabledExplicitLayerFails) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2)) .set_icd_api_version(VK_API_VERSION_1_2); const char* explicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer"; const char* explicit_json_name_1 = "First_layer.json"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(explicit_layer_name_1) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 0, 0))), explicit_json_name_1); env.debug_log.clear(); EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE", explicit_layer_name_1}; ASSERT_NO_FATAL_FAILURE(env.GetLayerProperties(0)); InstWrapper inst3{env.vulkan_functions}; inst3.create_info.add_layer(explicit_layer_name_1); FillDebugUtilsCreateDetails(inst3.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst3.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer ", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); } TEST(TestLayers, OverrideEnabledExplicitLayerWithDisableFilter) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2)) .set_icd_api_version(VK_API_VERSION_1_2); const char* explicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer"; const char* explicit_json_name_1 = "First_layer.json"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(explicit_layer_name_1) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))), explicit_json_name_1); env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_component_layer(explicit_layer_name_1) .set_disable_environment("DisableMeIfYouCan")), "meta_test_layer.json"); env.debug_log.clear(); EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE", explicit_layer_name_1}; auto layers = env.GetLayerProperties(1); EXPECT_TRUE(string_eq(lunarg_meta_layer_name, layers[0].layerName)); { // both override layer and Disable env var InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer ", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE( env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); } env.debug_log.clear(); { // Now try to enable the explicit layer as well InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(explicit_layer_name_1); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer ", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE( env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); } } TEST(TestLayers, OverrideEnabledExplicitLayerWithDisableFilterForOverrideLayer) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2)) .set_icd_api_version(VK_API_VERSION_1_2); const char* explicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer"; const char* explicit_json_name_1 = "First_layer.json"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(explicit_layer_name_1) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))), explicit_json_name_1); env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_component_layer(explicit_layer_name_1) .set_disable_environment("DisableMeIfYouCan")), "meta_test_layer.json"); env.debug_log.clear(); EnvVarWrapper layers_disable_env_var{"VK_LOADER_LAYERS_DISABLE", lunarg_meta_layer_name}; auto layers = env.GetLayerProperties(1); EXPECT_TRUE(string_eq(explicit_layer_name_1, layers[0].layerName)); { // both override layer and Disable env var InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix("Insert instance layer ", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE( env.debug_log.find_prefix_then_postfix(lunarg_meta_layer_name, "disabled because name matches filter of env var")); } env.debug_log.clear(); { // Now try to enable the explicit layer as well InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(explicit_layer_name_1); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); inst.CheckCreate(); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer ", explicit_layer_name_1)); ASSERT_FALSE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_TRUE( env.debug_log.find_prefix_then_postfix(lunarg_meta_layer_name, "disabled because name matches filter of env var")); } } TEST(TestLayers, OverrideBlacklistedLayerWithEnableFilter) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2)) .set_icd_api_version(VK_API_VERSION_1_2); const char* explicit_layer_name_1 = "VK_LAYER_LUNARG_First_layer"; const char* explicit_json_name_1 = "First_layer.json"; env.add_explicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(explicit_layer_name_1) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0))), explicit_json_name_1); env.add_implicit_layer( ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer(ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_blacklisted_layer(explicit_layer_name_1) .set_disable_environment("DisableMeIfYouCan")), "meta_test_layer.json"); env.debug_log.clear(); EnvVarWrapper layers_enable_env_var{"VK_LOADER_LAYERS_ENABLE", explicit_layer_name_1}; auto layers = env.GetLayerProperties(1); EXPECT_TRUE(string_eq(explicit_layer_name_1, layers[0].layerName)); { InstWrapper inst{env.vulkan_functions}; FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst.CheckCreate()); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer ", explicit_layer_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE( env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); } env.debug_log.clear(); { // Try to enable a blacklisted layer InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(explicit_layer_name_1); FillDebugUtilsCreateDetails(inst.create_info, env.debug_log); ASSERT_NO_FATAL_FAILURE(inst.CheckCreate()); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Insert instance layer ", explicit_layer_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix("Found manifest file", explicit_json_name_1)); ASSERT_TRUE(env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "forced enabled due to env var")); ASSERT_FALSE( env.debug_log.find_prefix_then_postfix(explicit_layer_name_1, "disabled because name matches filter of env var")); } } // Add a device layer, should not work TEST(TestLayers, DoNotUseDeviceLayer) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2)) .set_icd_api_version(VK_API_VERSION_1_2) .add_physical_device(PhysicalDevice{}.set_api_version(VK_API_VERSION_1_2).finish()); 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 ASSERT_NO_FATAL_FAILURE(inst1.EnumerateDeviceExtensions(phys_dev1, 0)); // Create a device and query the function pointers DeviceWrapper dev1{inst1}; dev1.CheckCreate(phys_dev1); PFN_vkTrimCommandPoolKHR pfn_TrimCommandPoolBefore = dev1.load("vkTrimCommandPoolKHR"); PFN_vkGetSwapchainStatusKHR pfn_GetSwapchainStatusBefore = dev1.load("vkGetSwapchainStatusKHR"); handle_assert_null(pfn_TrimCommandPoolBefore); handle_assert_null(pfn_GetSwapchainStatusBefore); // 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 ASSERT_NO_FATAL_FAILURE(inst2.EnumerateDeviceExtensions(phys_dev2, 0)); DeviceWrapper dev2{inst2}; dev2.create_info.add_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME) .add_extension(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME) .add_layer(explicit_layer_name); dev2.CheckCreate(phys_dev2, VK_ERROR_EXTENSION_NOT_PRESENT); DeviceWrapper dev3{inst2}; dev3.create_info.add_layer(explicit_layer_name); dev3.CheckCreate(phys_dev2); PFN_vkTrimCommandPoolKHR pfn_TrimCommandPoolAfter = dev3.load("vkTrimCommandPoolKHR"); PFN_vkGetSwapchainStatusKHR pfn_GetSwapchainStatusAfter = dev3.load("vkGetSwapchainStatusKHR"); handle_assert_null(pfn_TrimCommandPoolAfter); handle_assert_null(pfn_GetSwapchainStatusAfter); } // Make sure that a layer enabled as both an instance and device layer works properly. TEST(TestLayers, InstanceAndDeviceLayer) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2)) .set_icd_api_version(VK_API_VERSION_1_2) .add_physical_device(PhysicalDevice{}.set_api_version(VK_API_VERSION_1_2).finish()); 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"); InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(explicit_layer_name); inst.CheckCreate(); VkPhysicalDevice phys_dev = inst.GetPhysDev(); DeviceWrapper dev{inst}; dev.create_info.add_extension(VK_KHR_MAINTENANCE1_EXTENSION_NAME) .add_extension(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME) .add_layer(explicit_layer_name); dev.CheckCreate(phys_dev); PFN_vkTrimCommandPoolKHR pfn_TrimCommandPoolAfter = dev.load("vkTrimCommandPoolKHR"); PFN_vkGetSwapchainStatusKHR pfn_GetSwapchainStatusAfter = dev.load("vkGetSwapchainStatusKHR"); handle_assert_has_value(pfn_TrimCommandPoolAfter); handle_assert_has_value(pfn_GetSwapchainStatusAfter); ASSERT_EQ(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, pfn_GetSwapchainStatusAfter(dev.dev, VK_NULL_HANDLE)); } // Make sure loader does not throw an error for a device layer that is not present TEST(TestLayers, DeviceLayerNotPresent) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA, VK_API_VERSION_1_2)) .set_icd_api_version(VK_API_VERSION_1_2) .add_physical_device(PhysicalDevice{}.set_api_version(VK_API_VERSION_1_2).finish()); const char* explicit_layer_name = "VK_LAYER_LUNARG_wrap_objects"; InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); VkPhysicalDevice phys_dev = inst.GetPhysDev(); DeviceWrapper dev{inst}; dev.create_info.add_layer(explicit_layer_name); dev.CheckCreate(phys_dev); } TEST(LayerPhysDeviceMod, AddPhysicalDevices) { FrameworkEnvironment env; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name("VK_LAYER_LunarG_add_phys_dev") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_API_VERSION_1_1) .set_disable_environment("TEST_DISABLE_ADD_PHYS_DEV")), "test_layer_add.json"); auto& layer = env.get_test_layer(0); layer.set_add_phys_devs(true); for (uint32_t icd = 0; icd < 2; ++icd) { auto& cur_icd = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2)).set_icd_api_version(VK_API_VERSION_1_2); VkPhysicalDeviceProperties properties{}; properties.apiVersion = VK_API_VERSION_1_2; properties.vendorID = 0x11000000 + (icd << 6); for (uint32_t dev = 0; dev < 3; ++dev) { properties.deviceID = properties.vendorID + dev; properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; auto dev_name = std::string("physdev_") + std::to_string(icd) + "_" + std::to_string(dev); #if defined(_WIN32) strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1); #else strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE); #endif cur_icd.add_physical_device({}); cur_icd.physical_devices.back().set_properties(properties); } cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]); cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]); cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]); } const uint32_t icd_devices = 6; InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(VK_API_VERSION_1_1); inst.CheckCreate(); uint32_t dev_count = 0; ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &dev_count, nullptr)); ASSERT_GT(dev_count, icd_devices); auto not_exp_physical_devices = std::vector(icd_devices); uint32_t returned_phys_dev_count = icd_devices; ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, not_exp_physical_devices.data())); ASSERT_EQ(icd_devices, returned_phys_dev_count); auto physical_devices = std::vector(dev_count); returned_phys_dev_count = dev_count; ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, physical_devices.data())); ASSERT_EQ(dev_count, returned_phys_dev_count); uint32_t diff_count = dev_count - icd_devices; uint32_t found_incomplete = 0; uint32_t found_added_count = 0; for (uint32_t dev = 0; dev < dev_count; ++dev) { VkPhysicalDeviceProperties props{}; inst->vkGetPhysicalDeviceProperties(physical_devices[dev], &props); if (string_eq(props.deviceName, "physdev_added_xx")) { found_added_count++; } for (uint32_t incomp = 0; incomp < icd_devices; ++incomp) { if (not_exp_physical_devices[incomp] == physical_devices[dev]) { found_incomplete++; break; } } } // We should have added the number of diff items, and the incomplete count should match the number of // original physical devices. ASSERT_EQ(found_added_count, diff_count); ASSERT_EQ(found_incomplete, icd_devices); } TEST(LayerPhysDeviceMod, RemovePhysicalDevices) { FrameworkEnvironment env; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name("VK_LAYER_LunarG_remove_phys_dev") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_API_VERSION_1_1) .set_disable_environment("TEST_DISABLE_REMOVE_PHYS_DEV")), "test_layer_remove.json"); auto& layer = env.get_test_layer(0); layer.set_remove_phys_devs(true); for (uint32_t icd = 0; icd < 2; ++icd) { auto& cur_icd = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2)).set_icd_api_version(VK_API_VERSION_1_2); VkPhysicalDeviceProperties properties{}; properties.apiVersion = VK_API_VERSION_1_2; properties.vendorID = 0x11000000 + (icd << 6); for (uint32_t dev = 0; dev < 3; ++dev) { properties.deviceID = properties.vendorID + dev; properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; auto dev_name = std::string("physdev_") + std::to_string(icd) + "_" + std::to_string(dev); #if defined(_WIN32) strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1); #else strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE); #endif cur_icd.add_physical_device({}); cur_icd.physical_devices.back().set_properties(properties); } cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]); cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]); cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]); } const uint32_t icd_devices = 6; InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(VK_API_VERSION_1_1); inst.CheckCreate(); uint32_t dev_count = 0; ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &dev_count, nullptr)); ASSERT_LT(dev_count, icd_devices); auto physical_devices = std::vector(dev_count); uint32_t returned_phys_dev_count = dev_count; ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, physical_devices.data())); ASSERT_EQ(dev_count, returned_phys_dev_count); } TEST(LayerPhysDeviceMod, ReorderPhysicalDevices) { FrameworkEnvironment env; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name("VK_LAYER_LunarG_reorder_phys_dev") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_API_VERSION_1_1) .set_disable_environment("TEST_DISABLE_REORDER_PHYS_DEV")), "test_layer_reorder.json"); auto& layer = env.get_test_layer(0); layer.set_reorder_phys_devs(true); for (uint32_t icd = 0; icd < 2; ++icd) { auto& cur_icd = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2)).set_icd_api_version(VK_API_VERSION_1_2); VkPhysicalDeviceProperties properties{}; properties.apiVersion = VK_API_VERSION_1_2; properties.vendorID = 0x11000000 + (icd << 6); for (uint32_t dev = 0; dev < 3; ++dev) { properties.deviceID = properties.vendorID + dev; properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; auto dev_name = std::string("physdev_") + std::to_string(icd) + "_" + std::to_string(dev); #if defined(_WIN32) strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1); #else strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE); #endif cur_icd.add_physical_device({}); cur_icd.physical_devices.back().set_properties(properties); } cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]); cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]); cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]); } const uint32_t icd_devices = 6; InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(VK_API_VERSION_1_1); inst.CheckCreate(); uint32_t dev_count = 0; ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &dev_count, nullptr)); ASSERT_EQ(dev_count, icd_devices); auto physical_devices = std::vector(dev_count); uint32_t returned_phys_dev_count = dev_count; ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, physical_devices.data())); ASSERT_EQ(dev_count, returned_phys_dev_count); } TEST(LayerPhysDeviceMod, AddRemoveAndReorderPhysicalDevices) { FrameworkEnvironment env; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name("VK_LAYER_LunarG_all_phys_dev") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_API_VERSION_1_1) .set_disable_environment("TEST_DISABLE_ALL_PHYS_DEV")), "test_layer_all.json"); auto& layer = env.get_test_layer(0); layer.set_add_phys_devs(true).set_remove_phys_devs(true).set_reorder_phys_devs(true); for (uint32_t icd = 0; icd < 2; ++icd) { auto& cur_icd = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2)).set_icd_api_version(VK_API_VERSION_1_2); VkPhysicalDeviceProperties properties{}; properties.apiVersion = VK_API_VERSION_1_2; properties.vendorID = 0x11000000 + (icd << 6); for (uint32_t dev = 0; dev < 3; ++dev) { properties.deviceID = properties.vendorID + dev; properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; auto dev_name = std::string("physdev_") + std::to_string(icd) + "_" + std::to_string(dev); #if defined(_WIN32) strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1); #else strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE); #endif cur_icd.add_physical_device({}); cur_icd.physical_devices.back().set_properties(properties); } cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]); cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]); cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]); } const uint32_t icd_devices = 6; InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(VK_API_VERSION_1_1); inst.CheckCreate(); uint32_t dev_count = 0; ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &dev_count, nullptr)); ASSERT_GT(dev_count, icd_devices); auto physical_devices = std::vector(dev_count); uint32_t returned_phys_dev_count = dev_count; ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, physical_devices.data())); ASSERT_EQ(dev_count, returned_phys_dev_count); uint32_t found_added_count = 0; for (uint32_t dev = 0; dev < dev_count; ++dev) { VkPhysicalDeviceProperties props{}; inst->vkGetPhysicalDeviceProperties(physical_devices[dev], &props); if (string_eq(props.deviceName, "physdev_added_xx")) { found_added_count++; } } // Should see 2 removed, but 3 added so a diff count of 1 uint32_t diff_count = dev_count - icd_devices; ASSERT_EQ(1U, diff_count); ASSERT_EQ(found_added_count, 3U); } bool GroupsAreTheSame(VkPhysicalDeviceGroupProperties a, VkPhysicalDeviceGroupProperties b) { if (a.physicalDeviceCount != b.physicalDeviceCount) { return false; } for (uint32_t dev = 0; dev < a.physicalDeviceCount; ++dev) { if (a.physicalDevices[dev] != b.physicalDevices[dev]) { return false; } } return true; } TEST(LayerPhysDeviceMod, AddPhysicalDeviceGroups) { FrameworkEnvironment env; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name("VK_LAYER_LunarG_add_phys_dev") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_API_VERSION_1_1) .set_disable_environment("TEST_DISABLE_ADD_PHYS_DEV")), "test_layer_remove.json"); auto& layer = env.get_test_layer(0); layer.set_add_phys_devs(true); for (uint32_t icd = 0; icd < 2; ++icd) { auto& cur_icd = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2)).set_icd_api_version(VK_API_VERSION_1_2); VkPhysicalDeviceProperties properties{}; properties.apiVersion = VK_API_VERSION_1_2; properties.vendorID = 0x11000000 + (icd << 6); for (uint32_t dev = 0; dev < 3; ++dev) { properties.deviceID = properties.vendorID + dev; properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; auto dev_name = std::string("physdev_") + std::to_string(icd) + "_" + std::to_string(dev); #if defined(_WIN32) strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1); #else strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE); #endif cur_icd.add_physical_device({}); cur_icd.physical_devices.back().set_properties(properties); } cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]); cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]); cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]); } const uint32_t icd_groups = 4; InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(VK_API_VERSION_1_1); inst.CheckCreate(); uint32_t grp_count = 0; ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &grp_count, nullptr)); ASSERT_GT(grp_count, icd_groups); auto not_exp_phys_dev_groups = std::vector(icd_groups, {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES}); uint32_t returned_group_count = icd_groups; ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, not_exp_phys_dev_groups.data())); ASSERT_EQ(icd_groups, returned_group_count); auto phys_dev_groups = std::vector(grp_count, {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES}); returned_group_count = grp_count; ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, phys_dev_groups.data())); ASSERT_EQ(grp_count, returned_group_count); uint32_t diff_count = grp_count - icd_groups; uint32_t found_incomplete = 0; uint32_t found_added_count = 0; for (uint32_t grp = 0; grp < grp_count; ++grp) { // Shortcut, only groups with 1 device could be added in the newly added count if (1 == phys_dev_groups[grp].physicalDeviceCount) { for (uint32_t dev = 0; dev < phys_dev_groups[grp].physicalDeviceCount; ++dev) { VkPhysicalDeviceProperties props{}; inst->vkGetPhysicalDeviceProperties(phys_dev_groups[grp].physicalDevices[dev], &props); if (string_eq(props.deviceName, "physdev_added_xx")) { found_added_count++; } } } for (uint32_t incomp = 0; incomp < icd_groups; ++incomp) { if (GroupsAreTheSame(not_exp_phys_dev_groups[incomp], phys_dev_groups[grp])) { found_incomplete++; break; } } } // We should have added the number of diff items, and the incomplete count should match the number of // original physical devices. ASSERT_EQ(found_added_count, diff_count); ASSERT_EQ(found_incomplete, icd_groups); } TEST(LayerPhysDeviceMod, RemovePhysicalDeviceGroups) { FrameworkEnvironment env; EnvVarWrapper disable_linux_sort("VK_LOADER_DISABLE_SELECT", "1"); env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name("VK_LAYER_LunarG_remove_phys_dev") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_API_VERSION_1_1) .set_disable_environment("TEST_DISABLE_REMOVE_PHYS_DEV")), "test_layer_remove.json"); auto& layer = env.get_test_layer(0); layer.set_remove_phys_devs(true); for (uint32_t icd = 0; icd < 2; ++icd) { auto& cur_icd = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2)).set_icd_api_version(VK_API_VERSION_1_2); VkPhysicalDeviceProperties properties{}; properties.apiVersion = VK_API_VERSION_1_2; properties.vendorID = 0x11000000 + (icd << 6); for (uint32_t dev = 0; dev < 3; ++dev) { properties.deviceID = properties.vendorID + dev; properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; auto dev_name = std::string("physdev_") + std::to_string(icd) + "_" + std::to_string(dev); #if defined(_WIN32) strncpy_s(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE); #else strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE); #endif cur_icd.add_physical_device({}); cur_icd.physical_devices.back().set_properties(properties); } cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]); cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]); cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]); } const uint32_t icd_groups = 3; InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(VK_API_VERSION_1_1); inst.CheckCreate(); uint32_t grp_count = 0; ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &grp_count, nullptr)); ASSERT_EQ(grp_count, icd_groups); auto phys_dev_groups = std::vector(grp_count, {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES}); uint32_t returned_group_count = grp_count; ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, phys_dev_groups.data())); ASSERT_EQ(grp_count, returned_group_count); } TEST(LayerPhysDeviceMod, ReorderPhysicalDeviceGroups) { FrameworkEnvironment env; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name("VK_LAYER_LunarG_reorder_phys_dev") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_API_VERSION_1_1) .set_disable_environment("TEST_DISABLE_REORDER_PHYS_DEV")), "test_layer_reorder.json"); auto& layer = env.get_test_layer(0); layer.set_reorder_phys_devs(true); for (uint32_t icd = 0; icd < 2; ++icd) { auto& cur_icd = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2)).set_icd_api_version(VK_API_VERSION_1_2); VkPhysicalDeviceProperties properties{}; properties.apiVersion = VK_API_VERSION_1_2; properties.vendorID = 0x11000000 + (icd << 6); for (uint32_t dev = 0; dev < 3; ++dev) { properties.deviceID = properties.vendorID + dev; properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; auto dev_name = std::string("physdev_") + std::to_string(icd) + "_" + std::to_string(dev); #if defined(_WIN32) strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1); #else strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE); #endif cur_icd.add_physical_device({}); cur_icd.physical_devices.back().set_properties(properties); } cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]); cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]); cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]); } const uint32_t icd_groups = 4; InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(VK_API_VERSION_1_1); inst.CheckCreate(); uint32_t grp_count = 0; ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &grp_count, nullptr)); ASSERT_EQ(grp_count, icd_groups); auto phys_dev_groups = std::vector(grp_count, {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES}); uint32_t returned_group_count = grp_count; ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, phys_dev_groups.data())); ASSERT_EQ(grp_count, returned_group_count); } TEST(LayerPhysDeviceMod, AddRemoveAndReorderPhysicalDeviceGroups) { FrameworkEnvironment env; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name("VK_LAYER_LunarG_all_phys_dev") .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_api_version(VK_API_VERSION_1_1) .set_disable_environment("TEST_DISABLE_ALL_PHYS_DEV")), "test_layer_all.json"); auto& layer = env.get_test_layer(0); layer.set_add_phys_devs(true).set_remove_phys_devs(true).set_reorder_phys_devs(true); for (uint32_t icd = 0; icd < 2; ++icd) { auto& cur_icd = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_2)).set_icd_api_version(VK_API_VERSION_1_2); VkPhysicalDeviceProperties properties{}; properties.apiVersion = VK_API_VERSION_1_2; properties.vendorID = 0x11000000 + (icd << 6); for (uint32_t dev = 0; dev < 3; ++dev) { properties.deviceID = properties.vendorID + dev; properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; auto dev_name = std::string("physdev_") + std::to_string(icd) + "_" + std::to_string(dev); #if defined(_WIN32) strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1); #else strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE); #endif cur_icd.add_physical_device({}); cur_icd.physical_devices.back().set_properties(properties); } cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]); cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[1]); cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[2]); } const uint32_t icd_groups = 4; InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(VK_API_VERSION_1_1); inst.CheckCreate(); uint32_t grp_count = 0; ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &grp_count, nullptr)); ASSERT_GT(grp_count, icd_groups); auto phys_dev_groups = std::vector(grp_count, {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES}); uint32_t returned_group_count = grp_count; ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, phys_dev_groups.data())); ASSERT_EQ(grp_count, returned_group_count); uint32_t diff_count = grp_count - icd_groups; uint32_t found_added_count = 0; for (uint32_t grp = 0; grp < grp_count; ++grp) { // Shortcut, only groups with 1 device could be added in the newly added count if (1 == phys_dev_groups[grp].physicalDeviceCount) { for (uint32_t dev = 0; dev < phys_dev_groups[grp].physicalDeviceCount; ++dev) { VkPhysicalDeviceProperties props{}; inst->vkGetPhysicalDeviceProperties(phys_dev_groups[grp].physicalDevices[dev], &props); if (string_eq(props.deviceName, "physdev_added_xx")) { found_added_count++; } } } } // Should see 2 devices removed which should result in 1 group removed and since 3 // devices were added we should have 3 new groups. So we should have a diff of 2 // groups and 3 new groups ASSERT_EQ(2U, diff_count); ASSERT_EQ(found_added_count, 3U); } TEST(TestLayers, AllowFilterWithExplicitLayer) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({}); const char* layer_name = "VK_LAYER_test_layer"; env.add_explicit_layer( ManifestLayer{}.add_layer( ManifestLayer::LayerDescription{}.set_name(layer_name).set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)), "test_layer_all.json"); EnvVarWrapper allow{"VK_LOADER_LAYERS_ALLOW", layer_name}; { InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { EnvVarWrapper disable{"VK_LOADER_LAYERS_DISABLE", layer_name}; InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { EnvVarWrapper disable{"VK_LOADER_LAYERS_DISABLE", layer_name}; EnvVarWrapper enable{"VK_LOADER_LAYERS_ENABLE", layer_name}; InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(layer_name); inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration( LoaderSettingsLayerConfiguration{} .set_name(layer_name) .set_control("on") .set_path(env.get_shimmed_layer_manifest_path(0)) .set_treat_as_implicit_manifest(false))); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("off"); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("auto"); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } } TEST(TestLayers, AllowFilterWithImplicitLayer) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({}); const char* layer_name = "VK_LAYER_test_layer"; const char* disable_env_var = "TEST_DISABLE_ENV_VAR"; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment(disable_env_var)), "test_layer_all.json"); EnvVarWrapper allow{"VK_LOADER_LAYERS_ALLOW", layer_name}; { InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { EnvVarWrapper disable{"VK_LOADER_LAYERS_DISABLE", layer_name}; InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { EnvVarWrapper disable{"VK_LOADER_LAYERS_DISABLE", layer_name}; EnvVarWrapper enable{"VK_LOADER_LAYERS_ENABLE", layer_name}; InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(layer_name); inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration( LoaderSettingsLayerConfiguration{} .set_name(layer_name) .set_control("on") .set_path(env.get_shimmed_layer_manifest_path(0)) .set_treat_as_implicit_manifest(true))); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("off"); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("auto"); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } env.remove_loader_settings(); // Set the disable_environment variable EnvVarWrapper set_disable_env_var{disable_env_var, "1"}; { InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { EnvVarWrapper disable{"VK_LOADER_LAYERS_DISABLE", layer_name}; InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { EnvVarWrapper disable{"VK_LOADER_LAYERS_DISABLE", layer_name}; EnvVarWrapper enable{"VK_LOADER_LAYERS_ENABLE", layer_name}; InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); // layer's disable_environment takes priority ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(layer_name); inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration( LoaderSettingsLayerConfiguration{} .set_name(layer_name) .set_control("on") .set_path(env.get_shimmed_layer_manifest_path(0)) .set_treat_as_implicit_manifest(true))); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("off"); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("auto"); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } } TEST(TestLayers, AllowFilterWithConditionallyImlicitLayer) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({}); const char* layer_name = "VK_LAYER_test_layer"; const char* enable_env_var = "TEST_ENABLE_ENV_VAR"; env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment("TEST_DISABLE_ENV_VAR") .set_enable_environment(enable_env_var)), "test_layer_all.json"); EnvVarWrapper allow{"VK_LOADER_LAYERS_ALLOW", layer_name}; { InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { EnvVarWrapper disable{"VK_LOADER_LAYERS_DISABLE", layer_name}; InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { EnvVarWrapper disable{"VK_LOADER_LAYERS_DISABLE", layer_name}; EnvVarWrapper enable{"VK_LOADER_LAYERS_ENABLE", layer_name}; InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(layer_name); inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration( LoaderSettingsLayerConfiguration{} .set_name(layer_name) .set_control("on") .set_path(env.get_shimmed_layer_manifest_path(0)) .set_treat_as_implicit_manifest(true))); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("off"); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("auto"); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } env.remove_loader_settings(); // Repeate the above tests but with the enable_environment variable set EnvVarWrapper set_enable_env_var{enable_env_var, "1"}; { InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { EnvVarWrapper disable{"VK_LOADER_LAYERS_DISABLE", layer_name}; InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { EnvVarWrapper disable{"VK_LOADER_LAYERS_DISABLE", layer_name}; EnvVarWrapper enable{"VK_LOADER_LAYERS_ENABLE", layer_name}; InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(layer_name); inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration( LoaderSettingsLayerConfiguration{} .set_name(layer_name) .set_control("on") .set_path(env.get_shimmed_layer_manifest_path(0)) .set_treat_as_implicit_manifest(true))); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("off"); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("auto"); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } } TEST(TestLayers, AllowFilterWithConditionallyImlicitLayerWithOverrideLayer) { FrameworkEnvironment env; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).add_physical_device({}); const char* layer_name = "VK_LAYER_test_layer"; const char* enable_env_var = "TEST_ENABLE_ENV_VAR"; env.add_implicit_layer(TestLayerDetails{ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} .set_name(layer_name) .set_api_version(VK_API_VERSION_1_1) .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) .set_disable_environment("TEST_DISABLE_ENV_VAR") .set_enable_environment(enable_env_var)), "test_layer_all.json"} .set_discovery_type(ManifestDiscoveryType::override_folder)); env.add_implicit_layer(ManifestLayer{}.set_file_format_version({1, 2, 0}).add_layer( ManifestLayer::LayerDescription{} .set_name(lunarg_meta_layer_name) .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) .add_component_layer(layer_name) .set_disable_environment("DisableMeIfYouCan") .add_override_path(env.get_folder(ManifestLocation::override_layer).location().string())), "meta_test_layer.json"); EnvVarWrapper allow{"VK_LOADER_LAYERS_ALLOW", layer_name}; { InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); ASSERT_TRUE(string_eq(layers.at(1).layerName, lunarg_meta_layer_name)); } { EnvVarWrapper disable{"VK_LOADER_LAYERS_DISABLE", layer_name}; InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); ASSERT_TRUE(string_eq(layers.at(1).layerName, lunarg_meta_layer_name)); } { EnvVarWrapper disable{"VK_LOADER_LAYERS_DISABLE", layer_name}; EnvVarWrapper enable{"VK_LOADER_LAYERS_ENABLE", layer_name}; InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); ASSERT_TRUE(string_eq(layers.at(1).layerName, lunarg_meta_layer_name)); } { InstWrapper inst{env.vulkan_functions}; inst.create_info.add_layer(layer_name); inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 2); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); ASSERT_TRUE(string_eq(layers.at(1).layerName, lunarg_meta_layer_name)); } { env.loader_settings.add_app_specific_setting(AppSpecificSettings{}.add_stderr_log_filter("all").add_layer_configuration( LoaderSettingsLayerConfiguration{} .set_name(layer_name) .set_control("on") .set_path(env.get_shimmed_layer_manifest_path(0)) .set_treat_as_implicit_manifest(true))); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); auto layers = inst.GetActiveLayers(inst.GetPhysDev(), 1); ASSERT_TRUE(string_eq(layers.at(0).layerName, layer_name)); } { env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("off"); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } { env.loader_settings.app_specific_settings.at(0).layer_configurations.at(0).set_control("auto"); env.update_loader_settings(env.loader_settings); InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); ASSERT_NO_FATAL_FAILURE(inst.GetActiveLayers(inst.GetPhysDev(), 0)); } }