Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/Vulkan-Loader.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Natalie <jenatali@microsoft.com>2022-06-30 22:55:55 +0300
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>2022-07-05 23:34:53 +0300
commit26921924d63bda937feb0d7caf9258dfb2d1d894 (patch)
treedf9d89fe32e4cc177a689b06e0f3009d2bdf346d
parent0ad591fa3c2a68e555e80f45a4d6cb52dfdaf8f0 (diff)
Enable the Vulkan loader to load VulkanOn12/Dozen out of the D3DMappingLayers app package
-rw-r--r--docs/LoaderDriverInterface.md6
-rw-r--r--loader/loader.c25
-rw-r--r--loader/loader_windows.c70
-rw-r--r--loader/loader_windows.h4
-rw-r--r--tests/framework/shim/shim.h4
-rw-r--r--tests/framework/shim/shim_common.cpp5
-rw-r--r--tests/framework/shim/windows_shim.cpp49
-rw-r--r--tests/framework/test_environment.cpp9
-rw-r--r--tests/framework/test_environment.h14
-rw-r--r--tests/loader_regression_tests.cpp11
10 files changed, 187 insertions, 10 deletions
diff --git a/docs/LoaderDriverInterface.md b/docs/LoaderDriverInterface.md
index 1021dd41d..40430fbd8 100644
--- a/docs/LoaderDriverInterface.md
+++ b/docs/LoaderDriverInterface.md
@@ -291,6 +291,12 @@ In this case, the loader will open the first and last listings, but not the
middle.
This is because the value of 1 for vendor_b_vk.json disables the driver.
+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™ and OpenGL® 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/loader/loader.c b/loader/loader.c
index 48a4d5b6f..b1eca3880 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -2917,7 +2917,9 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in
bool xdg_data_dirs_secenv_alloc = true;
#endif
-#ifndef _WIN32
+#ifdef _WIN32
+ char *package_path = NULL;
+#else
// Determine how much space is needed to generate the full search path
// for the current manifest files.
char *xdg_config_home = loader_secure_getenv("XDG_CONFIG_HOME", inst);
@@ -3004,6 +3006,9 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in
}
additional_env = loader_secure_getenv(VK_ADDITIONAL_DRIVER_FILES_ENV_VAR, inst);
relative_location = VK_DRIVERS_INFO_RELATIVE_DIR;
+#ifdef _WIN32
+ package_path = windows_get_app_package_manifest_path(inst);
+#endif
break;
case LOADER_DATA_FILE_MANIFEST_IMPLICIT_LAYER:
relative_location = VK_ILAYERS_INFO_RELATIVE_DIR;
@@ -3036,7 +3041,11 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in
if (NULL != additional_env) {
search_path_size += determine_data_file_path_size(additional_env, 0) + 2;
#ifdef _WIN32
- } else {
+ }
+ if (NULL != package_path) {
+ search_path_size += determine_data_file_path_size(package_path, 0) + 2;
+ }
+ if (search_path_size == 2) {
goto out;
}
#else // !_WIN32
@@ -3088,7 +3097,11 @@ static VkResult read_data_files_in_search_paths(const struct loader_instance *in
copy_data_file_info(additional_env, NULL, 0, &cur_path_ptr);
}
-#ifndef _WIN32
+#ifdef _WIN32
+ if (NULL != package_path) {
+ copy_data_file_info(package_path, NULL, 0, &cur_path_ptr);
+ }
+#else
if (rel_size > 0) {
#if defined(__APPLE__)
// Add the bundle's Resources dir to the beginning of the search path.
@@ -3223,7 +3236,11 @@ out:
if (NULL != override_env) {
loader_free_getenv(override_env, inst);
}
-#ifndef _WIN32
+#ifdef _WIN32
+ if (NULL != package_path) {
+ loader_instance_heap_free(inst, package_path);
+ }
+#else
if (xdg_config_home_secenv_alloc) {
loader_free_getenv(xdg_config_home, inst);
}
diff --git a/loader/loader_windows.c b/loader/loader_windows.c
index c7fbab9c8..1ad74e96c 100644
--- a/loader/loader_windows.c
+++ b/loader/loader_windows.c
@@ -51,6 +51,8 @@
#include <dxgi1_6.h>
#include "adapters.h"
+#include <appmodel.h>
+
#if !defined(NDEBUG)
#include <crtdbg.h>
#endif
@@ -996,4 +998,72 @@ VkResult windows_sort_physical_device_groups(struct loader_instance *inst, const
return VK_SUCCESS;
}
+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.
+ */
+ PCWSTR familyName = L"Microsoft.D3DMappingLayers_8wekyb3d8bbwe";
+ if (ERROR_INSUFFICIENT_BUFFER != GetPackagesByPackageFamily(familyName,
+ &numPackages, NULL,
+ &bufferLength, NULL) ||
+ numPackages == 0 || bufferLength == 0) {
+ loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
+ "windows_get_app_package_manifest_path: Failed to find mapping layers packages by family name\n");
+ return NULL;
+ }
+
+ char *ret = NULL;
+ WCHAR *buffer = loader_instance_heap_alloc(inst, sizeof(WCHAR) * bufferLength, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+ PWSTR *packages = loader_instance_heap_alloc(inst, sizeof(PWSTR) * numPackages, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+ if (!buffer || !packages) {
+ loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
+ "windows_get_app_package_manifest_path: Failed to allocate memory for package names\n");
+ goto cleanup;
+ }
+
+ if (ERROR_SUCCESS != GetPackagesByPackageFamily(familyName,
+ &numPackages, packages,
+ &bufferLength, buffer)) {
+ loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
+ "windows_get_app_package_manifest_path: Failed to mapping layers package full names\n");
+ goto cleanup;
+ }
+
+ UINT32 pathLength = 0;
+ WCHAR path[MAX_PATH];
+ memset(path, 0, sizeof(path));
+ if (ERROR_INSUFFICIENT_BUFFER != GetPackagePathByFullName(packages[0], &pathLength, NULL) ||
+ pathLength > MAX_PATH ||
+ ERROR_SUCCESS != GetPackagePathByFullName(packages[0], &pathLength, path)) {
+ loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
+ "windows_get_app_package_manifest_path: Failed to get mapping layers package path\n");
+ goto cleanup;
+ }
+
+ int narrowPathLength = WideCharToMultiByte(CP_ACP, 0, path, -1, NULL, 0, NULL, NULL);
+ if (narrowPathLength == 0) {
+ loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
+ "windows_get_app_package_manifest_path: Failed to convert path from wide to narrow\n");
+ goto cleanup;
+ }
+
+ ret = loader_instance_heap_alloc(inst, narrowPathLength, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+ if (!ret) {
+ loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
+ "windows_get_app_package_manifest_path: Failed to allocate path\n");
+ goto cleanup;
+ }
+
+ narrowPathLength = WideCharToMultiByte(CP_ACP, 0, path, -1, ret, narrowPathLength, NULL, NULL);
+ assert((size_t)narrowPathLength == strlen(ret) + 1);
+
+cleanup:
+ loader_instance_heap_free(inst, buffer);
+ loader_instance_heap_free(inst, packages);
+ return ret;
+}
+
#endif // _WIN32
diff --git a/loader/loader_windows.h b/loader/loader_windows.h
index ff7555c0b..2e34f6574 100644
--- a/loader/loader_windows.h
+++ b/loader/loader_windows.h
@@ -111,4 +111,8 @@ VkResult windows_sort_physical_device_groups(struct loader_instance *inst, const
// Creates a DXGI factory
// Returns VkLoaderFeatureFlags containing VK_LOADER_FEATURE_PHYSICAL_DEVICE_SORTING if successful, otherwise 0
VkLoaderFeatureFlags windows_initialize_dxgi(void);
+
+// Retrieve a path to an installed app package that contains Vulkan manifests.
+// When done using the returned string, the caller should free the pointer.
+char *windows_get_app_package_manifest_path(const struct loader_instance *inst);
#endif // WIN32 \ No newline at end of file
diff --git a/tests/framework/shim/shim.h b/tests/framework/shim/shim.h
index bb0ad9a30..4b0c8bc23 100644
--- a/tests/framework/shim/shim.h
+++ b/tests/framework/shim/shim.h
@@ -37,6 +37,7 @@
#include <initguid.h>
#include <devpkey.h>
#include <winternl.h>
+#include <appmodel.h>
#define CINTERFACE
#include <dxgi1_6.h>
@@ -151,6 +152,7 @@ struct PlatformShim {
void add_dxgi_adapter(GpuType gpu_preference, DXGI_ADAPTER_DESC1 desc1);
void add_d3dkmt_adapter(D3DKMT_Adapter const& adapter);
+ void set_app_package_path(fs::path const& path);
uint32_t next_adapter_handle = 1; // increment everytime add_dxgi_adapter is called
std::vector<DXGIAdapter> dxgi_adapters;
@@ -173,6 +175,8 @@ struct PlatformShim {
std::vector<RegistryEntry> hkey_local_machine_implicit_layers;
std::vector<RegistryEntry> hkey_local_machine_drivers;
+ std::wstring app_package_path;
+
// When a key is created, return the index of the
size_t created_key_count = 0;
std::vector<HKeyHandle> created_keys;
diff --git a/tests/framework/shim/shim_common.cpp b/tests/framework/shim/shim_common.cpp
index 721aabef5..e946c0d4c 100644
--- a/tests/framework/shim/shim_common.cpp
+++ b/tests/framework/shim/shim_common.cpp
@@ -118,6 +118,11 @@ void PlatformShim::add_dxgi_adapter(GpuType gpu_preference, DXGI_ADAPTER_DESC1 d
void PlatformShim::add_d3dkmt_adapter(D3DKMT_Adapter const& adapter) { d3dkmt_adapters.push_back(adapter); }
+void PlatformShim::set_app_package_path(fs::path const& path) {
+ app_package_path.resize(path.size());
+ MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, &app_package_path[0], static_cast<int>(app_package_path.size()));
+}
+
// TODO:
void PlatformShim::add_CM_Device_ID(std::wstring const& id, fs::path const& icd_path, fs::path const& layer_path) {
// // append a null byte as separator if there is already id's in the list
diff --git a/tests/framework/shim/windows_shim.cpp b/tests/framework/shim/windows_shim.cpp
index 15117606e..c847234af 100644
--- a/tests/framework/shim/windows_shim.cpp
+++ b/tests/framework/shim/windows_shim.cpp
@@ -379,6 +379,51 @@ LSTATUS __stdcall ShimRegCloseKey(HKEY hKey) {
return ERROR_SUCCESS;
}
+// Windows app package shims
+using PFN_GetPackagesByPackageFamily = LONG(WINAPI *)(PCWSTR, UINT32 *, PWSTR *, UINT32 *, WCHAR *);
+static PFN_GetPackagesByPackageFamily fpGetPackagesByPackageFamily = GetPackagesByPackageFamily;
+using PFN_GetPackagePathByFullName = LONG(WINAPI *)(PCWSTR, UINT32 *, PWSTR);
+static PFN_GetPackagePathByFullName fpGetPackagePathByFullName = GetPackagePathByFullName;
+
+static constexpr wchar_t package_full_name[] = L"ThisIsARandomStringSinceTheNameDoesn'tMatter";
+LONG WINAPI ShimGetPackagesByPackageFamily(_In_ PCWSTR packageFamilyName, _Inout_ UINT32 *count,
+ _Out_writes_opt_(*count) PWSTR *packageFullNames, _Inout_ UINT32 *bufferLength,
+ _Out_writes_opt_(*bufferLength) WCHAR *buffer) {
+ if (!packageFamilyName || !count || !bufferLength) return ERROR_INVALID_PARAMETER;
+ if (!platform_shim.app_package_path.empty() && wcscmp(packageFamilyName, L"Microsoft.D3DMappingLayers_8wekyb3d8bbwe") == 0) {
+ if (*count > 0 && !packageFullNames) return ERROR_INVALID_PARAMETER;
+ if (*bufferLength > 0 && !buffer) return ERROR_INVALID_PARAMETER;
+ if (*count > 1) return ERROR_INVALID_PARAMETER;
+ bool too_small = *count < 1 || *bufferLength < ARRAYSIZE(package_full_name);
+ *count = 1;
+ *bufferLength = ARRAYSIZE(package_full_name);
+ if (too_small) return ERROR_INSUFFICIENT_BUFFER;
+
+ wcscpy(buffer, package_full_name);
+ *packageFullNames = buffer;
+ return 0;
+ }
+ *count = 0;
+ *bufferLength = 0;
+ return 0;
+}
+
+LONG WINAPI ShimGetPackagePathByFullName(_In_ PCWSTR packageFullName, _Inout_ UINT32 *pathLength,
+ _Out_writes_opt_(*pathLength) PWSTR path) {
+ if (!packageFullName || !pathLength) return ERROR_INVALID_PARAMETER;
+ if (*pathLength > 0 && !path) return ERROR_INVALID_PARAMETER;
+ if (wcscmp(packageFullName, package_full_name) != 0) {
+ *pathLength = 0;
+ return 0;
+ }
+ if (*pathLength < platform_shim.app_package_path.size() + 1) {
+ *pathLength = static_cast<UINT32>(platform_shim.app_package_path.size() + 1);
+ return ERROR_INSUFFICIENT_BUFFER;
+ }
+ wcscpy(path, platform_shim.app_package_path.c_str());
+ return 0;
+}
+
// Initialization
void WINAPI DetourFunctions() {
if (!gdi32_dll) {
@@ -426,6 +471,8 @@ void WINAPI DetourFunctions() {
DetourAttach(&(PVOID &)fpRegQueryValueExA, (PVOID)ShimRegQueryValueExA);
DetourAttach(&(PVOID &)fpRegEnumValueA, (PVOID)ShimRegEnumValueA);
DetourAttach(&(PVOID &)fpRegCloseKey, (PVOID)ShimRegCloseKey);
+ DetourAttach(&(PVOID &)fpGetPackagesByPackageFamily, (PVOID)ShimGetPackagesByPackageFamily);
+ DetourAttach(&(PVOID &)fpGetPackagePathByFullName, (PVOID)ShimGetPackagePathByFullName);
LONG error = DetourTransactionCommit();
if (error != NO_ERROR) {
@@ -453,6 +500,8 @@ void DetachFunctions() {
DetourDetach(&(PVOID &)fpRegQueryValueExA, (PVOID)ShimRegQueryValueExA);
DetourDetach(&(PVOID &)fpRegEnumValueA, (PVOID)ShimRegEnumValueA);
DetourDetach(&(PVOID &)fpRegCloseKey, (PVOID)ShimRegCloseKey);
+ DetourDetach(&(PVOID &)fpGetPackagesByPackageFamily, (PVOID)ShimGetPackagesByPackageFamily);
+ DetourDetach(&(PVOID &)fpGetPackagePathByFullName, (PVOID)ShimGetPackagePathByFullName);
DetourTransactionCommit();
}
diff --git a/tests/framework/test_environment.cpp b/tests/framework/test_environment.cpp
index 92c88bb8f..7654be723 100644
--- a/tests/framework/test_environment.cpp
+++ b/tests/framework/test_environment.cpp
@@ -194,6 +194,7 @@ FrameworkEnvironment::FrameworkEnvironment() noexcept : platform_shim(&folders),
folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("explicit_add_env_var_layer_folder"));
folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("implicit_layer_manifests"));
folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("override_layer_manifests"));
+ folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("app_package_manifests"));
platform_shim->redirect_all_paths(get_folder(ManifestLocation::null).location());
platform_shim->set_path(ManifestCategory::icd, get_folder(ManifestLocation::driver).location());
@@ -208,6 +209,9 @@ void FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept {
icd_details.discovery_type == ManifestDiscoveryType::add_env_var) {
folder = &get_folder(ManifestLocation::driver_env_var);
}
+ if (icd_details.discovery_type == ManifestDiscoveryType::windows_app_package) {
+ folder = &get_folder(ManifestLocation::windows_app_package);
+ }
if (!icd_details.is_fake) {
fs::path new_driver_name = fs::path(icd_details.icd_manifest.lib_path).stem() + "_" + std::to_string(cur_icd_index) +
fs::path(icd_details.icd_manifest.lib_path).extension();
@@ -242,6 +246,11 @@ void FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept {
break;
case (ManifestDiscoveryType::none):
break;
+#ifdef _WIN32
+ case (ManifestDiscoveryType::windows_app_package):
+ platform_shim->set_app_package_path(folder->location());
+ break;
+#endif
}
}
diff --git a/tests/framework/test_environment.h b/tests/framework/test_environment.h
index 4d33c28df..a9259138d 100644
--- a/tests/framework/test_environment.h
+++ b/tests/framework/test_environment.h
@@ -303,11 +303,12 @@ struct TestLayerHandle {
};
enum class ManifestDiscoveryType {
- generic, // put the manifest in the regular locations
- none, // don't add to regular locations - eg D3DKMT
- env_var, // use the corresponding env-var for it
- add_env_var, // use the corresponding add-env-var for it
- override_folder, // add to a special folder for the override layer to use
+ generic, // put the manifest in the regular locations
+ none, // don't add to regular locations - eg D3DKMT
+ env_var, // use the corresponding env-var for it
+ add_env_var, // use the corresponding add-env-var for it
+ override_folder, // add to a special folder for the override layer to use
+ windows_app_package, // let the app package search find it
};
struct TestICDDetails {
@@ -338,7 +339,8 @@ enum class ManifestLocation {
explicit_layer_env_var = 4,
explicit_layer_add_env_var = 5,
implicit_layer = 6,
- override_layer = 7
+ override_layer = 7,
+ windows_app_package = 8,
};
struct FrameworkEnvironment {
diff --git a/tests/loader_regression_tests.cpp b/tests/loader_regression_tests.cpp
index bd8fdeebf..ea71f10e5 100644
--- a/tests/loader_regression_tests.cpp
+++ b/tests/loader_regression_tests.cpp
@@ -3355,3 +3355,14 @@ TEST(PortabilityICDConfiguration, PortabilityAndRegularICDPreInstanceFunctions)
ASSERT_EQ(layer_count, 0U);
}
}
+
+#ifdef _WIN32
+TEST(AppPackageDriverDiscovery, AppPackageTest) {
+ FrameworkEnvironment env;
+ env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2}.set_discovery_type(ManifestDiscoveryType::windows_app_package));
+ env.get_test_icd().physical_devices.push_back({});
+
+ InstWrapper inst{env.vulkan_functions};
+ inst.CheckCreate();
+}
+#endif