@@ -3203,6 +3203,161 @@ TEST(SettingsFile, InvalidAdditionalDriversField) {
32033203 EXPECT_TRUE (string_eq (active_layer_props.at (0 ).layerName , layer_name));
32043204}
32053205
3206+ // Reproduces #1915: the settings file's device_configurations list restricts
3207+ // what vkEnumeratePhysicalDevices reports, but vkEnumeratePhysicalDeviceGroups
3208+ // ignores it entirely, so an application can still reach a hidden device.
3209+ //
3210+ // Singleton groups only -- one group per physical device. There is no
3211+ // ambiguity in that case: a device the settings file hides must not be
3212+ // reachable through any group.
3213+ TEST (SettingsFile, DeviceConfigurationAppliesToPhysicalDeviceGroups) {
3214+ FrameworkEnvironment env{};
3215+ std::vector<VulkanUUID> uuids{2 , VulkanUUID{0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 }};
3216+
3217+ // Mix up the uuid's so that they are all unique
3218+ int count = 1 ;
3219+ for (auto & uuid : uuids) {
3220+ std::rotate (uuid.begin (), uuid.begin () + count, uuid.end ());
3221+ count++;
3222+ }
3223+
3224+ auto & icd = env.add_icd (TEST_ICD_PATH_VERSION_2 ).set_icd_api_version (VK_API_VERSION_1_1 );
3225+ icd.add_physical_device (
3226+ PhysicalDevice ().set_deviceName (" visible" ).set_api_version (VK_API_VERSION_1_1 ).set_deviceUUID (uuids[0 ]));
3227+ icd.add_physical_device (PhysicalDevice ().set_deviceName (" hidden" ).set_api_version (VK_API_VERSION_1_1 ).set_deviceUUID (uuids[1 ]));
3228+
3229+ icd.physical_device_groups .emplace_back (0 );
3230+ icd.physical_device_groups .emplace_back (1 );
3231+
3232+ // The settings file lists only the first device, so the second is hidden.
3233+ env.loader_settings .set_file_format_version ({1 , 0 , 0 }).add_app_specific_setting (AppSpecificSettings{});
3234+ env.loader_settings .app_specific_settings .at (0 ).add_device_configuration (
3235+ LoaderSettingsDeviceConfiguration{}.set_deviceUUID (uuids[0 ]));
3236+ env.update_loader_settings (env.loader_settings );
3237+
3238+ InstWrapper inst{env.vulkan_functions };
3239+ inst.CheckCreate ();
3240+
3241+ // The non-group path already honours the settings file.
3242+ auto pds = inst.GetPhysDevs ();
3243+ ASSERT_EQ (pds.size (), 1U );
3244+
3245+ // The group path must agree. The count query is an upper bound -- the
3246+ // non-group path estimates its count the same way -- so what matters is
3247+ // that the groups actually written out exclude the hidden device.
3248+ uint32_t group_count = 0 ;
3249+ ASSERT_EQ (VK_SUCCESS , inst->vkEnumeratePhysicalDeviceGroups (inst, &group_count, nullptr ));
3250+ ASSERT_GE (group_count, 1U );
3251+
3252+ std::vector<VkPhysicalDeviceGroupProperties> groups{
3253+ group_count, VkPhysicalDeviceGroupProperties{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES }};
3254+ ASSERT_EQ (VK_SUCCESS , inst->vkEnumeratePhysicalDeviceGroups (inst, &group_count, groups.data ()));
3255+ ASSERT_EQ (group_count, 1U );
3256+
3257+ // ...and the one device reachable through it is the visible one.
3258+ ASSERT_EQ (groups[0 ].physicalDeviceCount , 1U );
3259+ VkPhysicalDeviceProperties props{};
3260+ inst->vkGetPhysicalDeviceProperties (groups[0 ].physicalDevices [0 ], &props);
3261+ ASSERT_TRUE (string_eq (props.deviceName , " visible" ));
3262+ }
3263+
3264+ // A group holding both a visible and a hidden device is dropped whole rather
3265+ // than having the hidden device removed from it. The devices in a group are
3266+ // physically linked, so a group missing a member misdescribes the hardware.
3267+ TEST (SettingsFile, DeviceConfigurationDropsPartiallyHiddenPhysicalDeviceGroup) {
3268+ FrameworkEnvironment env{};
3269+ std::vector<VulkanUUID> uuids{2 , VulkanUUID{0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 }};
3270+
3271+ int count = 1 ;
3272+ for (auto & uuid : uuids) {
3273+ std::rotate (uuid.begin (), uuid.begin () + count, uuid.end ());
3274+ count++;
3275+ }
3276+
3277+ auto & icd = env.add_icd (TEST_ICD_PATH_VERSION_2 ).set_icd_api_version (VK_API_VERSION_1_1 );
3278+ icd.add_physical_device (
3279+ PhysicalDevice ().set_deviceName (" visible" ).set_api_version (VK_API_VERSION_1_1 ).set_deviceUUID (uuids[0 ]));
3280+ icd.add_physical_device (PhysicalDevice ().set_deviceName (" hidden" ).set_api_version (VK_API_VERSION_1_1 ).set_deviceUUID (uuids[1 ]));
3281+
3282+ // A single group containing both devices.
3283+ icd.physical_device_groups .push_back (PhysicalDeviceGroup ({0 , 1 }));
3284+
3285+ env.loader_settings .set_file_format_version ({1 , 0 , 0 }).add_app_specific_setting (AppSpecificSettings{});
3286+ env.loader_settings .app_specific_settings .at (0 ).add_device_configuration (
3287+ LoaderSettingsDeviceConfiguration{}.set_deviceUUID (uuids[0 ]));
3288+ env.update_loader_settings (env.loader_settings );
3289+
3290+ InstWrapper inst{env.vulkan_functions };
3291+ inst.CheckCreate ();
3292+
3293+ auto pds = inst.GetPhysDevs ();
3294+ ASSERT_EQ (pds.size (), 1U );
3295+
3296+ uint32_t group_count = 0 ;
3297+ ASSERT_EQ (VK_SUCCESS , inst->vkEnumeratePhysicalDeviceGroups (inst, &group_count, nullptr ));
3298+ std::vector<VkPhysicalDeviceGroupProperties> groups{
3299+ group_count, VkPhysicalDeviceGroupProperties{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES }};
3300+ ASSERT_EQ (VK_SUCCESS , inst->vkEnumeratePhysicalDeviceGroups (inst, &group_count, groups.data ()));
3301+ ASSERT_EQ (group_count, 0U );
3302+ }
3303+
3304+ // When no device matches the settings file, the group path fails the same way
3305+ // the plain path does rather than quietly reporting every group.
3306+ TEST (SettingsFile, DeviceConfigurationMatchingNothingFailsPhysicalDeviceGroups) {
3307+ FrameworkEnvironment env{};
3308+ std::vector<VulkanUUID> uuids{2 , VulkanUUID{0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 }};
3309+
3310+ int count = 1 ;
3311+ for (auto & uuid : uuids) {
3312+ std::rotate (uuid.begin (), uuid.begin () + count, uuid.end ());
3313+ count++;
3314+ }
3315+
3316+ auto & icd = env.add_icd (TEST_ICD_PATH_VERSION_2 ).set_icd_api_version (VK_API_VERSION_1_1 );
3317+ icd.add_physical_device (PhysicalDevice ().set_deviceName (" only" ).set_api_version (VK_API_VERSION_1_1 ).set_deviceUUID (uuids[0 ]));
3318+ icd.physical_device_groups .emplace_back (0 );
3319+
3320+ // The settings file names a device that does not exist.
3321+ env.loader_settings .set_file_format_version ({1 , 0 , 0 }).add_app_specific_setting (AppSpecificSettings{});
3322+ env.loader_settings .app_specific_settings .at (0 ).add_device_configuration (
3323+ LoaderSettingsDeviceConfiguration{}.set_deviceUUID (uuids[1 ]));
3324+ env.update_loader_settings (env.loader_settings );
3325+
3326+ InstWrapper inst{env.vulkan_functions };
3327+ inst.CheckCreate ();
3328+
3329+ inst.GetPhysDev (VK_ERROR_INITIALIZATION_FAILED );
3330+
3331+ uint32_t group_count = 0 ;
3332+ ASSERT_EQ (VK_SUCCESS , inst->vkEnumeratePhysicalDeviceGroups (inst, &group_count, nullptr ));
3333+ std::vector<VkPhysicalDeviceGroupProperties> groups{
3334+ group_count, VkPhysicalDeviceGroupProperties{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES }};
3335+ ASSERT_EQ (VK_ERROR_INITIALIZATION_FAILED , inst->vkEnumeratePhysicalDeviceGroups (inst, &group_count, groups.data ()));
3336+ }
3337+
3338+ // Without a settings file the groups are reported exactly as the driver gives
3339+ // them, so the filtering above must not disturb the normal path.
3340+ TEST (SettingsFile, NoDeviceConfigurationLeavesPhysicalDeviceGroupsAlone) {
3341+ FrameworkEnvironment env{};
3342+
3343+ auto & icd = env.add_icd (TEST_ICD_PATH_VERSION_2 ).set_icd_api_version (VK_API_VERSION_1_1 );
3344+ icd.add_physical_device (PhysicalDevice ().set_deviceName (" first" ).set_api_version (VK_API_VERSION_1_1 ));
3345+ icd.add_physical_device (PhysicalDevice ().set_deviceName (" second" ).set_api_version (VK_API_VERSION_1_1 ));
3346+
3347+ icd.physical_device_groups .emplace_back (0 );
3348+ icd.physical_device_groups .emplace_back (1 );
3349+
3350+ InstWrapper inst{env.vulkan_functions };
3351+ inst.CheckCreate ();
3352+
3353+ uint32_t group_count = 0 ;
3354+ ASSERT_EQ (VK_SUCCESS , inst->vkEnumeratePhysicalDeviceGroups (inst, &group_count, nullptr ));
3355+ std::vector<VkPhysicalDeviceGroupProperties> groups{
3356+ group_count, VkPhysicalDeviceGroupProperties{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES }};
3357+ ASSERT_EQ (VK_SUCCESS , inst->vkEnumeratePhysicalDeviceGroups (inst, &group_count, groups.data ()));
3358+ ASSERT_EQ (group_count, 2U );
3359+ }
3360+
32063361TEST (SettingsFile, DriverConfigurationsInSpecifiedOrder) {
32073362 FrameworkEnvironment env{};
32083363 std::vector<VulkanUUID> uuids{10 , VulkanUUID{0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 }};
0 commit comments