diff --git a/docs/LoaderDriverInterface.md b/docs/LoaderDriverInterface.md index c8e1872fe..e86c83ea7 100644 --- a/docs/LoaderDriverInterface.md +++ b/docs/LoaderDriverInterface.md @@ -360,7 +360,7 @@ AppX/MSIX packages. If a package is found, the loader will scan the root directory of this installed package for JSON manifest files. At this time, the only package that is known is Microsoft's -[OpenCL™ and OpenGL® Compatibility Pack](https://apps.microsoft.com/store/detail/9NQPSL29BFFF?hl=en-us&gl=US). +[OpenCL™, OpenGL®, and Vulkan® Compatibility Pack](https://apps.microsoft.com/store/detail/9NQPSL29BFFF?hl=en-us&gl=US). The Vulkan loader will open each enabled manifest file found to obtain the name or pathname of a driver's shared library (".DLL") file. diff --git a/docs/LoaderLayerInterface.md b/docs/LoaderLayerInterface.md index 2ee614419..6ca9bc57c 100644 --- a/docs/LoaderLayerInterface.md +++ b/docs/LoaderLayerInterface.md @@ -233,6 +233,13 @@ distributed as part of a driver installation. An application installer should not modify the device-specific registries, while a device driver should not modify the system registries. +Additionally, the Vulkan loader will scan the system for well-known Windows +AppX/MSIX packages. +If a package is found, the loader will scan the root directory of this installed +package for JSON manifest files. At this time, the only package that is known is +Microsoft's +[OpenCL™, OpenGL®, and Vulkan® Compatibility Pack](https://apps.microsoft.com/store/detail/9NQPSL29BFFF?hl=en-us&gl=US). + The Vulkan loader will open each manifest file to obtain information about the layer, including the name or pathname of a shared library (".dll") file. diff --git a/loader/loader.c b/loader/loader.c index 7470790aa..bfbf515fd 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -3038,6 +3038,9 @@ VkResult read_data_files_in_search_paths(const struct loader_instance *inst, enu case LOADER_DATA_FILE_MANIFEST_IMPLICIT_LAYER: #if COMMON_UNIX_PLATFORMS relative_location = VK_ILAYERS_INFO_RELATIVE_DIR; +#endif +#if defined(_WIN32) + package_path = windows_get_app_package_manifest_path(inst); #endif break; case LOADER_DATA_FILE_MANIFEST_EXPLICIT_LAYER: diff --git a/loader/loader_windows.c b/loader/loader_windows.c index 1ed524dc5..5fbf8d6b4 100644 --- a/loader/loader_windows.c +++ b/loader/loader_windows.c @@ -1110,10 +1110,8 @@ char *windows_get_app_package_manifest_path(const struct loader_instance *inst) } UINT32 numPackages = 0, bufferLength = 0; - /* This literal string identifies the Microsoft-published OpenCL and OpenGL Compatibility Pack - * (so named at the time this is being added), which contains OpenGLOn12 and OpenCLOn12 mapping - * layers, and will contain VulkanOn12 (aka Dozen) going forward. - */ + // This literal string identifies the Microsoft-published OpenCL, OpenGL, and Vulkan Compatibility Pack, which contains + // OpenGLOn12, OpenCLOn12, and VulkanOn12 (aka Dozen) mappinglayers PCWSTR familyName = L"Microsoft.D3DMappingLayers_8wekyb3d8bbwe"; if (ERROR_INSUFFICIENT_BUFFER != fpGetPackagesByPackageFamily(familyName, &numPackages, NULL, &bufferLength, NULL) || numPackages == 0 || bufferLength == 0) { diff --git a/tests/framework/test_environment.cpp b/tests/framework/test_environment.cpp index 1105f84b2..cac95d84b 100644 --- a/tests/framework/test_environment.cpp +++ b/tests/framework/test_environment.cpp @@ -594,6 +594,9 @@ void FrameworkEnvironment::add_layer_impl(TestLayerDetails layer_details, Manife case (ManifestDiscoveryType::unsecured_generic): fs_ptr = &(get_folder(ManifestLocation::unsecured_location)); break; + case (ManifestDiscoveryType::windows_app_package): + fs_ptr = &(get_folder(ManifestLocation::windows_app_package)); + break; case (ManifestDiscoveryType::none): case (ManifestDiscoveryType::null_dir): fs_ptr = &(get_folder(ManifestLocation::null)); @@ -650,6 +653,11 @@ void FrameworkEnvironment::add_layer_impl(TestLayerDetails layer_details, Manife if (layer_details.discovery_type == ManifestDiscoveryType::unsecured_generic) { platform_shim->add_unsecured_manifest(category, layer_manifest_loc); } +#if defined(_WIN32) + if (layer_details.discovery_type == ManifestDiscoveryType::windows_app_package) { + platform_shim->set_app_package_path(layer_manifest_loc); + } +#endif for (size_t i = new_layers_start; i < layers.size(); i++) { layers.at(i).manifest_path = layer_manifest_loc; layers.at(i).shimmed_manifest_path = layer_manifest_loc; diff --git a/tests/loader_regression_tests.cpp b/tests/loader_regression_tests.cpp index e39df09a4..438713ae8 100644 --- a/tests/loader_regression_tests.cpp +++ b/tests/loader_regression_tests.cpp @@ -3806,7 +3806,7 @@ TEST(PortabilityICDConfiguration, PortabilityAndRegularICDPreInstanceFunctions) } #if defined(_WIN32) -TEST(AppPackageDriverDiscovery, AppPackageTest) { +TEST(AppPackageDiscovery, AppPackageDrivers) { FrameworkEnvironment env; env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2}.set_discovery_type(ManifestDiscoveryType::windows_app_package)) .add_physical_device({}); @@ -3814,6 +3814,30 @@ TEST(AppPackageDriverDiscovery, AppPackageTest) { InstWrapper inst{env.vulkan_functions}; inst.CheckCreate(); } +TEST(AppPackageDiscovery, AppPackageLayers) { + FrameworkEnvironment env{}; + env.add_icd(TestICDDetails(ManifestICD{}.set_lib_path(TEST_ICD_PATH_VERSION_2))); + + const char* layer_name = "test_package_layer"; + env.add_implicit_layer(TestLayerDetails(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{} + .set_name(layer_name) + .set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2) + .set_disable_environment("DISABLE_ME")), + "test_package_layer.json") + .set_discovery_type(ManifestDiscoveryType::windows_app_package)); + + InstWrapper inst{env.vulkan_functions}; + inst.CheckCreate(); + + { + VkLayerProperties layer_props{}; + uint32_t layer_count = 0; + ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, NULL)); + ASSERT_EQ(layer_count, 1); + ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumerateInstanceLayerProperties(&layer_count, &layer_props)); + ASSERT_TRUE(string_eq(layer_name, layer_props.layerName)); + } +} // Make sure that stale layer manifests (path to nonexistant file) which have the same name as real manifests don't cause the real // manifests to be skipped. Stale registry entries happen when a registry is written on layer/driver installation but not cleaned up