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
161 changes: 113 additions & 48 deletions loader/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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);
}
}

Expand All @@ -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);
}
}

Expand Down
7 changes: 7 additions & 0 deletions loader/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
}
4 changes: 4 additions & 0 deletions loader/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Loading
Loading