Skip to content

Commit e77c0af

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 e77c0af

11 files changed

Lines changed: 748 additions & 40 deletions

File tree

loader/loader.c

Lines changed: 119 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,113 @@ 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+
// take the minimum of the settings configurations count and number of terminators
6798+
*pPhysicalDeviceCount = (inst->settings.device_configuration_count < inst->phys_dev_count_term)
6799+
? inst->settings.device_configuration_count
6800+
: inst->phys_dev_count_term;
6801+
} else {
6802+
res = loader_apply_settings_device_configurations(inst, pPhysicalDeviceCount, pPhysicalDevices);
67926803
}
6804+
} else {
6805+
// Otherwise just copy the physical devices up normally and pass it up the chain
6806+
uint32_t copy_count = inst->phys_dev_count_term;
6807+
if (NULL != pPhysicalDevices) {
6808+
if (copy_count > *pPhysicalDeviceCount) {
6809+
copy_count = *pPhysicalDeviceCount;
6810+
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
6811+
"terminator_EnumeratePhysicalDevices : Trimming device count from %d to %d.", inst->phys_dev_count_term,
6812+
copy_count);
6813+
res = VK_INCOMPLETE;
6814+
}
67936815

6794-
for (uint32_t i = 0; i < copy_count; i++) {
6795-
pPhysicalDevices[i] = (VkPhysicalDevice)inst->phys_devs_term[i];
6816+
for (uint32_t i = 0; i < copy_count; i++) {
6817+
pPhysicalDevices[i] = (VkPhysicalDevice)inst->phys_devs_term[i];
6818+
}
67966819
}
6797-
}
67986820

6799-
*pPhysicalDeviceCount = copy_count;
6821+
*pPhysicalDeviceCount = copy_count;
6822+
}
68006823

68016824
out:
68026825

68036826
return res;
68046827
}
68056828

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