Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions loader/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -7122,6 +7122,15 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDevices(VkInstance in
// device_configurations in the settings file.
VkResult loader_apply_settings_device_configurations(struct loader_instance *inst, uint32_t *pPhysicalDeviceCount,
VkPhysicalDevice *pPhysicalDevices) {
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
"Reordering the output of vkEnumeratePhysicalDevices to match the loader settings device configurations list");

bool *pd_was_added = loader_stack_alloc(inst->phys_dev_count_term * sizeof(bool));
if (NULL == pd_was_added) {
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
memset(pd_was_added, 0, inst->phys_dev_count_term * sizeof(bool));

bool *pd_supports_11 = loader_stack_alloc(inst->phys_dev_count_term * sizeof(bool));
if (NULL == pd_supports_11) {
return VK_ERROR_OUT_OF_HOST_MEMORY;
Expand Down Expand Up @@ -7177,9 +7186,10 @@ VkResult loader_apply_settings_device_configurations(struct loader_instance *ins
*pPhysicalDeviceCount = written_output_index; // write out how many were written
return VK_INCOMPLETE;
}
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "pPhysicalDevices array index %d is set to \"%s\" ",
written_output_index, pd_props[j].deviceName);
pPhysicalDevices[written_output_index++] = (VkPhysicalDevice)inst->phys_devs_term[j];
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0, "Insert VkPhysicalDevice \"%s\" to the pPhysicalDevices list",
pd_props[j].deviceName);
pd_was_added[j] = true;
break;
}
}
Expand All @@ -7191,20 +7201,37 @@ VkResult loader_apply_settings_device_configurations(struct loader_instance *ins
inst, VULKAN_LOADER_WARN_BIT, 0,
"loader_apply_settings_device_configurations: settings file contained device_configuration which does not "
"appear in the enumerated VkPhysicalDevices. Missing VkPhysicalDevice with deviceName: \"%s\" and deviceUUID: "
"%x%x%x%x-%x%x-%x%x-%x%x-%x%x%x%x%x%x",
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
inst->settings.device_configurations[i].deviceName, 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], id[15]);
} else {
loader_log(
inst, VULKAN_LOADER_WARN_BIT, 0,
"loader_apply_settings_device_configurations: settings file contained device_configuration which does not "
"appear in the enumerated VkPhysicalDevices. Missing VkPhysicalDevice with deviceUUID: "
"%x%x%x%x-%x%x-%x%x-%x%x-%x%x%x%x%x%x",
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
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],
id[15]);
}
}
}

for (uint32_t j = 0; j < inst->phys_dev_count_term; j++) {
if (!pd_was_added[j]) {
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
"VkPhysicalDevice \"%s\" did not appear in the settings file device configurations list, so was not added "
"to the pPhysicalDevices array",
pd_props[j].deviceName);
}
}

if (written_output_index == 0) {
loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
"loader_apply_settings_device_configurations: None of the settings file device configurations had "
"deviceUUID's that corresponded to enumerated VkPhysicalDevices. Returning VK_ERROR_INITIALIZATION_FAILED");
return VK_ERROR_INITIALIZATION_FAILED;
}

*pPhysicalDeviceCount = written_output_index; // update with how many were written
return VK_SUCCESS;
}
Expand Down
18 changes: 15 additions & 3 deletions loader/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,11 @@ VkResult parse_device_configuration(const struct loader_instance* inst, cJSON* d
res = VK_ERROR_INITIALIZATION_FAILED;
goto out;
}

if (deviceUUID_array->type != cJSON_Array) {
res = VK_ERROR_INITIALIZATION_FAILED;
goto out;
}
if (VK_UUID_SIZE != loader_cJSON_GetArraySize(deviceUUID_array)) {
res = VK_ERROR_INITIALIZATION_FAILED;
goto out;
Expand Down Expand Up @@ -368,10 +373,13 @@ VkResult parse_device_configurations(const struct loader_instance* inst, cJSON*
res = VK_ERROR_INITIALIZATION_FAILED;
goto out;
}
res = parse_device_configuration(inst, device, &(loader_settings->device_configurations[i++]));
if (VK_SUCCESS != res) {
res = parse_device_configuration(inst, device, &(loader_settings->device_configurations[i]));
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) {
goto out;
} else if (res != VK_SUCCESS) {
continue;
}
i++;
}
out:
if (res != VK_SUCCESS) {
Expand Down Expand Up @@ -606,8 +614,12 @@ void log_settings(const struct loader_instance* inst, loader_settings* settings)
for (uint32_t i = 0; i < settings->device_configuration_count; i++) {
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "---- Device Configuration [%d] ----", i);
uint8_t* id = settings->device_configurations[i].deviceUUID;
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "deviceUUID: %x%x%x%x-%x%x-%x%x-%x%x-%x%x%x%x%x%x", id[0], id[1], id[2],
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0,
"deviceUUID: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", 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], id[15]);
if ('\0' != settings->device_configurations[i].deviceName[0]) {
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "deviceName: %s", settings->device_configurations[i].deviceName);
}
}
}
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "---------------------------------");
Expand Down
167 changes: 166 additions & 1 deletion tests/loader_settings_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3302,7 +3302,7 @@ TEST(SettingsFile, MissingDriverConfiguration) {

InstWrapper inst{env.vulkan_functions};
inst.CheckCreate();
auto pd = inst.GetPhysDev();
inst.GetPhysDev(VK_ERROR_INITIALIZATION_FAILED);
}

// Three drivers, second on has the matching UUID in the settings file.
Expand Down Expand Up @@ -3398,3 +3398,168 @@ TEST(SettingsFile, DriverConfigurationsAndAdditionalDrivers) {

ASSERT_TRUE(0 == memcmp(vulkan_11_props.deviceUUID, uuids[1].data(), VK_UUID_SIZE * sizeof(uint8_t)));
}

TEST(SettingsFile, InvalidDriverConfigurations) {
FrameworkEnvironment env{};
std::vector<VulkanUUID> uuids{3, VulkanUUID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};

// Mix up the uuid's so that they are all unique
int count = 1;
for (auto& uuid : uuids) {
std::rotate(uuid.begin(), uuid.begin() + count, uuid.end());
count++;
}
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
.set_icd_api_version(VK_API_VERSION_1_1)
.add_physical_device(PhysicalDevice{}
.set_api_version(VK_API_VERSION_1_1)
.set_deviceName("regular_driver")
.set_deviceUUID(uuids[0])
.finish());

env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2).set_discovery_type(ManifestDiscoveryType::override_folder))
.add_physical_device(PhysicalDevice{}
.set_api_version(VK_API_VERSION_1_1)
.set_deviceName("additional_device")
.set_deviceUUID(uuids[2])
.finish());

env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
AppSpecificSettings{}
.set_additional_drivers_use_exclusively(true)
.add_driver_configuration(LoaderSettingsDriverConfiguration{}.set_path(env.get_icd_manifest_path(1)))
.add_device_configuration(LoaderSettingsDeviceConfiguration{}.set_deviceUUID(uuids[1])));
env.update_loader_settings(env.loader_settings);

InstWrapper inst{env.vulkan_functions};
inst.CheckCreate();
auto pd = inst.GetPhysDev(VK_ERROR_INITIALIZATION_FAILED);
}

TEST(SettingsFile, DeviceConfigurationReordersAdditionalDrivers) {
FrameworkEnvironment env{};
std::vector<VulkanUUID> uuids{3, VulkanUUID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};

// Mix up the uuid's so that they are all unique
int count = 1;
for (auto& uuid : uuids) {
std::rotate(uuid.begin(), uuid.begin() + count, uuid.end());
count++;
}

env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
.set_icd_api_version(VK_API_VERSION_1_1)
.add_physical_device(PhysicalDevice{}
.set_api_version(VK_API_VERSION_1_1)
.set_deviceName("regular_driverA")
.set_deviceUUID(uuids[0])
.finish());
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
.set_icd_api_version(VK_API_VERSION_1_1)
.add_physical_device(PhysicalDevice{}
.set_api_version(VK_API_VERSION_1_1)
.set_deviceName("regular_driverB")
.set_deviceUUID(uuids[1])
.finish());

env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2).set_discovery_type(ManifestDiscoveryType::override_folder))
.set_icd_api_version(VK_API_VERSION_1_1)
.add_physical_device(PhysicalDevice{}
.set_api_version(VK_API_VERSION_1_1)
.set_deviceName("additional_device")
.set_deviceUUID(uuids[2])
.finish());

env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
AppSpecificSettings{}
.add_driver_configuration(LoaderSettingsDriverConfiguration{}.set_path(env.get_icd_manifest_path(2)))
.add_device_configuration(LoaderSettingsDeviceConfiguration{}.set_deviceUUID(uuids[2]))
.add_device_configuration(LoaderSettingsDeviceConfiguration{}.set_deviceUUID(uuids[0]))
.add_device_configuration(LoaderSettingsDeviceConfiguration{}.set_deviceUUID(uuids[1])));
env.update_loader_settings(env.loader_settings);
{
InstWrapper inst{env.vulkan_functions};
inst.CheckCreate();
auto pd = inst.GetPhysDevs(3).at(0);
VkPhysicalDeviceProperties props{};
env.vulkan_functions.vkGetPhysicalDeviceProperties(pd, &props);
ASSERT_TRUE(string_eq(props.deviceName, "additional_device"));
}
{ // do the same check but with 1.1 so we can check that the UUID matches
InstWrapper inst{env.vulkan_functions};
inst.create_info.set_api_version(VK_API_VERSION_1_1);
inst.CheckCreate();
auto pd = inst.GetPhysDevs(3).at(0);
VkPhysicalDeviceProperties props{};
env.vulkan_functions.vkGetPhysicalDeviceProperties(pd, &props);
ASSERT_TRUE(string_eq(props.deviceName, "additional_device"));

VkPhysicalDeviceVulkan11Properties vulkan_11_props{};
vulkan_11_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
VkPhysicalDeviceProperties2 props2{};
props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
props2.pNext = &vulkan_11_props;
inst->vkGetPhysicalDeviceProperties2(pd, &props2);

ASSERT_TRUE(0 == memcmp(vulkan_11_props.deviceUUID, uuids[2].data(), VK_UUID_SIZE * sizeof(uint8_t)));
}
}

TEST(SettingsFile, DeviceConfigurationReordersExclusiveAdditionalDrivers) {
FrameworkEnvironment env{};
std::vector<VulkanUUID> uuids{3, VulkanUUID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};

// Mix up the uuid's so that they are all unique
int count = 1;
for (auto& uuid : uuids) {
std::rotate(uuid.begin(), uuid.begin() + count, uuid.end());
count++;
}

env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
.set_icd_api_version(VK_API_VERSION_1_1)
.add_physical_device(PhysicalDevice{}
.set_api_version(VK_API_VERSION_1_1)
.set_deviceName("regular_driverA")
.set_deviceUUID(uuids[0])
.finish());
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2))
.set_icd_api_version(VK_API_VERSION_1_1)
.add_physical_device(PhysicalDevice{}
.set_api_version(VK_API_VERSION_1_1)
.set_deviceName("regular_driverB")
.set_deviceUUID(uuids[1])
.finish());

env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2).set_discovery_type(ManifestDiscoveryType::override_folder))
.set_icd_api_version(VK_API_VERSION_1_1)
.add_physical_device(PhysicalDevice{}
.set_api_version(VK_API_VERSION_1_1)
.set_deviceName("additional_device")
.set_deviceUUID(uuids[2])
.finish());

env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(
AppSpecificSettings{}
.set_additional_drivers_use_exclusively(true)
.add_driver_configuration(LoaderSettingsDriverConfiguration{}.set_path(env.get_icd_manifest_path(2)))
.add_device_configuration(LoaderSettingsDeviceConfiguration{}.set_deviceUUID(uuids[2])));
env.update_loader_settings(env.loader_settings);

InstWrapper inst{env.vulkan_functions};
inst.create_info.set_api_version(VK_API_VERSION_1_1);
inst.CheckCreate();
auto pd = inst.GetPhysDev();
VkPhysicalDeviceProperties props{};
env.vulkan_functions.vkGetPhysicalDeviceProperties(pd, &props);
ASSERT_TRUE(string_eq(props.deviceName, "additional_device"));

VkPhysicalDeviceVulkan11Properties vulkan_11_props{};
vulkan_11_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
VkPhysicalDeviceProperties2 props2{};
props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
props2.pNext = &vulkan_11_props;
inst->vkGetPhysicalDeviceProperties2(pd, &props2);

ASSERT_TRUE(0 == memcmp(vulkan_11_props.deviceUUID, uuids[2].data(), VK_UUID_SIZE * sizeof(uint8_t)));
}
Loading