@@ -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 }
@@ -5659,6 +5669,19 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(const VkInstanceCreateI
56595669 uint32_t requested_version = (pCreateInfo == NULL || pCreateInfo -> pApplicationInfo == NULL )
56605670 ? api_version_1_0
56615671 : pCreateInfo -> pApplicationInfo -> apiVersion ;
5672+ // If the settings file has device_configurations, we need to raise the ApiVersion drivers use to 1.1 if the driver
5673+ // supports 1.1 or higher. This allows 1.0 apps to use the device_configurations without the app having to set its own
5674+ // ApiVersion to 1.1 on its own.
5675+ if (ptr_instance -> settings .settings_active && ptr_instance -> settings .device_configuration_count > 0 &&
5676+ icd_version >= VK_API_VERSION_1_1 && requested_version < VK_API_VERSION_1_1 ) {
5677+ requested_version = VK_API_VERSION_1_1 ;
5678+ loader_log (
5679+ ptr_instance , VULKAN_LOADER_INFO_BIT , 0 ,
5680+ "terminator_CreateInstance: Raising the VkApplicationInfo::apiVersion from 1.0 to 1.1 on driver \"%s\" so that "
5681+ "the loader settings file is able to use this driver in the device_configuration selection logic." ,
5682+ icd_term -> scanned_icd -> lib_name );
5683+ }
5684+
56625685 if ((requested_version != 0 ) && (icd_version_nopatch == api_version_1_0 )) {
56635686 if (icd_create_info .pApplicationInfo == NULL ) {
56645687 memset (& icd_app_info , 0 , sizeof (icd_app_info ));
@@ -6781,28 +6804,133 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDevices(VkInstance in
67816804 goto out ;
67826805 }
67836806
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 ;
6807+ if (inst -> settings .settings_active && inst -> settings .device_configuration_count > 0 ) {
6808+ // Use settings file device_configurations if present
6809+ if (NULL == pPhysicalDevices ) {
6810+ // take the minimum of the settings configurations count and number of terminators
6811+ * pPhysicalDeviceCount = (inst -> settings .device_configuration_count < inst -> phys_dev_count_term )
6812+ ? inst -> settings .device_configuration_count
6813+ : inst -> phys_dev_count_term ;
6814+ } else {
6815+ res = loader_apply_settings_device_configurations (inst , pPhysicalDeviceCount , pPhysicalDevices );
67926816 }
6817+ } else {
6818+ // Otherwise just copy the physical devices up normally and pass it up the chain
6819+ uint32_t copy_count = inst -> phys_dev_count_term ;
6820+ if (NULL != pPhysicalDevices ) {
6821+ if (copy_count > * pPhysicalDeviceCount ) {
6822+ copy_count = * pPhysicalDeviceCount ;
6823+ loader_log (inst , VULKAN_LOADER_INFO_BIT , 0 ,
6824+ "terminator_EnumeratePhysicalDevices : Trimming device count from %d to %d." , inst -> phys_dev_count_term ,
6825+ copy_count );
6826+ res = VK_INCOMPLETE ;
6827+ }
67936828
6794- for (uint32_t i = 0 ; i < copy_count ; i ++ ) {
6795- pPhysicalDevices [i ] = (VkPhysicalDevice )inst -> phys_devs_term [i ];
6829+ for (uint32_t i = 0 ; i < copy_count ; i ++ ) {
6830+ pPhysicalDevices [i ] = (VkPhysicalDevice )inst -> phys_devs_term [i ];
6831+ }
67966832 }
6797- }
67986833
6799- * pPhysicalDeviceCount = copy_count ;
6834+ * pPhysicalDeviceCount = copy_count ;
6835+ }
68006836
68016837out :
68026838
68036839 return res ;
68046840}
68056841
6842+ // Apply the device_configurations in the settings file to the output VkPhysicalDeviceList.
6843+ // That means looking up each VkPhysicalDevice's deviceUUID, filtering using that, and putting them in the order of
6844+ // device_configurations in the settings file.
6845+ VkResult loader_apply_settings_device_configurations (struct loader_instance * inst , uint32_t * pPhysicalDeviceCount ,
6846+ VkPhysicalDevice * pPhysicalDevices ) {
6847+ bool * pd_supports_11 = loader_stack_alloc (inst -> phys_dev_count_term * sizeof (bool ));
6848+ if (NULL == pd_supports_11 ) {
6849+ return VK_ERROR_OUT_OF_HOST_MEMORY ;
6850+ }
6851+ memset (pd_supports_11 , 0 , inst -> phys_dev_count_term * sizeof (bool ));
6852+
6853+ VkPhysicalDeviceProperties * pd_props = loader_stack_alloc (inst -> phys_dev_count_term * sizeof (VkPhysicalDeviceProperties ));
6854+ if (NULL == pd_props ) {
6855+ return VK_ERROR_OUT_OF_HOST_MEMORY ;
6856+ }
6857+ memset (pd_props , 0 , inst -> phys_dev_count_term * sizeof (VkPhysicalDeviceProperties ));
6858+
6859+ VkPhysicalDeviceVulkan11Properties * pd_vulkan_11_props =
6860+ loader_stack_alloc (inst -> phys_dev_count_term * sizeof (VkPhysicalDeviceVulkan11Properties ));
6861+ if (NULL == pd_vulkan_11_props ) {
6862+ return VK_ERROR_OUT_OF_HOST_MEMORY ;
6863+ }
6864+ memset (pd_vulkan_11_props , 0 , inst -> phys_dev_count_term * sizeof (VkPhysicalDeviceVulkan11Properties ));
6865+
6866+ for (uint32_t i = 0 ; i < inst -> phys_dev_count_term ; i ++ ) {
6867+ pd_vulkan_11_props [i ].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES ;
6868+
6869+ inst -> phys_devs_term [i ]-> this_icd_term -> dispatch .GetPhysicalDeviceProperties (inst -> phys_devs_term [i ]-> phys_dev ,
6870+ & pd_props [i ]);
6871+ if (pd_props [i ].apiVersion >= VK_API_VERSION_1_1 ) {
6872+ pd_supports_11 [i ] = true;
6873+ VkPhysicalDeviceProperties2 props2 = {0 };
6874+ props2 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 ;
6875+ props2 .pNext = (void * )& pd_vulkan_11_props [i ];
6876+ if (inst -> phys_devs_term [i ]-> this_icd_term -> dispatch .GetPhysicalDeviceProperties2 ) {
6877+ inst -> phys_devs_term [i ]-> this_icd_term -> dispatch .GetPhysicalDeviceProperties2 (inst -> phys_devs_term [i ]-> phys_dev ,
6878+ & props2 );
6879+ }
6880+ }
6881+ }
6882+
6883+ // Loop over the setting's device configurations, find each VkPhysicalDevice which matches the deviceUUID given, add to the
6884+ // pPhysicalDevices output list.
6885+ uint32_t written_output_index = 0 ;
6886+
6887+ for (uint32_t i = 0 ; i < inst -> settings .device_configuration_count ; i ++ ) {
6888+ uint8_t * current_deviceUUID = inst -> settings .device_configurations [i ].deviceUUID ;
6889+ bool configuration_found = false;
6890+ for (uint32_t j = 0 ; j < inst -> phys_dev_count_term ; j ++ ) {
6891+ // Don't compare deviceUUID's if they have nothing, since we require deviceUUID's to effectively sort them.
6892+ if (!pd_supports_11 [j ]) {
6893+ continue ;
6894+ }
6895+ if (memcmp (current_deviceUUID , pd_vulkan_11_props [j ].deviceUUID , sizeof (uint8_t ) * VK_UUID_SIZE ) == 0 ) {
6896+ configuration_found = true;
6897+ // Catch when there are more device_configurations than space available in the output
6898+ if (written_output_index >= * pPhysicalDeviceCount ) {
6899+ * pPhysicalDeviceCount = written_output_index ; // write out how many were written
6900+ return VK_INCOMPLETE ;
6901+ }
6902+ pPhysicalDevices [written_output_index ++ ] = (VkPhysicalDevice )inst -> phys_devs_term [j ];
6903+ loader_log (inst , VULKAN_LOADER_INFO_BIT , 0 , "Insert VkPhysicalDevice \"%s\" to the pPhysicalDevices list" ,
6904+ pd_props [j ].deviceName );
6905+ break ;
6906+ }
6907+ }
6908+ if (!configuration_found ) {
6909+ uint8_t * id = current_deviceUUID ;
6910+ // Log that this configuration was missing.
6911+ if (inst -> settings .device_configurations [i ].deviceName [0 ] != '\0' ) {
6912+ loader_log (
6913+ inst , VULKAN_LOADER_WARN_BIT , 0 ,
6914+ "loader_apply_settings_device_configurations: settings file contained device_configuration which does not "
6915+ "appear in the enumerated VkPhysicalDevices. Missing VkPhysicalDevice with deviceName: \"%s\" and deviceUUID: "
6916+ "[%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d]" ,
6917+ inst -> settings .device_configurations [i ].deviceName , id [0 ], id [1 ], id [2 ], id [3 ], id [4 ], id [5 ], id [6 ], id [7 ],
6918+ id [8 ], id [9 ], id [10 ], id [11 ], id [12 ], id [13 ], id [14 ], id [15 ]);
6919+ } else {
6920+ loader_log (
6921+ inst , VULKAN_LOADER_WARN_BIT , 0 ,
6922+ "loader_apply_settings_device_configurations: settings file contained device_configuration which does not "
6923+ "appear in the enumerated VkPhysicalDevices. Missing VkPhysicalDevice with deviceUUID: "
6924+ "[%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d]" ,
6925+ 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 ],
6926+ id [15 ]);
6927+ }
6928+ }
6929+ }
6930+ * pPhysicalDeviceCount = written_output_index ; // update with how many were written
6931+ return VK_SUCCESS ;
6932+ }
6933+
68066934VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties (VkPhysicalDevice physicalDevice ,
68076935 const char * pLayerName , uint32_t * pPropertyCount ,
68086936 VkExtensionProperties * pProperties ) {
0 commit comments