@@ -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
@@ -3801,18 +3803,26 @@ VkResult loader_icd_scan(const struct loader_instance *inst, struct loader_icd_t
38013803 goto out ;
38023804 }
38033805
3804- // Parse the filter environment variables to determine if we have any special behavior
3805- res = parse_generic_filter_environment_var (inst , VK_DRIVERS_SELECT_ENV_VAR , & select_filter );
3806- if (VK_SUCCESS != res ) {
3807- goto out ;
3806+ if (loader_settings_should_use_driver_environment_variables (inst )) {
3807+ // Parse the filter environment variables to determine if we have any special behavior
3808+ res = parse_generic_filter_environment_var (inst , VK_DRIVERS_SELECT_ENV_VAR , & select_filter );
3809+ if (VK_SUCCESS != res ) {
3810+ goto out ;
3811+ }
3812+ res = parse_generic_filter_environment_var (inst , VK_DRIVERS_DISABLE_ENV_VAR , & disable_filter );
3813+ if (VK_SUCCESS != res ) {
3814+ goto out ;
3815+ }
38083816 }
3809- res = parse_generic_filter_environment_var (inst , VK_DRIVERS_DISABLE_ENV_VAR , & disable_filter );
3817+
3818+ // Get a list of manifest files for ICDs
3819+ res = loader_get_data_files (inst , LOADER_DATA_FILE_MANIFEST_DRIVER , NULL , & manifest_files );
38103820 if (VK_SUCCESS != res ) {
38113821 goto out ;
38123822 }
38133823
3814- // Get a list of manifest files for ICDs
3815- res = loader_get_data_files (inst , LOADER_DATA_FILE_MANIFEST_DRIVER , NULL , & manifest_files );
3824+ // Add any drivers provided by the loader settings file
3825+ res = loader_settings_get_additional_driver_files (inst , & manifest_files );
38163826 if (VK_SUCCESS != res ) {
38173827 goto out ;
38183828 }
@@ -5459,10 +5469,10 @@ VkResult loader_validate_device_extensions(struct loader_instance *this_instance
54595469// All named terminator_<Vulkan API name>
54605470VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance (const VkInstanceCreateInfo * pCreateInfo ,
54615471 const VkAllocationCallbacks * pAllocator , VkInstance * pInstance ) {
5462- struct loader_icd_term * icd_term ;
5463- VkExtensionProperties * prop ;
5472+ struct loader_icd_term * icd_term = NULL ;
5473+ VkExtensionProperties * prop = NULL ;
54645474 char * * filtered_extension_names = NULL ;
5465- VkInstanceCreateInfo icd_create_info ;
5475+ VkInstanceCreateInfo icd_create_info = { 0 } ;
54665476 VkResult res = VK_SUCCESS ;
54675477 bool one_icd_successful = false;
54685478
@@ -5650,7 +5660,7 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(const VkInstanceCreateI
56505660 }
56515661
56525662 // Create an instance, substituting the version to 1.0 if necessary
5653- VkApplicationInfo icd_app_info ;
5663+ VkApplicationInfo icd_app_info = { 0 } ;
56545664 const uint32_t api_variant = 0 ;
56555665 const uint32_t api_version_1_0 = VK_API_VERSION_1_0 ;
56565666 uint32_t icd_version_nopatch =
@@ -5667,6 +5677,25 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(const VkInstanceCreateI
56675677 icd_app_info .apiVersion = icd_version ;
56685678 icd_create_info .pApplicationInfo = & icd_app_info ;
56695679 }
5680+
5681+ // If the settings file has device_configurations, we need to raise the ApiVersion drivers use to 1.1 if the driver
5682+ // supports 1.1 or higher. This allows 1.0 apps to use the device_configurations without the app having to set its own
5683+ // ApiVersion to 1.1 on its own.
5684+ if (ptr_instance -> settings .settings_active && ptr_instance -> settings .device_configuration_count > 0 &&
5685+ icd_version >= VK_API_VERSION_1_1 && requested_version < VK_API_VERSION_1_1 ) {
5686+ if (NULL != pCreateInfo -> pApplicationInfo ) {
5687+ memcpy (& icd_app_info , pCreateInfo -> pApplicationInfo , sizeof (VkApplicationInfo ));
5688+ }
5689+ icd_app_info .apiVersion = VK_API_VERSION_1_1 ;
5690+ icd_create_info .pApplicationInfo = & icd_app_info ;
5691+
5692+ loader_log (
5693+ ptr_instance , VULKAN_LOADER_INFO_BIT , 0 ,
5694+ "terminator_CreateInstance: Raising the VkApplicationInfo::apiVersion from 1.0 to 1.1 on driver \"%s\" so that "
5695+ "the loader settings file is able to use this driver in the device_configuration selection logic." ,
5696+ icd_term -> scanned_icd -> lib_name );
5697+ }
5698+
56705699 icd_result =
56715700 ptr_instance -> icd_tramp_list .scanned_list [i ].CreateInstance (& icd_create_info , pAllocator , & (icd_term -> instance ));
56725701 if (VK_ERROR_OUT_OF_HOST_MEMORY == icd_result ) {
@@ -6780,28 +6809,133 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDevices(VkInstance in
67806809 goto out ;
67816810 }
67826811
6783- uint32_t copy_count = inst -> phys_dev_count_term ;
6784- if (NULL != pPhysicalDevices ) {
6785- if (copy_count > * pPhysicalDeviceCount ) {
6786- copy_count = * pPhysicalDeviceCount ;
6787- loader_log (inst , VULKAN_LOADER_INFO_BIT , 0 ,
6788- "terminator_EnumeratePhysicalDevices : Trimming device count from %d to %d." , inst -> phys_dev_count_term ,
6789- copy_count );
6790- res = VK_INCOMPLETE ;
6812+ if (inst -> settings .settings_active && inst -> settings .device_configuration_count > 0 ) {
6813+ // Use settings file device_configurations if present
6814+ if (NULL == pPhysicalDevices ) {
6815+ // take the minimum of the settings configurations count and number of terminators
6816+ * pPhysicalDeviceCount = (inst -> settings .device_configuration_count < inst -> phys_dev_count_term )
6817+ ? inst -> settings .device_configuration_count
6818+ : inst -> phys_dev_count_term ;
6819+ } else {
6820+ res = loader_apply_settings_device_configurations (inst , pPhysicalDeviceCount , pPhysicalDevices );
67916821 }
6822+ } else {
6823+ // Otherwise just copy the physical devices up normally and pass it up the chain
6824+ uint32_t copy_count = inst -> phys_dev_count_term ;
6825+ if (NULL != pPhysicalDevices ) {
6826+ if (copy_count > * pPhysicalDeviceCount ) {
6827+ copy_count = * pPhysicalDeviceCount ;
6828+ loader_log (inst , VULKAN_LOADER_INFO_BIT , 0 ,
6829+ "terminator_EnumeratePhysicalDevices : Trimming device count from %d to %d." , inst -> phys_dev_count_term ,
6830+ copy_count );
6831+ res = VK_INCOMPLETE ;
6832+ }
67926833
6793- for (uint32_t i = 0 ; i < copy_count ; i ++ ) {
6794- pPhysicalDevices [i ] = (VkPhysicalDevice )inst -> phys_devs_term [i ];
6834+ for (uint32_t i = 0 ; i < copy_count ; i ++ ) {
6835+ pPhysicalDevices [i ] = (VkPhysicalDevice )inst -> phys_devs_term [i ];
6836+ }
67956837 }
6796- }
67976838
6798- * pPhysicalDeviceCount = copy_count ;
6839+ * pPhysicalDeviceCount = copy_count ;
6840+ }
67996841
68006842out :
68016843
68026844 return res ;
68036845}
68046846
6847+ // Apply the device_configurations in the settings file to the output VkPhysicalDeviceList.
6848+ // That means looking up each VkPhysicalDevice's deviceUUID, filtering using that, and putting them in the order of
6849+ // device_configurations in the settings file.
6850+ VkResult loader_apply_settings_device_configurations (struct loader_instance * inst , uint32_t * pPhysicalDeviceCount ,
6851+ VkPhysicalDevice * pPhysicalDevices ) {
6852+ bool * pd_supports_11 = loader_stack_alloc (inst -> phys_dev_count_term * sizeof (bool ));
6853+ if (NULL == pd_supports_11 ) {
6854+ return VK_ERROR_OUT_OF_HOST_MEMORY ;
6855+ }
6856+ memset (pd_supports_11 , 0 , inst -> phys_dev_count_term * sizeof (bool ));
6857+
6858+ VkPhysicalDeviceProperties * pd_props = loader_stack_alloc (inst -> phys_dev_count_term * sizeof (VkPhysicalDeviceProperties ));
6859+ if (NULL == pd_props ) {
6860+ return VK_ERROR_OUT_OF_HOST_MEMORY ;
6861+ }
6862+ memset (pd_props , 0 , inst -> phys_dev_count_term * sizeof (VkPhysicalDeviceProperties ));
6863+
6864+ VkPhysicalDeviceVulkan11Properties * pd_vulkan_11_props =
6865+ loader_stack_alloc (inst -> phys_dev_count_term * sizeof (VkPhysicalDeviceVulkan11Properties ));
6866+ if (NULL == pd_vulkan_11_props ) {
6867+ return VK_ERROR_OUT_OF_HOST_MEMORY ;
6868+ }
6869+ memset (pd_vulkan_11_props , 0 , inst -> phys_dev_count_term * sizeof (VkPhysicalDeviceVulkan11Properties ));
6870+
6871+ for (uint32_t i = 0 ; i < inst -> phys_dev_count_term ; i ++ ) {
6872+ pd_vulkan_11_props [i ].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES ;
6873+
6874+ inst -> phys_devs_term [i ]-> this_icd_term -> dispatch .GetPhysicalDeviceProperties (inst -> phys_devs_term [i ]-> phys_dev ,
6875+ & pd_props [i ]);
6876+ if (pd_props [i ].apiVersion >= VK_API_VERSION_1_1 ) {
6877+ pd_supports_11 [i ] = true;
6878+ VkPhysicalDeviceProperties2 props2 = {0 };
6879+ props2 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 ;
6880+ props2 .pNext = (void * )& pd_vulkan_11_props [i ];
6881+ if (inst -> phys_devs_term [i ]-> this_icd_term -> dispatch .GetPhysicalDeviceProperties2 ) {
6882+ inst -> phys_devs_term [i ]-> this_icd_term -> dispatch .GetPhysicalDeviceProperties2 (inst -> phys_devs_term [i ]-> phys_dev ,
6883+ & props2 );
6884+ }
6885+ }
6886+ }
6887+
6888+ // Loop over the setting's device configurations, find each VkPhysicalDevice which matches the deviceUUID given, add to the
6889+ // pPhysicalDevices output list.
6890+ uint32_t written_output_index = 0 ;
6891+
6892+ for (uint32_t i = 0 ; i < inst -> settings .device_configuration_count ; i ++ ) {
6893+ uint8_t * current_deviceUUID = inst -> settings .device_configurations [i ].deviceUUID ;
6894+ bool configuration_found = false;
6895+ for (uint32_t j = 0 ; j < inst -> phys_dev_count_term ; j ++ ) {
6896+ // Don't compare deviceUUID's if they have nothing, since we require deviceUUID's to effectively sort them.
6897+ if (!pd_supports_11 [j ]) {
6898+ continue ;
6899+ }
6900+ if (memcmp (current_deviceUUID , pd_vulkan_11_props [j ].deviceUUID , sizeof (uint8_t ) * VK_UUID_SIZE ) == 0 ) {
6901+ configuration_found = true;
6902+ // Catch when there are more device_configurations than space available in the output
6903+ if (written_output_index >= * pPhysicalDeviceCount ) {
6904+ * pPhysicalDeviceCount = written_output_index ; // write out how many were written
6905+ return VK_INCOMPLETE ;
6906+ }
6907+ pPhysicalDevices [written_output_index ++ ] = (VkPhysicalDevice )inst -> phys_devs_term [j ];
6908+ loader_log (inst , VULKAN_LOADER_INFO_BIT , 0 , "Insert VkPhysicalDevice \"%s\" to the pPhysicalDevices list" ,
6909+ pd_props [j ].deviceName );
6910+ break ;
6911+ }
6912+ }
6913+ if (!configuration_found ) {
6914+ uint8_t * id = current_deviceUUID ;
6915+ // Log that this configuration was missing.
6916+ if (inst -> settings .device_configurations [i ].deviceName [0 ] != '\0' ) {
6917+ loader_log (
6918+ inst , VULKAN_LOADER_WARN_BIT , 0 ,
6919+ "loader_apply_settings_device_configurations: settings file contained device_configuration which does not "
6920+ "appear in the enumerated VkPhysicalDevices. Missing VkPhysicalDevice with deviceName: \"%s\" and deviceUUID: "
6921+ "%x%x%x%x-%x%x-%x%x-%x%x-%x%x%x%x%x%x" ,
6922+ inst -> settings .device_configurations [i ].deviceName , id [0 ], id [1 ], id [2 ], id [3 ], id [4 ], id [5 ], id [6 ], id [7 ],
6923+ id [8 ], id [9 ], id [10 ], id [11 ], id [12 ], id [13 ], id [14 ], id [15 ]);
6924+ } else {
6925+ loader_log (
6926+ inst , VULKAN_LOADER_WARN_BIT , 0 ,
6927+ "loader_apply_settings_device_configurations: settings file contained device_configuration which does not "
6928+ "appear in the enumerated VkPhysicalDevices. Missing VkPhysicalDevice with deviceUUID: "
6929+ "%x%x%x%x-%x%x-%x%x-%x%x-%x%x%x%x%x%x" ,
6930+ 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 ],
6931+ id [15 ]);
6932+ }
6933+ }
6934+ }
6935+ * pPhysicalDeviceCount = written_output_index ; // update with how many were written
6936+ return VK_SUCCESS ;
6937+ }
6938+
68056939VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumerateDeviceExtensionProperties (VkPhysicalDevice physicalDevice ,
68066940 const char * pLayerName , uint32_t * pPropertyCount ,
68076941 VkExtensionProperties * pProperties ) {
0 commit comments