Add app packages to layers search path
authorJim Lewis <jim.lewis@microsoft.com>
Tue, 13 Feb 2024 00:41:53 +0000 (18:41 -0600)
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>
Tue, 27 Feb 2024 19:16:40 +0000 (13:16 -0600)
Expand Windows system search path for layers to include AppX/MSIX
packages currently scanned only for ICD manifests.

docs/LoaderDriverInterface.md
docs/LoaderLayerInterface.md
loader/loader.c
loader/loader_windows.c
tests/framework/test_environment.cpp
tests/loader_regression_tests.cpp

index c8e1872fe71f711bc94bbb62a3e918a4041b8753..e86c83ea7660231521ca4ab8325057f683246351 100644 (file)
@@ -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.
index 2ee6144197860f8580064de7389689d68804ee14..6ca9bc57cef5b94889e5865b7c2700d8192d4f89 100644 (file)
@@ -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.
 
index 7470790aa78a7fdfbaa62cce0088525836f4c331..bfbf515fd9204a179933de71ae9a5514f11fe505 100644 (file)
@@ -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:
index 1ed524dc50f16c80f4208c1b034bd99b4d7f4604..5fbf8d6b42ef6a820b5b773eb1ee01b54c52a5f8 100644 (file)
@@ -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) {
index 1105f84b200dd94206b0739c3ee9e2b8bbb9a5df..cac95d84b927ab67d46213525f60edb031495776 100644 (file)
@@ -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;
index e39df09a4fdcd069b2de58516510742a66cb53c0..438713ae822ad3c79a3ad4c997931e261daf019a 100644 (file)
@@ -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