Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions docs/LoaderDriverInterface.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
- [Example Linux Driver Search Path](#example-linux-driver-search-path)
- [Driver Discovery on Fuchsia](#driver-discovery-on-fuchsia)
- [Driver Discovery on macOS](#driver-discovery-on-macos)
- [Use App Bundled Drivers exclusively](#use-app-bundled-drivers-exclusively)
- [Example macOS Driver Search Path](#example-macos-driver-search-path)
- [Additional Settings For Driver Debugging](#additional-settings-for-driver-debugging)
- [Driver Discovery using the`VK_LUNARG_direct_driver_loading` extension](#driver-discovery-using-thevk_lunarg_direct_driver_loading-extension)
Expand Down Expand Up @@ -512,16 +513,14 @@ The order is similar to the search path on Linux with the exception that
the application's bundle resources are searched first:
`(bundle)/Contents/Resources/`.

System installed drivers will be ignored if drivers are found inside of the app
bundle.
This is because there is not a standard mechanism in which to distinguish drivers
that happen to be duplicates.
For example, MoltenVK is commonly placed inside application bundles.
If there exists a system installed MoltenVK, the loader will load both the app
bundled and the system installed MoltenVK, leading to potential issues or crashes.
Drivers found through environment variables, such as `VK_DRIVER_FILES`, will be
used regardless of whether there are bundled drivers present or not.
#### Use App Bundled Drivers exclusively

By default, the Vulkan Loader searches various system and user paths
for driver manifests. Defining the environment variable
`VK_LOADER_SEARCH_ONLY_IN_BUNDLE` makes the Vulkan Loader only search
for driver manifests in `(bundle)/Contents/Resources/`. This is
intended for applications including drivers inside of the app bundle
so that any drivers elsewhere on the system do not affect the app.

#### Example macOS Driver Search Path

Expand Down
21 changes: 21 additions & 0 deletions docs/LoaderInterfaceArchitecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
- [Globs](#globs)
- [Case-Insensitive](#case-insensitive)
- [Environment Variable Priority](#environment-variable-priority)
- [Multiple Filtering](#multiple-filtering)
- [Table of Debug Environment Variables](#table-of-debug-environment-variables)
- [Active Environment Variables](#active-environment-variables)
- [Deprecated Environment Variables](#deprecated-environment-variables)
Expand Down Expand Up @@ -1061,6 +1062,26 @@ discovery.
&nbsp;&nbsp;VK_LOADER_DRIVER_ID_FILTER=1-3:13<br/><br/>
</small></td>
</tr>
<tr>
<td><small>
<i>VK_LOADER_SEARCH_ONLY_IN_BUNDLE</i>
</small></td>
<td><small>
Prevents searching for layer and driver manifests outside of the
Application Bundle. Meant to isolate applications shipping on macOS/iOS
in a bundle from using system installed layers and drivers.
</small></td>
<td><small>
<b>macOS/iOS only</b><br/>
This functionality is only available with Loaders built with version
1.4.359 of the Vulkan headers and later.
</small></td>
<td><small>
export<br/>
&nbsp;&nbsp;VK_LOADER_SEARCH_ONLY_IN_BUNDLE=1<br/>
<br/>
</small></td>
</tr>
</table>

<br/>
Expand Down
10 changes: 10 additions & 0 deletions docs/LoaderLayerInterface.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
- [Fuchsia Layer Discovery](#fuchsia-layer-discovery)
- [macOS Layer Discovery](#macos-layer-discovery)
- [Example macOS Implicit Layer Search Path](#example-macos-implicit-layer-search-path)
- [Use App Bundled Layers exclusively](#use-app-bundled-layers-exclusively)
- [Layer Filtering](#layer-filtering)
- [Layer Enable Filtering](#layer-enable-filtering)
- [Layer Disable Filtering](#layer-disable-filtering)
Expand Down Expand Up @@ -453,6 +454,15 @@ following:
/usr/share/vulkan/implicit_layer.d
```

#### Use App Bundled Layers exclusively

By default, the Vulkan Loader searches various system and user paths
for layer manifests. Defining the environment variable
`VK_LOADER_SEARCH_ONLY_IN_BUNDLE` makes the Vulkan Loader only search
for layer manifests in `(bundle)/Contents/Resources/`. This is
intended for applications including layers inside of the app bundle
so that any layers elsewhere on the system do not affect the app.

### Layer Filtering

**NOTE:** This functionality is only available with Loaders built with version
Expand Down
57 changes: 33 additions & 24 deletions loader/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -3501,6 +3501,7 @@ VkResult read_data_files_in_search_paths(const struct loader_instance *inst, enu

#if defined(__APPLE__)
char *bundle_path = NULL;
char *search_only_in_bundle_env_var = loader_secure_getenv(VK_LOADER_SEARCH_ONLY_IN_BUNDLE_ENV_VAR, inst);
#endif

#if defined(_WIN32)
Expand Down Expand Up @@ -3656,6 +3657,8 @@ VkResult read_data_files_in_search_paths(const struct loader_instance *inst, enu
}
}
#elif COMMON_UNIX_PLATFORMS
bool search_outside_of_bundle = true;

rel_size = strlen(relative_location);
if (rel_size > 0) {
#if defined(__APPLE__)
Expand Down Expand Up @@ -3714,41 +3717,46 @@ VkResult read_data_files_in_search_paths(const struct loader_instance *inst, enu
CFRelease(ref);
}
}
#endif // __APPLE__

// Only add the home folders if not NULL
if (NULL != home_config_dir) {
vk_result = copy_data_file_info(inst, home_config_dir, relative_location, rel_size, &search_paths);
if (NULL != search_only_in_bundle_env_var) {
search_outside_of_bundle = false;
}
#endif // __APPLE__
if (search_outside_of_bundle) {
// Only add the home folders if not NULL
if (NULL != home_config_dir) {
vk_result = copy_data_file_info(inst, home_config_dir, relative_location, rel_size, &search_paths);
if (VK_SUCCESS != vk_result) {
goto out;
}
}
vk_result = copy_data_file_info(inst, xdg_config_dirs, relative_location, rel_size, &search_paths);
if (VK_SUCCESS != vk_result) {
goto out;
}
vk_result = copy_data_file_info(inst, SYSCONFDIR, relative_location, rel_size, &search_paths);
if (VK_SUCCESS != vk_result) {
goto out;
}
}
vk_result = copy_data_file_info(inst, xdg_config_dirs, relative_location, rel_size, &search_paths);
if (VK_SUCCESS != vk_result) {
goto out;
}
vk_result = copy_data_file_info(inst, SYSCONFDIR, relative_location, rel_size, &search_paths);
if (VK_SUCCESS != vk_result) {
goto out;
}
#if defined(EXTRASYSCONFDIR)
vk_result = copy_data_file_info(inst, EXTRASYSCONFDIR, relative_location, rel_size, &search_paths);
if (VK_SUCCESS != vk_result) {
goto out;
}
vk_result = copy_data_file_info(inst, EXTRASYSCONFDIR, relative_location, rel_size, &search_paths);
if (VK_SUCCESS != vk_result) {
goto out;
}
#endif

// Only add the home folders if not NULL
if (NULL != home_data_dir) {
vk_result = copy_data_file_info(inst, home_data_dir, relative_location, rel_size, &search_paths);
// Only add the home folders if not NULL
if (NULL != home_data_dir) {
vk_result = copy_data_file_info(inst, home_data_dir, relative_location, rel_size, &search_paths);
if (VK_SUCCESS != vk_result) {
goto out;
}
}
vk_result = copy_data_file_info(inst, xdg_data_dirs, relative_location, rel_size, &search_paths);
if (VK_SUCCESS != vk_result) {
goto out;
}
}
vk_result = copy_data_file_info(inst, xdg_data_dirs, relative_location, rel_size, &search_paths);
if (VK_SUCCESS != vk_result) {
goto out;
}
}
#else
#warning read_data_files_in_search_paths unsupported platform
Expand Down Expand Up @@ -3799,6 +3807,7 @@ VkResult read_data_files_in_search_paths(const struct loader_instance *inst, enu
#elif COMMON_UNIX_PLATFORMS
#if defined(__APPLE__)
loader_instance_heap_free(inst, bundle_path);
loader_free_getenv(search_only_in_bundle_env_var, inst);
#endif
loader_free_getenv(xdg_config_home, inst);
loader_free_getenv(xdg_config_dirs, inst);
Expand Down
4 changes: 4 additions & 0 deletions loader/vk_loader_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@
#define VK_VENDOR_ID_FILTER_ENV_VAR "VK_LOADER_VENDOR_ID_FILTER"
#define VK_DRIVER_ID_FILTER_ENV_VAR "VK_LOADER_DRIVER_ID_FILTER"

#if defined(__APPLE__)
#define VK_LOADER_SEARCH_ONLY_IN_BUNDLE_ENV_VAR "VK_LOADER_SEARCH_ONLY_IN_BUNDLE"
#endif

// Override layer information
#define VK_OVERRIDE_LAYER_NAME "VK_LAYER_LUNARG_override"

Expand Down
4 changes: 3 additions & 1 deletion tests/framework/test_environment.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,9 @@ struct FrameworkEnvironment {

#if TESTING_COMMON_UNIX_PLATFORMS
EnvVarWrapper env_var_home{"HOME", "/home/fake_home"};
#if !defined(__APPLE__)
#if defined(__APPLE__)
EnvVarWrapper env_var_search_only_in_bundle{"VK_LOADER_SEARCH_ONLY_IN_BUNDLE"};
#else
EnvVarWrapper env_var_xdg_config_home{"XDG_CONFIG_HOME"};
EnvVarWrapper env_var_xdg_config_dirs{"XDG_CONFIG_DIRS"};
EnvVarWrapper env_var_xdg_data_home{"XDG_DATA_HOME"};
Expand Down
31 changes: 31 additions & 0 deletions tests/loader_regression_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4478,6 +4478,37 @@ TEST(ManifestDiscovery, AppleBundles) {
ASSERT_EQ(test_physical_device_0.properties.deviceID, props.deviceID);
}

// Add two drivers, one to the bundle and one to the system locations
TEST(ManifestDiscovery, AppleBundlesWithSearchOnlyInBundleEnvVar) {
FrameworkEnvironment env{};
env.env_var_search_only_in_bundle.set_new_value("1");
env.setup_macos_bundle();
env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA,
ManifestOptions{}.set_discovery_type(ManifestDiscoveryType::macos_bundle));
auto& test_physical_device_0 = env.get_test_icd(0).add_and_get_physical_device({});
test_physical_device_0.properties.deviceID = 1337;
env.add_icd(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA);
auto& test_physical_device_1 = env.get_test_icd(1).add_and_get_physical_device({});
test_physical_device_1.properties.deviceID = 9999;

env.add_explicit_layer(
{}, ManifestLayer{}.add_layer(
ManifestLayer::LayerDescription{}.set_name("VK_LAYER_test").set_lib_path(TEST_LAYER_PATH_EXPORT_VERSION_2)));

InstWrapper inst{env.vulkan_functions};
ASSERT_NO_FATAL_FAILURE(inst.CheckCreate());
auto physical_devices = inst.GetPhysDevs();
ASSERT_EQ(1, physical_devices.size());

// should only get bundled driver and layer
VkPhysicalDeviceProperties props{};
inst->vkGetPhysicalDeviceProperties(physical_devices[0], &props);
ASSERT_EQ(test_physical_device_0.properties.deviceID, props.deviceID);

// No layers should be found
env.GetLayerProperties(0);
}

// Add two drivers, one to the bundle and one using the driver env-var
TEST(ManifestDiscovery, AppleBundlesEnvVarActive) {
FrameworkEnvironment env{};
Expand Down
Loading