Skip to content

Commit

Permalink
Add app packages to layers search path
Browse files Browse the repository at this point in the history
Expand Windows system search path for layers to include AppX/MSIX
packages currently scanned only for ICD manifests.
  • Loading branch information
jlewis-austin authored and charles-lunarg committed Feb 27, 2024
1 parent d518edf commit 5475f3d
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 6 deletions.
2 changes: 1 addition & 1 deletion docs/LoaderDriverInterface.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
7 changes: 7 additions & 0 deletions docs/LoaderLayerInterface.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
3 changes: 3 additions & 0 deletions loader/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
6 changes: 2 additions & 4 deletions loader/loader_windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
8 changes: 8 additions & 0 deletions tests/framework/test_environment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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;
Expand Down
26 changes: 25 additions & 1 deletion tests/loader_regression_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3806,14 +3806,38 @@ 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({});

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
Expand Down

0 comments on commit 5475f3d

Please sign in to comment.