Skip to content

Commit 74047e4

Browse files
Add driverUUID and driverVersion to settings file device configuration parameters
deviceUUID is not sufficient to be able to distinguish VkPhysicalDevices as there can be multiple ICD's that report the same VkPhysicalDevice. This can easily occur when a development build of a driver is present alongside a stable build on a system. driverUUID then helps differentiate ICD's reporting the same VkPhysicalDevice, but isn't sufficient as some drivers use the same driverUUID across all builds (RADV from Mesa as example). Thus, driverVersion is used for that purpose.
1 parent b4e1325 commit 74047e4

File tree

8 files changed

+248
-73
lines changed

8 files changed

+248
-73
lines changed

loader/loader.c

Lines changed: 113 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7142,6 +7142,46 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDevices(VkInstance in
71427142
return res;
71437143
}
71447144

7145+
VkResult check_physical_device_extensions_for_driver_properties_extension(struct loader_physical_device_term *phys_dev_term,
7146+
bool *supports_driver_properties) {
7147+
*supports_driver_properties = false;
7148+
uint32_t extension_count = 0;
7149+
VkResult res = phys_dev_term->this_icd_term->dispatch.EnumerateDeviceExtensionProperties(phys_dev_term->phys_dev, NULL,
7150+
&extension_count, NULL);
7151+
if (res != VK_SUCCESS || extension_count == 0) {
7152+
return VK_SUCCESS;
7153+
}
7154+
VkExtensionProperties *extension_data = loader_stack_alloc(sizeof(VkExtensionProperties) * extension_count);
7155+
if (NULL == extension_data) {
7156+
return VK_ERROR_OUT_OF_HOST_MEMORY;
7157+
}
7158+
7159+
res = phys_dev_term->this_icd_term->dispatch.EnumerateDeviceExtensionProperties(phys_dev_term->phys_dev, NULL, &extension_count,
7160+
extension_data);
7161+
if (res != VK_SUCCESS) {
7162+
return VK_SUCCESS;
7163+
}
7164+
for (uint32_t j = 0; j < extension_count; j++) {
7165+
if (!strcmp(extension_data[j].extensionName, VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME)) {
7166+
*supports_driver_properties = true;
7167+
return VK_SUCCESS;
7168+
}
7169+
}
7170+
return VK_SUCCESS;
7171+
}
7172+
7173+
// Helper struct containing the relevant details of a VkPhysicalDevice necessary for applying the loader settings device
7174+
// configurations.
7175+
typedef struct physical_device_configuration_details {
7176+
bool pd_was_added;
7177+
bool pd_supports_vulkan_11;
7178+
bool pd_supports_driver_properties;
7179+
VkPhysicalDeviceProperties properties;
7180+
VkPhysicalDeviceIDProperties device_id_properties;
7181+
VkPhysicalDeviceDriverProperties driver_properties;
7182+
7183+
} physical_device_configuration_details;
7184+
71457185
// Apply the device_configurations in the settings file to the output VkPhysicalDeviceList.
71467186
// That means looking up each VkPhysicalDevice's deviceUUID, filtering using that, and putting them in the order of
71477187
// device_configurations in the settings file.
@@ -7150,45 +7190,46 @@ VkResult loader_apply_settings_device_configurations(struct loader_instance *ins
71507190
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
71517191
"Reordering the output of vkEnumeratePhysicalDevices to match the loader settings device configurations list");
71527192

7153-
bool *pd_was_added = loader_stack_alloc(inst->phys_dev_count_term * sizeof(bool));
7154-
if (NULL == pd_was_added) {
7193+
physical_device_configuration_details *pd_details =
7194+
loader_stack_alloc(inst->phys_dev_count_term * sizeof(physical_device_configuration_details));
7195+
if (NULL == pd_details) {
71557196
return VK_ERROR_OUT_OF_HOST_MEMORY;
71567197
}
7157-
memset(pd_was_added, 0, inst->phys_dev_count_term * sizeof(bool));
7198+
memset(pd_details, 0, inst->phys_dev_count_term * sizeof(physical_device_configuration_details));
71587199

7159-
bool *pd_supports_11 = loader_stack_alloc(inst->phys_dev_count_term * sizeof(bool));
7160-
if (NULL == pd_supports_11) {
7161-
return VK_ERROR_OUT_OF_HOST_MEMORY;
7162-
}
7163-
memset(pd_supports_11, 0, inst->phys_dev_count_term * sizeof(bool));
7200+
for (uint32_t i = 0; i < inst->phys_dev_count_term; i++) {
7201+
struct loader_physical_device_term *phys_dev_term = inst->phys_devs_term[i];
71647202

7165-
VkPhysicalDeviceProperties *pd_props = loader_stack_alloc(inst->phys_dev_count_term * sizeof(VkPhysicalDeviceProperties));
7166-
if (NULL == pd_props) {
7167-
return VK_ERROR_OUT_OF_HOST_MEMORY;
7168-
}
7169-
memset(pd_props, 0, inst->phys_dev_count_term * sizeof(VkPhysicalDeviceProperties));
7203+
phys_dev_term->this_icd_term->dispatch.GetPhysicalDeviceProperties(phys_dev_term->phys_dev, &pd_details[i].properties);
7204+
if (pd_details[i].properties.apiVersion < VK_API_VERSION_1_1) {
7205+
// Device isn't eligible for sorting
7206+
continue;
7207+
}
7208+
pd_details[i].pd_supports_vulkan_11 = true;
7209+
if (pd_details[i].properties.apiVersion >= VK_API_VERSION_1_2) {
7210+
pd_details[i].pd_supports_driver_properties = true;
7211+
}
71707212

7171-
VkPhysicalDeviceVulkan11Properties *pd_vulkan_11_props =
7172-
loader_stack_alloc(inst->phys_dev_count_term * sizeof(VkPhysicalDeviceVulkan11Properties));
7173-
if (NULL == pd_vulkan_11_props) {
7174-
return VK_ERROR_OUT_OF_HOST_MEMORY;
7175-
}
7176-
memset(pd_vulkan_11_props, 0, inst->phys_dev_count_term * sizeof(VkPhysicalDeviceVulkan11Properties));
7213+
// If this physical device isn't 1.2, then we need to check if it supports VK_KHR_driver_properties
7214+
if (!pd_details[i].pd_supports_driver_properties) {
7215+
VkResult res = check_physical_device_extensions_for_driver_properties_extension(
7216+
phys_dev_term, &pd_details[i].pd_supports_driver_properties);
7217+
if (res == VK_ERROR_OUT_OF_HOST_MEMORY) {
7218+
return res;
7219+
}
7220+
}
71777221

7178-
for (uint32_t i = 0; i < inst->phys_dev_count_term; i++) {
7179-
pd_vulkan_11_props[i].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
7222+
pd_details[i].device_id_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
7223+
pd_details[i].driver_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
7224+
if (pd_details[i].pd_supports_driver_properties) {
7225+
pd_details[i].device_id_properties.pNext = (void *)&pd_details[i].driver_properties;
7226+
}
71807227

7181-
inst->phys_devs_term[i]->this_icd_term->dispatch.GetPhysicalDeviceProperties(inst->phys_devs_term[i]->phys_dev,
7182-
&pd_props[i]);
7183-
if (pd_props[i].apiVersion >= VK_API_VERSION_1_1) {
7184-
pd_supports_11[i] = true;
7185-
VkPhysicalDeviceProperties2 props2 = {0};
7186-
props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
7187-
props2.pNext = (void *)&pd_vulkan_11_props[i];
7188-
if (inst->phys_devs_term[i]->this_icd_term->dispatch.GetPhysicalDeviceProperties2) {
7189-
inst->phys_devs_term[i]->this_icd_term->dispatch.GetPhysicalDeviceProperties2(inst->phys_devs_term[i]->phys_dev,
7190-
&props2);
7191-
}
7228+
VkPhysicalDeviceProperties2 props2 = {0};
7229+
props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
7230+
props2.pNext = (void *)&pd_details[i].device_id_properties;
7231+
if (phys_dev_term->this_icd_term->dispatch.GetPhysicalDeviceProperties2) {
7232+
phys_dev_term->this_icd_term->dispatch.GetPhysicalDeviceProperties2(phys_dev_term->phys_dev, &props2);
71927233
}
71937234
}
71947235

@@ -7198,55 +7239,79 @@ VkResult loader_apply_settings_device_configurations(struct loader_instance *ins
71987239

71997240
for (uint32_t i = 0; i < inst->settings.device_configuration_count; i++) {
72007241
uint8_t *current_deviceUUID = inst->settings.device_configurations[i].deviceUUID;
7242+
uint8_t *current_driverUUID = inst->settings.device_configurations[i].driverUUID;
72017243
bool configuration_found = false;
72027244
for (uint32_t j = 0; j < inst->phys_dev_count_term; j++) {
72037245
// Don't compare deviceUUID's if they have nothing, since we require deviceUUID's to effectively sort them.
7204-
if (!pd_supports_11[j]) {
7246+
if (!pd_details[j].pd_supports_vulkan_11) {
72057247
continue;
72067248
}
7207-
if (memcmp(current_deviceUUID, pd_vulkan_11_props[j].deviceUUID, sizeof(uint8_t) * VK_UUID_SIZE) == 0) {
7249+
if (memcmp(current_deviceUUID, pd_details[j].device_id_properties.deviceUUID, sizeof(uint8_t) * VK_UUID_SIZE) == 0 &&
7250+
memcmp(current_driverUUID, pd_details[j].device_id_properties.driverUUID, sizeof(uint8_t) * VK_UUID_SIZE) == 0 &&
7251+
inst->settings.device_configurations[i].driverVersion == pd_details[j].properties.driverVersion) {
72087252
configuration_found = true;
72097253
// Catch when there are more device_configurations than space available in the output
72107254
if (written_output_index >= *pPhysicalDeviceCount) {
72117255
*pPhysicalDeviceCount = written_output_index; // write out how many were written
72127256
return VK_INCOMPLETE;
72137257
}
7214-
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "pPhysicalDevices array index %d is set to \"%s\" ",
7215-
written_output_index, pd_props[j].deviceName);
7258+
if (pd_details[j].pd_supports_driver_properties) {
7259+
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0,
7260+
"pPhysicalDevices array index %d is set to \"%s\" (%s, version %d) ", written_output_index,
7261+
pd_details[j].properties.deviceName, pd_details[i].driver_properties.driverName,
7262+
pd_details[i].properties.driverVersion);
7263+
} else {
7264+
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0,
7265+
"pPhysicalDevices array index %d is set to \"%s\" (driver version %d) ", written_output_index,
7266+
pd_details[j].properties.deviceName, pd_details[i].properties.driverVersion);
7267+
}
72167268
pPhysicalDevices[written_output_index++] = (VkPhysicalDevice)inst->phys_devs_term[j];
7217-
pd_was_added[j] = true;
7269+
pd_details[j].pd_was_added = true;
72187270
break;
72197271
}
72207272
}
72217273
if (!configuration_found) {
7222-
uint8_t *id = current_deviceUUID;
7274+
char device_uuid_str[UUID_STR_LEN] = {0};
7275+
loader_log_generate_uuid_string(current_deviceUUID, device_uuid_str);
7276+
char driver_uuid_str[UUID_STR_LEN] = {0};
7277+
loader_log_generate_uuid_string(current_deviceUUID, driver_uuid_str);
7278+
72237279
// Log that this configuration was missing.
7224-
if (inst->settings.device_configurations[i].deviceName[0] != '\0') {
7280+
if (inst->settings.device_configurations[i].deviceName[0] != '\0' &&
7281+
inst->settings.device_configurations[i].driverName[0] != '\0') {
7282+
loader_log(
7283+
inst, VULKAN_LOADER_WARN_BIT, 0,
7284+
"loader_apply_settings_device_configurations: settings file contained device_configuration which does not "
7285+
"appear in the enumerated VkPhysicalDevices. Missing VkPhysicalDevice with deviceName: \"%s\", "
7286+
"deviceUUID: %s, driverName: %s, driverUUID: %s, driverVersion: %d",
7287+
inst->settings.device_configurations[i].deviceName, device_uuid_str,
7288+
inst->settings.device_configurations[i].driverName, driver_uuid_str,
7289+
inst->settings.device_configurations[i].driverVersion);
7290+
} else if (inst->settings.device_configurations[i].deviceName[0] != '\0') {
72257291
loader_log(
72267292
inst, VULKAN_LOADER_WARN_BIT, 0,
72277293
"loader_apply_settings_device_configurations: settings file contained device_configuration which does not "
7228-
"appear in the enumerated VkPhysicalDevices. Missing VkPhysicalDevice with deviceName: \"%s\" and deviceUUID: "
7229-
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
7230-
inst->settings.device_configurations[i].deviceName, id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7],
7231-
id[8], id[9], id[10], id[11], id[12], id[13], id[14], id[15]);
7294+
"appear in the enumerated VkPhysicalDevices. Missing VkPhysicalDevice with deviceName: \"%s\", "
7295+
"deviceUUID: %s, driverUUID: %s, driverVersion: %d",
7296+
inst->settings.device_configurations[i].deviceName, device_uuid_str, driver_uuid_str,
7297+
inst->settings.device_configurations[i].driverVersion);
72327298
} else {
72337299
loader_log(
72347300
inst, VULKAN_LOADER_WARN_BIT, 0,
72357301
"loader_apply_settings_device_configurations: settings file contained device_configuration which does not "
72367302
"appear in the enumerated VkPhysicalDevices. Missing VkPhysicalDevice with deviceUUID: "
7237-
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
7238-
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],
7239-
id[15]);
7303+
"%s, driverUUID: %s, driverVersion: %d",
7304+
device_uuid_str, driver_uuid_str, inst->settings.device_configurations[i].driverVersion);
72407305
}
72417306
}
72427307
}
72437308

72447309
for (uint32_t j = 0; j < inst->phys_dev_count_term; j++) {
7245-
if (!pd_was_added[j]) {
7310+
if (!pd_details[j].pd_was_added) {
72467311
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
72477312
"VkPhysicalDevice \"%s\" did not appear in the settings file device configurations list, so was not added "
72487313
"to the pPhysicalDevices array",
7249-
pd_props[j].deviceName);
7314+
pd_details[j].properties.deviceName);
72507315
}
72517316
}
72527317

loader/settings.c

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -297,46 +297,72 @@ VkResult parse_additional_drivers(const struct loader_instance* inst, cJSON* set
297297
return res;
298298
}
299299

300-
VkResult parse_device_configuration(const struct loader_instance* inst, cJSON* device_configuration_json,
301-
loader_settings_device_configuration* device_configuration) {
302-
(void)inst;
303-
VkResult res = VK_SUCCESS;
304-
cJSON* deviceUUID_array = loader_cJSON_GetObjectItem(device_configuration_json, "deviceUUID");
305-
if (NULL == deviceUUID_array) {
306-
res = VK_ERROR_INITIALIZATION_FAILED;
307-
goto out;
300+
VkResult parse_uuid_array(cJSON* device_configuration_json, const char* uuid_name, uint8_t uuid[16]) {
301+
cJSON* uuid_array = loader_cJSON_GetObjectItem(device_configuration_json, uuid_name);
302+
if (NULL == uuid_array) {
303+
return VK_ERROR_INITIALIZATION_FAILED;
308304
}
309305

310-
if (deviceUUID_array->type != cJSON_Array) {
311-
res = VK_ERROR_INITIALIZATION_FAILED;
312-
goto out;
306+
if (uuid_array->type != cJSON_Array) {
307+
return VK_ERROR_INITIALIZATION_FAILED;
313308
}
314-
if (VK_UUID_SIZE != loader_cJSON_GetArraySize(deviceUUID_array)) {
315-
res = VK_ERROR_INITIALIZATION_FAILED;
316-
goto out;
309+
if (VK_UUID_SIZE != loader_cJSON_GetArraySize(uuid_array)) {
310+
return VK_ERROR_INITIALIZATION_FAILED;
317311
}
318312

319313
cJSON* uuid_field = NULL;
320314
size_t i = 0;
321-
cJSON_ArrayForEach(uuid_field, deviceUUID_array) {
315+
cJSON_ArrayForEach(uuid_field, uuid_array) {
316+
if (i >= VK_UUID_SIZE) {
317+
break;
318+
}
322319
if (uuid_field->type != cJSON_Number) {
323-
res = VK_ERROR_INITIALIZATION_FAILED;
324-
goto out;
320+
return VK_ERROR_INITIALIZATION_FAILED;
325321
}
326322
if (uuid_field->valueint < 0 || uuid_field->valueint > 255) {
327-
res = VK_ERROR_INITIALIZATION_FAILED;
328-
goto out;
323+
return VK_ERROR_INITIALIZATION_FAILED;
329324
}
330-
device_configuration->deviceUUID[i] = (uint8_t)uuid_field->valueint;
325+
326+
uuid[i] = (uint8_t)uuid_field->valueint;
331327
i++;
332328
}
329+
return VK_SUCCESS;
330+
}
331+
332+
VkResult parse_device_configuration(const struct loader_instance* inst, cJSON* device_configuration_json,
333+
loader_settings_device_configuration* device_configuration) {
334+
(void)inst;
335+
VkResult res = VK_SUCCESS;
336+
337+
res = parse_uuid_array(device_configuration_json, "deviceUUID", device_configuration->deviceUUID);
338+
if (VK_SUCCESS != res) {
339+
goto out;
340+
}
341+
342+
res = parse_uuid_array(device_configuration_json, "driverUUID", device_configuration->driverUUID);
343+
if (VK_SUCCESS != res) {
344+
goto out;
345+
}
346+
347+
cJSON* driverVersion_json = loader_cJSON_GetObjectItem(device_configuration_json, "driverVersion");
348+
if (NULL == driverVersion_json || driverVersion_json->type != cJSON_Number) {
349+
return VK_ERROR_INITIALIZATION_FAILED;
350+
}
351+
device_configuration->driverVersion = driverVersion_json->valueint;
333352

334353
VkResult deviceNameRes = loader_parse_json_string_to_existing_str(
335354
device_configuration_json, "deviceName", VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, device_configuration->deviceName);
336355
if (VK_ERROR_OUT_OF_HOST_MEMORY == deviceNameRes) {
337356
res = deviceNameRes;
338357
goto out;
339358
}
359+
360+
VkResult driverNameRes = loader_parse_json_string_to_existing_str(
361+
device_configuration_json, "driverName", VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, device_configuration->driverName);
362+
if (VK_ERROR_OUT_OF_HOST_MEMORY == driverNameRes) {
363+
res = driverNameRes;
364+
goto out;
365+
}
340366
out:
341367
if (res != VK_SUCCESS) {
342368
memset(device_configuration, 0, sizeof(loader_settings_device_configuration));
@@ -542,6 +568,10 @@ bool check_if_device_configurations_are_equal(loader_settings_device_configurati
542568
for (uint32_t i = 0; i < VK_UUID_SIZE; i++) {
543569
if (a->deviceUUID[i] != b->deviceUUID[i]) return false;
544570
}
571+
for (uint32_t i = 0; i < VK_UUID_SIZE; i++) {
572+
if (a->driverUUID[i] != b->driverUUID[i]) return false;
573+
}
574+
if (a->driverVersion != b->driverVersion) return false;
545575
return true;
546576
}
547577

@@ -613,13 +643,19 @@ void log_settings(const struct loader_instance* inst, loader_settings* settings)
613643
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "Device Configurations count = %d", settings->device_configuration_count);
614644
for (uint32_t i = 0; i < settings->device_configuration_count; i++) {
615645
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "---- Device Configuration [%d] ----", i);
616-
uint8_t* id = settings->device_configurations[i].deviceUUID;
617-
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0,
618-
"deviceUUID: %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", id[0], id[1], id[2],
619-
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]);
646+
char device_uuid_str[UUID_STR_LEN] = {0};
647+
loader_log_generate_uuid_string(settings->device_configurations[i].deviceUUID, device_uuid_str);
648+
char driver_uuid_str[UUID_STR_LEN] = {0};
649+
loader_log_generate_uuid_string(settings->device_configurations[i].driverUUID, driver_uuid_str);
650+
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "deviceUUID: %s", device_uuid_str);
651+
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "driverUUID: %s", driver_uuid_str);
652+
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "driverVersion: %d", settings->device_configurations[i].driverVersion);
620653
if ('\0' != settings->device_configurations[i].deviceName[0]) {
621654
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "deviceName: %s", settings->device_configurations[i].deviceName);
622655
}
656+
if ('\0' != settings->device_configurations[i].driverName[0]) {
657+
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "driverName: %s", settings->device_configurations[i].driverName);
658+
}
623659
}
624660
}
625661
loader_log(inst, VULKAN_LOADER_DEBUG_BIT, 0, "---------------------------------");

loader/settings.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,11 @@ typedef struct loader_settings_driver_configuration {
6767
} loader_settings_driver_configuration;
6868

6969
typedef struct loader_settings_device_configuration {
70-
char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
7170
uint8_t deviceUUID[VK_UUID_SIZE];
71+
uint8_t driverUUID[VK_UUID_SIZE];
72+
uint32_t driverVersion;
73+
char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
74+
char driverName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE];
7275
} loader_settings_device_configuration;
7376

7477
typedef struct loader_settings {

0 commit comments

Comments
 (0)