diff --git a/loader/loader.c b/loader/loader.c index 821872174..3e5c2d523 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -7142,6 +7142,46 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDevices(VkInstance in return res; } +VkResult check_physical_device_extensions_for_driver_properties_extension(struct loader_physical_device_term *phys_dev_term, + bool *supports_driver_properties) { + *supports_driver_properties = false; + uint32_t extension_count = 0; + VkResult res = phys_dev_term->this_icd_term->dispatch.EnumerateDeviceExtensionProperties(phys_dev_term->phys_dev, NULL, + &extension_count, NULL); + if (res != VK_SUCCESS || extension_count == 0) { + return VK_SUCCESS; + } + VkExtensionProperties *extension_data = loader_stack_alloc(sizeof(VkExtensionProperties) * extension_count); + if (NULL == extension_data) { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + res = phys_dev_term->this_icd_term->dispatch.EnumerateDeviceExtensionProperties(phys_dev_term->phys_dev, NULL, &extension_count, + extension_data); + if (res != VK_SUCCESS) { + return VK_SUCCESS; + } + for (uint32_t j = 0; j < extension_count; j++) { + if (!strcmp(extension_data[j].extensionName, VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)) { + *supports_driver_properties = true; + return VK_SUCCESS; + } + } + return VK_SUCCESS; +} + +// Helper struct containing the relevant details of a VkPhysicalDevice necessary for applying the loader settings device +// configurations. +typedef struct physical_device_configuration_details { + bool pd_was_added; + bool pd_supports_vulkan_11; + bool pd_supports_driver_properties; + VkPhysicalDeviceProperties properties; + VkPhysicalDeviceIDProperties device_id_properties; + VkPhysicalDeviceDriverProperties driver_properties; + +} physical_device_configuration_details; + // Apply the device_configurations in the settings file to the output VkPhysicalDeviceList. // That means looking up each VkPhysicalDevice's deviceUUID, filtering using that, and putting them in the order of // device_configurations in the settings file. @@ -7150,45 +7190,46 @@ VkResult loader_apply_settings_device_configurations(struct loader_instance *ins 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) { + physical_device_configuration_details *pd_details = + loader_stack_alloc(inst->phys_dev_count_term * sizeof(physical_device_configuration_details)); + if (NULL == pd_details) { return VK_ERROR_OUT_OF_HOST_MEMORY; } - memset(pd_was_added, 0, inst->phys_dev_count_term * sizeof(bool)); + memset(pd_details, 0, inst->phys_dev_count_term * sizeof(physical_device_configuration_details)); - 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; - } - memset(pd_supports_11, 0, inst->phys_dev_count_term * sizeof(bool)); + for (uint32_t i = 0; i < inst->phys_dev_count_term; i++) { + struct loader_physical_device_term *phys_dev_term = inst->phys_devs_term[i]; - VkPhysicalDeviceProperties *pd_props = loader_stack_alloc(inst->phys_dev_count_term * sizeof(VkPhysicalDeviceProperties)); - if (NULL == pd_props) { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - memset(pd_props, 0, inst->phys_dev_count_term * sizeof(VkPhysicalDeviceProperties)); + phys_dev_term->this_icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, &pd_details[i].properties); + if (pd_details[i].properties.apiVersion < VK_API_VERSION_1_1) { + // Device isn't eligible for sorting + continue; + } + pd_details[i].pd_supports_vulkan_11 = true; + if (pd_details[i].properties.apiVersion >= VK_API_VERSION_1_2) { + pd_details[i].pd_supports_driver_properties = true; + } - VkPhysicalDeviceVulkan11Properties *pd_vulkan_11_props = - loader_stack_alloc(inst->phys_dev_count_term * sizeof(VkPhysicalDeviceVulkan11Properties)); - if (NULL == pd_vulkan_11_props) { - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - memset(pd_vulkan_11_props, 0, inst->phys_dev_count_term * sizeof(VkPhysicalDeviceVulkan11Properties)); + // If this physical device isn't 1.2, then we need to check if it supports VK_KHR_driver_properties + if (!pd_details[i].pd_supports_driver_properties) { + VkResult res = check_physical_device_extensions_for_driver_properties_extension( + phys_dev_term, &pd_details[i].pd_supports_driver_properties); + if (res == VK_ERROR_OUT_OF_HOST_MEMORY) { + return res; + } + } - for (uint32_t i = 0; i < inst->phys_dev_count_term; i++) { - pd_vulkan_11_props[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES; + pd_details[i].device_id_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES; + pd_details[i].driver_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES; + if (pd_details[i].pd_supports_driver_properties) { + pd_details[i].device_id_properties.pNext = (void *)&pd_details[i].driver_properties; + } - inst->phys_devs_term[i]->this_icd_term->dispatch.GetPhysicalDeviceProperties(inst->phys_devs_term[i]->phys_dev, - &pd_props[i]); - if (pd_props[i].apiVersion >= VK_API_VERSION_1_1) { - pd_supports_11[i] = true; - VkPhysicalDeviceProperties2 props2 = {0}; - props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; - props2.pNext = (void *)&pd_vulkan_11_props[i]; - if (inst->phys_devs_term[i]->this_icd_term->dispatch.GetPhysicalDeviceProperties2) { - inst->phys_devs_term[i]->this_icd_term->dispatch.GetPhysicalDeviceProperties2(inst->phys_devs_term[i]->phys_dev, - &props2); - } + VkPhysicalDeviceProperties2 props2 = {0}; + props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; + props2.pNext = (void *)&pd_details[i].device_id_properties; + if (phys_dev_term->this_icd_term->dispatch.GetPhysicalDeviceProperties2) { + phys_dev_term->this_icd_term->dispatch.GetPhysicalDeviceProperties2(phys_dev_term->phys_dev, &props2); } } @@ -7198,55 +7239,79 @@ VkResult loader_apply_settings_device_configurations(struct loader_instance *ins for (uint32_t i = 0; i < inst->settings.device_configuration_count; i++) { uint8_t *current_deviceUUID = inst->settings.device_configurations[i].deviceUUID; + uint8_t *current_driverUUID = inst->settings.device_configurations[i].driverUUID; bool configuration_found = false; for (uint32_t j = 0; j < inst->phys_dev_count_term; j++) { // Don't compare deviceUUID's if they have nothing, since we require deviceUUID's to effectively sort them. - if (!pd_supports_11[j]) { + if (!pd_details[j].pd_supports_vulkan_11) { continue; } - if (memcmp(current_deviceUUID, pd_vulkan_11_props[j].deviceUUID, sizeof(uint8_t) * VK_UUID_SIZE) == 0) { + if (memcmp(current_deviceUUID, pd_details[j].device_id_properties.deviceUUID, sizeof(uint8_t) * VK_UUID_SIZE) == 0 && + memcmp(current_driverUUID, pd_details[j].device_id_properties.driverUUID, sizeof(uint8_t) * VK_UUID_SIZE) == 0 && + inst->settings.device_configurations[i].driverVersion == pd_details[j].properties.driverVersion) { configuration_found = true; // Catch when there are more device_configurations than space available in the output if (written_output_index >= *pPhysicalDeviceCount) { *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); + if (pd_details[j].pd_supports_driver_properties) { + loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, + "pPhysicalDevices array index %d is set to \"%s\" (%s, version %d) ", written_output_index, + pd_details[j].properties.deviceName, pd_details[i].driver_properties.driverName, + pd_details[i].properties.driverVersion); + } else { + loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, + "pPhysicalDevices array index %d is set to \"%s\" (driver version %d) ", written_output_index, + pd_details[j].properties.deviceName, pd_details[i].properties.driverVersion); + } pPhysicalDevices[written_output_index++] = (VkPhysicalDevice)inst->phys_devs_term[j]; - pd_was_added[j] = true; + pd_details[j].pd_was_added = true; break; } } if (!configuration_found) { - uint8_t *id = current_deviceUUID; + char device_uuid_str[UUID_STR_LEN] = {0}; + loader_log_generate_uuid_string(current_deviceUUID, device_uuid_str); + char driver_uuid_str[UUID_STR_LEN] = {0}; + loader_log_generate_uuid_string(current_deviceUUID, driver_uuid_str); + // Log that this configuration was missing. - if (inst->settings.device_configurations[i].deviceName[0] != '\0') { + if (inst->settings.device_configurations[i].deviceName[0] != '\0' && + inst->settings.device_configurations[i].driverName[0] != '\0') { + 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 deviceName: \"%s\", " + "deviceUUID: %s, driverName: %s, driverUUID: %s, driverVersion: %d", + inst->settings.device_configurations[i].deviceName, device_uuid_str, + inst->settings.device_configurations[i].driverName, driver_uuid_str, + inst->settings.device_configurations[i].driverVersion); + } else if (inst->settings.device_configurations[i].deviceName[0] != '\0') { 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 deviceName: \"%s\" and deviceUUID: " - "%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]); + "appear in the enumerated VkPhysicalDevices. Missing VkPhysicalDevice with deviceName: \"%s\", " + "deviceUUID: %s, driverUUID: %s, driverVersion: %d", + inst->settings.device_configurations[i].deviceName, device_uuid_str, driver_uuid_str, + inst->settings.device_configurations[i].driverVersion); } 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: " - "%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]); + "%s, driverUUID: %s, driverVersion: %d", + device_uuid_str, driver_uuid_str, inst->settings.device_configurations[i].driverVersion); } } } for (uint32_t j = 0; j < inst->phys_dev_count_term; j++) { - if (!pd_was_added[j]) { + if (!pd_details[j].pd_was_added) { 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); + pd_details[j].properties.deviceName); } } diff --git a/loader/log.c b/loader/log.c index 41b89ee65..78589a47c 100644 --- a/loader/log.c +++ b/loader/log.c @@ -274,3 +274,10 @@ void loader_log_asm_function_not_supported(const struct loader_instance *inst, V const char *func_name) { loader_log(inst, msg_type, msg_code, "Function %s not supported for this physical device", func_name); } + +void loader_log_generate_uuid_string(const uint8_t uuid[16], char output[UUID_STR_LEN]) { + assert(uuid && output); + snprintf(output, UUID_STR_LEN, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", uuid[0], uuid[1], + uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7], uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], + uuid[14], uuid[15]); +} diff --git a/loader/log.h b/loader/log.h index 1b594ab77..6075e1a0a 100644 --- a/loader/log.h +++ b/loader/log.h @@ -83,3 +83,7 @@ void loader_log_asm_function_not_supported(const struct loader_instance *inst, V const char *func_name) ASM_NAME("loader_log_asm_function_not_supported"); #undef ASM_NAME + +#define UUID_STR_LEN 37 // always 32 digits, 4 dashes, and 1 null terminator + +void loader_log_generate_uuid_string(const uint8_t uuid[16], char output[UUID_STR_LEN]); diff --git a/loader/settings.c b/loader/settings.c index 365cfb9d0..8ca81728b 100644 --- a/loader/settings.c +++ b/loader/settings.c @@ -297,39 +297,58 @@ VkResult parse_additional_drivers(const struct loader_instance* inst, cJSON* set return res; } -VkResult parse_device_configuration(const struct loader_instance* inst, cJSON* device_configuration_json, - loader_settings_device_configuration* device_configuration) { - (void)inst; - VkResult res = VK_SUCCESS; - cJSON* deviceUUID_array = loader_cJSON_GetObjectItem(device_configuration_json, "deviceUUID"); - if (NULL == deviceUUID_array) { - res = VK_ERROR_INITIALIZATION_FAILED; - goto out; +VkResult parse_uuid_array(cJSON* device_configuration_json, const char* uuid_name, uint8_t uuid[16]) { + cJSON* uuid_array = loader_cJSON_GetObjectItem(device_configuration_json, uuid_name); + if (NULL == uuid_array) { + return VK_ERROR_INITIALIZATION_FAILED; } - if (deviceUUID_array->type != cJSON_Array) { - res = VK_ERROR_INITIALIZATION_FAILED; - goto out; + if (uuid_array->type != cJSON_Array) { + return VK_ERROR_INITIALIZATION_FAILED; } - if (VK_UUID_SIZE != loader_cJSON_GetArraySize(deviceUUID_array)) { - res = VK_ERROR_INITIALIZATION_FAILED; - goto out; + if (VK_UUID_SIZE != loader_cJSON_GetArraySize(uuid_array)) { + return VK_ERROR_INITIALIZATION_FAILED; } cJSON* uuid_field = NULL; size_t i = 0; - cJSON_ArrayForEach(uuid_field, deviceUUID_array) { + cJSON_ArrayForEach(uuid_field, uuid_array) { + if (i >= VK_UUID_SIZE) { + break; + } if (uuid_field->type != cJSON_Number) { - res = VK_ERROR_INITIALIZATION_FAILED; - goto out; + return VK_ERROR_INITIALIZATION_FAILED; } if (uuid_field->valueint < 0 || uuid_field->valueint > 255) { - res = VK_ERROR_INITIALIZATION_FAILED; - goto out; + return VK_ERROR_INITIALIZATION_FAILED; } - device_configuration->deviceUUID[i] = (uint8_t)uuid_field->valueint; + + uuid[i] = (uint8_t)uuid_field->valueint; i++; } + return VK_SUCCESS; +} + +VkResult parse_device_configuration(const struct loader_instance* inst, cJSON* device_configuration_json, + loader_settings_device_configuration* device_configuration) { + (void)inst; + VkResult res = VK_SUCCESS; + + res = parse_uuid_array(device_configuration_json, "deviceUUID", device_configuration->deviceUUID); + if (VK_SUCCESS != res) { + goto out; + } + + res = parse_uuid_array(device_configuration_json, "driverUUID", device_configuration->driverUUID); + if (VK_SUCCESS != res) { + goto out; + } + + cJSON* driverVersion_json = loader_cJSON_GetObjectItem(device_configuration_json, "driverVersion"); + if (NULL == driverVersion_json || driverVersion_json->type != cJSON_Number) { + return VK_ERROR_INITIALIZATION_FAILED; + } + device_configuration->driverVersion = driverVersion_json->valueint; VkResult deviceNameRes = loader_parse_json_string_to_existing_str( device_configuration_json, "deviceName", VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, device_configuration->deviceName); @@ -337,6 +356,13 @@ VkResult parse_device_configuration(const struct loader_instance* inst, cJSON* d res = deviceNameRes; goto out; } + + VkResult driverNameRes = loader_parse_json_string_to_existing_str( + device_configuration_json, "driverName", VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, device_configuration->driverName); + if (VK_ERROR_OUT_OF_HOST_MEMORY == driverNameRes) { + res = driverNameRes; + goto out; + } out: if (res != VK_SUCCESS) { memset(device_configuration, 0, sizeof(loader_settings_device_configuration)); @@ -542,6 +568,10 @@ bool check_if_device_configurations_are_equal(loader_settings_device_configurati for (uint32_t i = 0; i < VK_UUID_SIZE; i++) { if (a->deviceUUID[i] != b->deviceUUID[i]) return false; } + for (uint32_t i = 0; i < VK_UUID_SIZE; i++) { + if (a->driverUUID[i] != b->driverUUID[i]) return false; + } + if (a->driverVersion != b->driverVersion) return false; return true; } @@ -613,13 +643,19 @@ void log_settings(const struct loader_instance* inst, loader_settings* settings) loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Device Configurations count = %d", settings->device_configuration_count); 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: %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]); + char device_uuid_str[UUID_STR_LEN] = {0}; + loader_log_generate_uuid_string(settings->device_configurations[i].deviceUUID, device_uuid_str); + char driver_uuid_str[UUID_STR_LEN] = {0}; + loader_log_generate_uuid_string(settings->device_configurations[i].driverUUID, driver_uuid_str); + loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "deviceUUID: %s", device_uuid_str); + loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "driverUUID: %s", driver_uuid_str); + loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "driverVersion: %d", settings->device_configurations[i].driverVersion); if ('\0' != settings->device_configurations[i].deviceName[0]) { loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "deviceName: %s", settings->device_configurations[i].deviceName); } + if ('\0' != settings->device_configurations[i].driverName[0]) { + loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "driverName: %s", settings->device_configurations[i].driverName); + } } } loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "---------------------------------"); diff --git a/loader/settings.h b/loader/settings.h index 9ed5c80bf..df3448619 100644 --- a/loader/settings.h +++ b/loader/settings.h @@ -67,8 +67,11 @@ typedef struct loader_settings_driver_configuration { } loader_settings_driver_configuration; typedef struct loader_settings_device_configuration { - char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE]; uint8_t deviceUUID[VK_UUID_SIZE]; + uint8_t driverUUID[VK_UUID_SIZE]; + uint32_t driverVersion; + char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE]; + char driverName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE]; } loader_settings_device_configuration; typedef struct loader_settings { diff --git a/tests/framework/icd/test_icd.cpp b/tests/framework/icd/test_icd.cpp index 1cc964c35..56e8b0b2c 100644 --- a/tests/framework/icd/test_icd.cpp +++ b/tests/framework/icd/test_icd.cpp @@ -1231,6 +1231,12 @@ VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceProperties2(VkPhysicalDevice if (pNext->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES) { auto* vulkan_11_props = reinterpret_cast(pNext); memcpy(vulkan_11_props->deviceUUID, phys_dev.deviceUUID.data(), VK_UUID_SIZE); + memcpy(vulkan_11_props->driverUUID, phys_dev.driverUUID.data(), VK_UUID_SIZE); + } + if (pNext->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES) { + auto* device_id_props = reinterpret_cast(pNext); + memcpy(device_id_props->deviceUUID, phys_dev.deviceUUID.data(), VK_UUID_SIZE); + memcpy(device_id_props->driverUUID, phys_dev.driverUUID.data(), VK_UUID_SIZE); } if (pNext->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES) { auto* device_driver_props = reinterpret_cast(pNext); diff --git a/tests/framework/icd/test_icd.h b/tests/framework/icd/test_icd.h index 24309f410..4e4fcec0b 100644 --- a/tests/framework/icd/test_icd.h +++ b/tests/framework/icd/test_icd.h @@ -91,6 +91,7 @@ struct PhysicalDevice { DispatchableHandle vk_physical_device; BUILDER_VALUE(std::string, deviceName) BUILDER_VALUE(VulkanUUID, deviceUUID) + BUILDER_VALUE(VulkanUUID, driverUUID) BUILDER_VALUE(VkPhysicalDeviceProperties, properties) BUILDER_VALUE(VkPhysicalDeviceFeatures, features) BUILDER_VALUE(VkPhysicalDeviceMemoryProperties, memory_properties) diff --git a/tests/framework/test_environment.cpp b/tests/framework/test_environment.cpp index 261d21149..cf983d234 100644 --- a/tests/framework/test_environment.cpp +++ b/tests/framework/test_environment.cpp @@ -699,11 +699,21 @@ std::string get_loader_settings_file_contents(const LoaderSettings& loader_setti if (!device.deviceName.empty()) { writer.AddKeyedString("deviceName", device.deviceName); } + if (!device.driverName.empty()) { + writer.AddKeyedString("driverName", device.driverName); + } writer.StartKeyedArray("deviceUUID"); for (const auto& u : device.deviceUUID) { writer.AddInteger(u); } writer.EndArray(); + + writer.StartKeyedArray("driverUUID"); + for (const auto& u : device.driverUUID) { + writer.AddInteger(u); + } + writer.EndArray(); + writer.AddKeyedInteger("driverVersion", device.driverVersion); writer.EndObject(); } writer.EndArray(); diff --git a/tests/framework/test_environment.h b/tests/framework/test_environment.h index 678e88e99..59444b37e 100644 --- a/tests/framework/test_environment.h +++ b/tests/framework/test_environment.h @@ -365,7 +365,10 @@ using VulkanUUID = std::array; struct LoaderSettingsDeviceConfiguration { BUILDER_VALUE(VulkanUUID, deviceUUID) + BUILDER_VALUE(VulkanUUID, driverUUID) + BUILDER_VALUE(uint32_t, driverVersion) BUILDER_VALUE(std::string, deviceName) + BUILDER_VALUE(std::string, driverName) }; // Log files and their associated filter diff --git a/tests/loader_settings_tests.cpp b/tests/loader_settings_tests.cpp index a276bcce5..225af0e31 100644 --- a/tests/loader_settings_tests.cpp +++ b/tests/loader_settings_tests.cpp @@ -3354,6 +3354,57 @@ TEST(SettingsFile, MissingDriverConfiguration) { inst.GetPhysDev(VK_ERROR_INITIALIZATION_FAILED); } +TEST(SettingsFile, DeviceConfigurationWithSameDriver) { + FrameworkEnvironment env{}; + VulkanUUID device_uuid = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + VulkanUUID driver_uuid = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}; + + auto& icd0 = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).set_icd_api_version(VK_API_VERSION_1_1); + auto& phys_dev_0 = icd0.add_and_get_physical_device(PhysicalDevice() + .set_api_version(VK_API_VERSION_1_2) + .set_deviceUUID(device_uuid) + .set_driverUUID(driver_uuid) + .set_deviceName("foobar") + .finish()); + phys_dev_0.properties.driverVersion = 1000; + std::string("Fake Driver XYZ").copy(phys_dev_0.driver_properties.driverName, VK_MAX_EXTENSION_NAME_SIZE); + + auto& icd1 = env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2)).set_icd_api_version(VK_API_VERSION_1_1); + auto& phys_dev_1 = icd1.add_and_get_physical_device(PhysicalDevice() + .set_api_version(VK_API_VERSION_1_2) + .set_deviceUUID(device_uuid) + .set_driverUUID(driver_uuid) + .set_deviceName("foobar") + .finish()); + phys_dev_1.properties.driverVersion = 30; + std::string("Fake Driver XYZ, but differently named").copy(phys_dev_1.driver_properties.driverName, VK_MAX_EXTENSION_NAME_SIZE); + + env.loader_settings.set_file_format_version({1, 0, 0}).add_app_specific_setting(AppSpecificSettings{}); + + env.loader_settings.app_specific_settings.at(0).device_configurations.clear(); + env.loader_settings.app_specific_settings.at(0).add_device_configuration( + LoaderSettingsDeviceConfiguration{} + .set_deviceUUID(device_uuid) + .set_driverUUID(driver_uuid) + .set_driverVersion(phys_dev_1.properties.driverVersion)); + env.loader_settings.app_specific_settings.at(0).add_device_configuration( + LoaderSettingsDeviceConfiguration{} + .set_deviceUUID(device_uuid) + .set_driverUUID(driver_uuid) + .set_driverVersion(phys_dev_0.properties.driverVersion)); + env.update_loader_settings(env.loader_settings); + + InstWrapper inst{env.vulkan_functions}; + inst.CheckCreate(); + auto phys_devs = inst.GetPhysDevs(2); + VkPhysicalDeviceProperties props1{}; + VkPhysicalDeviceProperties props2{}; + inst->vkGetPhysicalDeviceProperties(phys_devs.at(0), &props1); + inst->vkGetPhysicalDeviceProperties(phys_devs.at(1), &props2); + ASSERT_EQ(props1.driverVersion, phys_dev_1.properties.driverVersion); + ASSERT_EQ(props2.driverVersion, phys_dev_0.properties.driverVersion); +} + // Three drivers, second on has the matching UUID in the settings file. TEST(SettingsFile, DriverConfigurationIgnoresDriverEnvVars) { FrameworkEnvironment env{};