Skip to content

Commit be5c44e

Browse files
Add device and drivers fields to settings file
The loader settings file now can specify additional drivers to include, whether to use those drivers exclusively, and filter/sort the VkPhysicalDevices using the settings file provided list of deviceUUID's. This lets the settings file control which drivers and/or devices are reported by the loader, giving greater control over the runtime behavior of the loader.
1 parent 01526ab commit be5c44e

File tree

11 files changed

+746
-40
lines changed

11 files changed

+746
-40
lines changed

loader/loader.c

Lines changed: 116 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3257,12 +3257,14 @@ VkResult read_data_files_in_search_paths(const struct loader_instance *inst, enu
32573257

32583258
switch (manifest_type) {
32593259
case LOADER_DATA_FILE_MANIFEST_DRIVER:
3260-
override_env = loader_secure_getenv(VK_DRIVER_FILES_ENV_VAR, inst);
3261-
if (NULL == override_env) {
3262-
// Not there, so fall back to the old name
3263-
override_env = loader_secure_getenv(VK_ICD_FILENAMES_ENV_VAR, inst);
3260+
if (loader_settings_should_use_driver_environment_variables(inst)) {
3261+
override_env = loader_secure_getenv(VK_DRIVER_FILES_ENV_VAR, inst);
3262+
if (NULL == override_env) {
3263+
// Not there, so fall back to the old name
3264+
override_env = loader_secure_getenv(VK_ICD_FILENAMES_ENV_VAR, inst);
3265+
}
3266+
additional_env = loader_secure_getenv(VK_ADDITIONAL_DRIVER_FILES_ENV_VAR, inst);
32643267
}
3265-
additional_env = loader_secure_getenv(VK_ADDITIONAL_DRIVER_FILES_ENV_VAR, inst);
32663268
#if COMMON_UNIX_PLATFORMS
32673269
relative_location = VK_DRIVERS_INFO_RELATIVE_DIR;
32683270
#endif
@@ -3802,18 +3804,26 @@ VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_t
38023804
goto out;
38033805
}
38043806

3805-
// Parse the filter environment variables to determine if we have any special behavior
3806-
res = parse_generic_filter_environment_var(inst, VK_DRIVERS_SELECT_ENV_VAR, &select_filter);
3807-
if (VK_SUCCESS != res) {
3808-
goto out;
3807+
if (loader_settings_should_use_driver_environment_variables(inst)) {
3808+
// Parse the filter environment variables to determine if we have any special behavior
3809+
res = parse_generic_filter_environment_var(inst, VK_DRIVERS_SELECT_ENV_VAR, &select_filter);
3810+
if (VK_SUCCESS != res) {
3811+
goto out;
3812+
}
3813+
res = parse_generic_filter_environment_var(inst, VK_DRIVERS_DISABLE_ENV_VAR, &disable_filter);
3814+
if (VK_SUCCESS != res) {
3815+
goto out;
3816+
}
38093817
}
3810-
res = parse_generic_filter_environment_var(inst, VK_DRIVERS_DISABLE_ENV_VAR, &disable_filter);
3818+
3819+
// Get a list of manifest files for ICDs
3820+
res = loader_get_data_files(inst, LOADER_DATA_FILE_MANIFEST_DRIVER, NULL, &manifest_files);
38113821
if (VK_SUCCESS != res) {
38123822
goto out;
38133823
}
38143824

3815-
// Get a list of manifest files for ICDs
3816-
res = loader_get_data_files(inst, LOADER_DATA_FILE_MANIFEST_DRIVER, NULL, &manifest_files);
3825+
// Add any drivers provided by the loader settings file
3826+
res = loader_settings_get_additional_driver_files(inst, &manifest_files);
38173827
if (VK_SUCCESS != res) {
38183828
goto out;
38193829
}
@@ -6781,28 +6791,110 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDevices(VkInstance in
67816791
goto out;
67826792
}
67836793

6784-
uint32_t copy_count = inst->phys_dev_count_term;
6785-
if (NULL != pPhysicalDevices) {
6786-
if (copy_count > *pPhysicalDeviceCount) {
6787-
copy_count = *pPhysicalDeviceCount;
6788-
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
6789-
"terminator_EnumeratePhysicalDevices : Trimming device count from %d to %d.", inst->phys_dev_count_term,
6790-
copy_count);
6791-
res = VK_INCOMPLETE;
6794+
if (inst->settings.settings_active && inst->settings.device_configuration_count > 0) {
6795+
// Use settings file device_configurations if present
6796+
if (NULL == pPhysicalDevices) {
6797+
*pPhysicalDeviceCount = min(inst->settings.device_configuration_count, inst->phys_dev_count_term);
6798+
} else {
6799+
res = loader_apply_settings_device_configurations(inst, pPhysicalDeviceCount, pPhysicalDevices);
67926800
}
6801+
} else {
6802+
// Otherwise just copy the physical devices up normally and pass it up the chain
6803+
uint32_t copy_count = inst->phys_dev_count_term;
6804+
if (NULL != pPhysicalDevices) {
6805+
if (copy_count > *pPhysicalDeviceCount) {
6806+
copy_count = *pPhysicalDeviceCount;
6807+
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
6808+
"terminator_EnumeratePhysicalDevices : Trimming device count from %d to %d.", inst->phys_dev_count_term,
6809+
copy_count);
6810+
res = VK_INCOMPLETE;
6811+
}
67936812

6794-
for (uint32_t i = 0; i < copy_count; i++) {
6795-
pPhysicalDevices[i] = (VkPhysicalDevice)inst->phys_devs_term[i];
6813+
for (uint32_t i = 0; i < copy_count; i++) {
6814+
pPhysicalDevices[i] = (VkPhysicalDevice)inst->phys_devs_term[i];
6815+
}
67966816
}
6797-
}
67986817

6799-
*pPhysicalDeviceCount = copy_count;
6818+
*pPhysicalDeviceCount = copy_count;
6819+
}
68006820

68016821
out:
68026822

68036823
return res;
68046824
}
68056825

6826+
// Apply the device_configurations in the settings file to the output VkPhysicalDeviceList.
6827+
// That means looking up each VkPhysicalDevice's deviceUUID, filtering using that, and putting them in the order of
6828+
// device_configurations in the settings file.
6829+
VkResult loader_apply_settings_device_configurations(struct loader_instance *inst, uint32_t *pPhysicalDeviceCount,
6830+
VkPhysicalDevice *pPhysicalDevices) {
6831+
bool *pd_supports_11 = loader_stack_alloc(inst->phys_dev_count_term * sizeof(bool));
6832+
if (NULL == pd_supports_11) {
6833+
return VK_ERROR_OUT_OF_HOST_MEMORY;
6834+
}
6835+
memset(pd_supports_11, 0, inst->phys_dev_count_term * sizeof(bool));
6836+
6837+
VkPhysicalDeviceVulkan11Properties *pd_vulkan_11_props =
6838+
loader_stack_alloc(inst->phys_dev_count_term * sizeof(VkPhysicalDeviceVulkan11Properties));
6839+
if (NULL == pd_vulkan_11_props) {
6840+
return VK_ERROR_OUT_OF_HOST_MEMORY;
6841+
}
6842+
memset(pd_vulkan_11_props, 0, inst->phys_dev_count_term * sizeof(VkPhysicalDeviceVulkan11Properties));
6843+
6844+
for (uint32_t i = 0; i < inst->phys_dev_count_term; i++) {
6845+
pd_vulkan_11_props[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
6846+
VkPhysicalDeviceProperties props = {0};
6847+
6848+
inst->phys_devs_term[i]->this_icd_term->dispatch.GetPhysicalDeviceProperties(inst->phys_devs_term[i]->phys_dev, &props);
6849+
if (props.apiVersion >= VK_API_VERSION_1_1) {
6850+
pd_supports_11[i] = true;
6851+
VkPhysicalDeviceProperties2 props2 = {0};
6852+
props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
6853+
props2.pNext = (void *)&pd_vulkan_11_props[i];
6854+
6855+
inst->phys_devs_term[i]->this_icd_term->dispatch.GetPhysicalDeviceProperties2(inst->phys_devs_term[i]->phys_dev,
6856+
&props2);
6857+
}
6858+
}
6859+
6860+
// Loop over the setting's device configurations, find each VkPhysicalDevice which matches the deviceUUID given, add to the
6861+
// pPhysicalDevices output list.
6862+
uint32_t written_output_index = 0;
6863+
6864+
for (uint32_t i = 0; i < inst->settings.device_configuration_count; i++) {
6865+
uint8_t *current_deviceUUID = inst->settings.device_configurations[i].deviceUUID;
6866+
bool configuration_found = false;
6867+
for (uint32_t j = 0; j < inst->phys_dev_count_term; j++) {
6868+
// Don't compare deviceUUID's if they have nothing, since we require deviceUUID's to effectively sort them.
6869+
if (!pd_supports_11[j]) {
6870+
continue;
6871+
}
6872+
if (memcmp(current_deviceUUID, pd_vulkan_11_props[j].deviceUUID, sizeof(uint8_t) * VK_UUID_SIZE) == 0) {
6873+
configuration_found = true;
6874+
// Catch when there are more device_configurations than space available in the output
6875+
if (written_output_index >= *pPhysicalDeviceCount) {
6876+
*pPhysicalDeviceCount = written_output_index; // write out how many were written
6877+
return VK_INCOMPLETE;
6878+
}
6879+
pPhysicalDevices[written_output_index++] = (VkPhysicalDevice)inst->phys_devs_term[j];
6880+
break;
6881+
}
6882+
}
6883+
if (!configuration_found) {
6884+
uint8_t *id = current_deviceUUID;
6885+
// Log that this configuration was missing.
6886+
loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
6887+
"loader_apply_settings_device_configurations: settings file contained device_configuration which does not "
6888+
"appear in the list of enumerated VkPhysicalDevices. Missing device_configuration's deviceUUID: "
6889+
"[%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d]",
6890+
id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7], id[8], id[9], id[10], id[11], id[12], id[13], id[14],
6891+
id[15]);
6892+
}
6893+
}
6894+
*pPhysicalDeviceCount = written_output_index; // update with how many were written
6895+
return VK_SUCCESS;
6896+
}
6897+
68066898
VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
68076899
const char *pLayerName, uint32_t *pPropertyCount,
68086900
VkExtensionProperties *pProperties) {

loader/loader.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ VkResult setup_loader_tramp_phys_dev_groups(struct loader_instance *inst, uint32
221221
VkPhysicalDeviceGroupProperties *groups);
222222
void unload_drivers_without_physical_devices(struct loader_instance *inst);
223223

224+
VkResult loader_apply_settings_device_configurations(struct loader_instance *inst, uint32_t *pPhysicalDeviceCount,
225+
VkPhysicalDevice *pPhysicalDevices);
226+
224227
VkStringErrorFlags vk_string_validate(const int max_length, const char *char_array);
225228
char *loader_get_next_path(char *path);
226229
VkResult add_if_manifest_file(const struct loader_instance *inst, const char *file_name, struct loader_string_list *out_files);

0 commit comments

Comments
 (0)