Fix #888 crash in Lutris with Linux sorting

The sorting algorithm needed to take into account both the application
API version as well as the driver API version.

This required additional changes to the sorting algorithm for the fallback
since even if the instance supports the extension or Vulkan 1.1, the individual
drivers may not.

Also, add supporting tests which would catch these cases in the future.
In the process, I realized we assumed that the presence of an extension in the
test_icd indicated "enablement" which was incorrect.  So I separated out
that into a set of "enabled instance extensions"
This commit is contained in:
Mark Young 2022-03-25 08:42:44 -06:00
parent 8354f108f5
commit d72909ee28
5 changed files with 293 additions and 36 deletions

View File

@ -5181,13 +5181,20 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateInstance(const VkInstanceCreateI
}
}
#ifdef LOADER_ENABLE_LINUX_SORT
// Force on "VK_KHR_get_physical_device_properties2" for Linux as we use it for GPU sorting.
if (icd_term->scanned_icd->api_version < VK_API_VERSION_1_1) {
// Force on "VK_KHR_get_physical_device_properties2" for Linux as we use it for GPU sorting. This
// should be done if the API version of either the application or the driver does not natively support
// the core version of vkGetPhysicalDevicePoroperties2 entrypoint.
if ((ptr_instance->app_api_major_version == 1 && ptr_instance->app_api_minor_version == 0) ||
(VK_API_VERSION_MAJOR(icd_term->scanned_icd->api_version) == 1 &&
VK_API_VERSION_MINOR(icd_term->scanned_icd->api_version) == 0)) {
prop = get_extension_property(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, &icd_exts);
if (prop) {
filtered_extension_names[icd_create_info.enabledExtensionCount] =
(char *)VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME;
icd_create_info.enabledExtensionCount++;
// At least one ICD supports this, so the instance should be able to support it
ptr_instance->supports_get_dev_prop_2 = true;
}
}
#endif // LOADER_ENABLE_LINUX_SORT

View File

@ -236,9 +236,9 @@ VkResult linux_read_sorted_physical_devices(struct loader_instance *inst, uint32
struct loader_phys_dev_per_icd *icd_devices,
struct loader_physical_device_term **sorted_device_term) {
VkResult res = VK_SUCCESS;
bool is_vulkan_1_1 = false;
bool app_is_vulkan_1_1 = false;
if (inst->app_api_major_version >= 1 && inst->app_api_minor_version >= 1) {
is_vulkan_1_1 = true;
app_is_vulkan_1_1 = true;
}
struct LinuxSortedDeviceInfo *sorted_device_info = loader_instance_heap_alloc(
@ -249,7 +249,9 @@ VkResult linux_read_sorted_physical_devices(struct loader_instance *inst, uint32
}
memset(sorted_device_info, 0, inst->total_gpu_count * sizeof(struct LinuxSortedDeviceInfo));
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, "linux_read_sorted_physical_devices: Original order:");
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
"linux_read_sorted_physical_devices: (App Version %d.%d)", inst->app_api_major_version, inst->app_api_minor_version);
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, " Original order:");
// Grab all the necessary info we can about each device
uint32_t index = 0;
@ -298,15 +300,22 @@ VkResult linux_read_sorted_physical_devices(struct loader_instance *inst, uint32
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT};
VkPhysicalDeviceProperties2 dev_props2 = (VkPhysicalDeviceProperties2){
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = (VkBaseInStructure *)&pci_props};
if (is_vulkan_1_1 && device_is_1_1_capable) {
icd_term->dispatch.GetPhysicalDeviceProperties2(sorted_device_info[index].physical_device, &dev_props2);
PFN_vkGetPhysicalDeviceProperties2 GetPhysDevProps2 = NULL;
if (app_is_vulkan_1_1 && device_is_1_1_capable) {
GetPhysDevProps2 = icd_term->dispatch.GetPhysicalDeviceProperties2;
} else {
icd_term->dispatch.GetPhysicalDeviceProperties2KHR(sorted_device_info[index].physical_device, &dev_props2);
GetPhysDevProps2 = (PFN_vkGetPhysicalDeviceProperties2)icd_term->dispatch.GetPhysicalDeviceProperties2KHR;
}
if (NULL != GetPhysDevProps2) {
GetPhysDevProps2(sorted_device_info[index].physical_device, &dev_props2);
sorted_device_info[index].pci_domain = pci_props.pciDomain;
sorted_device_info[index].pci_bus = pci_props.pciBus;
sorted_device_info[index].pci_device = pci_props.pciDevice;
sorted_device_info[index].pci_function = pci_props.pciFunction;
} else {
sorted_device_info[index].has_pci_bus_info = false;
}
sorted_device_info[index].pci_domain = pci_props.pciDomain;
sorted_device_info[index].pci_bus = pci_props.pciBus;
sorted_device_info[index].pci_device = pci_props.pciDevice;
sorted_device_info[index].pci_function = pci_props.pciFunction;
}
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, " [%u] %s", index,
sorted_device_info[index].device_name);
@ -321,7 +330,7 @@ VkResult linux_read_sorted_physical_devices(struct loader_instance *inst, uint32
qsort(sorted_device_info, inst->total_gpu_count, sizeof(struct LinuxSortedDeviceInfo), compare_devices);
// If we have a selected index, add that first.
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, "linux_read_sorted_physical_devices: Order set to:");
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, " Sorted order:");
// Add all others after (they've already been sorted)
for (uint32_t dev = 0; dev < inst->total_gpu_count; ++dev) {
@ -345,9 +354,9 @@ out:
VkResult linux_sort_physical_device_groups(struct loader_instance *inst, uint32_t group_count,
struct loader_physical_device_group_term *sorted_group_term) {
VkResult res = VK_SUCCESS;
bool is_vulkan_1_1 = false;
bool app_is_vulkan_1_1 = false;
if (inst->app_api_major_version >= 1 && inst->app_api_minor_version >= 1) {
is_vulkan_1_1 = true;
app_is_vulkan_1_1 = true;
}
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, "linux_sort_physical_device_groups: Original order:");
@ -400,18 +409,21 @@ VkResult linux_sort_physical_device_groups(struct loader_instance *inst, uint32_
VkPhysicalDeviceProperties2 dev_props2 = (VkPhysicalDeviceProperties2){
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, .pNext = (VkBaseInStructure *)&pci_props};
if (is_vulkan_1_1 && device_is_1_1_capable) {
icd_term->dispatch.GetPhysicalDeviceProperties2(
sorted_group_term[group].internal_device_info[gpu].physical_device, &dev_props2);
PFN_vkGetPhysicalDeviceProperties2 GetPhysDevProps2 = NULL;
if (app_is_vulkan_1_1 && device_is_1_1_capable) {
GetPhysDevProps2 = icd_term->dispatch.GetPhysicalDeviceProperties2;
} else {
icd_term->dispatch.GetPhysicalDeviceProperties2KHR(
sorted_group_term[group].internal_device_info[gpu].physical_device, &dev_props2);
GetPhysDevProps2 = (PFN_vkGetPhysicalDeviceProperties2)icd_term->dispatch.GetPhysicalDeviceProperties2KHR;
}
if (NULL != GetPhysDevProps2) {
GetPhysDevProps2(sorted_group_term[group].internal_device_info[gpu].physical_device, &dev_props2);
sorted_group_term[group].internal_device_info[gpu].pci_domain = pci_props.pciDomain;
sorted_group_term[group].internal_device_info[gpu].pci_bus = pci_props.pciBus;
sorted_group_term[group].internal_device_info[gpu].pci_device = pci_props.pciDevice;
sorted_group_term[group].internal_device_info[gpu].pci_function = pci_props.pciFunction;
} else {
sorted_group_term[group].internal_device_info[gpu].has_pci_bus_info = false;
}
sorted_group_term[group].internal_device_info[gpu].pci_domain = pci_props.pciDomain;
sorted_group_term[group].internal_device_info[gpu].pci_bus = pci_props.pciBus;
sorted_group_term[group].internal_device_info[gpu].pci_device = pci_props.pciDevice;
sorted_group_term[group].internal_device_info[gpu].pci_function = pci_props.pciFunction;
}
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, " [%u] %s", gpu,
sorted_group_term[group].internal_device_info[gpu].device_name);

View File

@ -70,12 +70,18 @@ bool CheckLayer(std::vector<LayerDefinition>& layers, std::string layerName) {
return false;
}
bool IsInstanceExtensionEnabled(const char* extension_name) {
bool IsInstanceExtensionSupported(const char* extension_name) {
return icd.instance_extensions.end() !=
std::find_if(icd.instance_extensions.begin(), icd.instance_extensions.end(),
[extension_name](Extension const& ext) { return ext.extensionName == extension_name; });
}
bool IsInstanceExtensionEnabled(const char* extension_name) {
return icd.enabled_instance_extensions.end() !=
std::find_if(icd.enabled_instance_extensions.begin(), icd.enabled_instance_extensions.end(),
[extension_name](Extension const& ext) { return ext.extensionName == extension_name; });
}
bool IsPhysicalDeviceExtensionAvailable(const char* extension_name) {
for (auto& phys_dev : icd.physical_devices) {
if (phys_dev.extensions.end() !=
@ -177,6 +183,14 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateInstance(const VkInstanceCreateInfo*
return VK_ERROR_INCOMPATIBLE_DRIVER;
}
}
// Add to the list of enabled extensions only those that the ICD actively supports
for (uint32_t iii = 0; iii < pCreateInfo->enabledExtensionCount; ++iii) {
if (IsInstanceExtensionSupported(pCreateInfo->ppEnabledExtensionNames[iii])) {
icd.add_enabled_instance_extension({pCreateInfo->ppEnabledExtensionNames[iii]});
}
}
// VK_SUCCESS
*pInstance = icd.instance_handle.handle;

View File

@ -68,6 +68,7 @@ struct TestICD {
BUILDER_VALUE(TestICD, uint32_t, icd_api_version, VK_API_VERSION_1_0)
BUILDER_VECTOR(TestICD, LayerDefinition, instance_layers, instance_layer)
BUILDER_VECTOR(TestICD, Extension, instance_extensions, instance_extension)
BUILDER_VECTOR(TestICD, Extension, enabled_instance_extensions, enabled_instance_extension)
BUILDER_VECTOR_MOVE_ONLY(TestICD, PhysicalDevice, physical_devices, physical_device);

View File

@ -2219,9 +2219,229 @@ TEST_F(CreateInstance, InstanceNullExtensionPtr) {
#if defined(__linux__) || defined(__FreeBSD__)
// NOTE: Sort order only affects Linux
TEST(SortedPhysicalDevices, DevicesSortEnabled) {
TEST(SortedPhysicalDevices, DevicesSortEnabled10NoAppExt) {
FrameworkEnvironment env{};
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
env.get_test_icd(0).physical_devices.push_back({"pd0", 7});
FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
VK_API_VERSION_1_1, 888, 0xAAA001);
env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
env.get_test_icd(0).physical_devices.push_back({"pd1", 3});
FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
VK_API_VERSION_1_1, 888, 0xAAA002);
env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
env.get_test_icd(1).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
env.get_test_icd(1).physical_devices.push_back({"pd2", 0});
FillInRandomDeviceProps(env.get_test_icd(1).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_CPU, VK_API_VERSION_1_0,
1, 0xBBBB001);
env.get_test_icd(1).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
env.get_test_icd(2).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
env.get_test_icd(2).physical_devices.push_back({"pd3", 1});
FillInRandomDeviceProps(env.get_test_icd(2).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
VK_API_VERSION_1_1, 75, 0xCCCC001);
env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
env.get_test_icd(2).physical_devices.push_back({"pd4", 4});
FillInRandomDeviceProps(env.get_test_icd(2).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
VK_API_VERSION_1_0, 75, 0xCCCC002);
env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
env.get_test_icd(3).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
env.get_test_icd(3).physical_devices.push_back({"pd5", 0});
FillInRandomDeviceProps(env.get_test_icd(3).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU,
VK_API_VERSION_1_1, 6940, 0xDDDD001);
env.get_test_icd(3).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
InstWrapper instance(env.vulkan_functions);
instance.CheckCreate();
const uint32_t max_phys_devs = 6;
uint32_t device_count = max_phys_devs;
std::array<VkPhysicalDevice, max_phys_devs> physical_devices;
ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data()));
ASSERT_EQ(device_count, max_phys_devs);
for (uint32_t dev = 0; dev < device_count; ++dev) {
VkPhysicalDeviceProperties props{};
instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &props);
switch (dev) {
case 0:
ASSERT_EQ(props.deviceType, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU);
ASSERT_EQ(true, !strcmp("pd3", props.deviceName));
ASSERT_EQ(props.vendorID, 75);
ASSERT_EQ(props.deviceID, 0xCCCC001);
break;
case 1:
ASSERT_EQ(props.deviceType, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU);
ASSERT_EQ(true, !strcmp("pd4", props.deviceName));
ASSERT_EQ(props.vendorID, 75);
ASSERT_EQ(props.deviceID, 0xCCCC002);
break;
case 2:
ASSERT_EQ(props.deviceType, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU);
ASSERT_EQ(true, !strcmp("pd0", props.deviceName));
ASSERT_EQ(props.vendorID, 888);
ASSERT_EQ(props.deviceID, 0xAAA001);
break;
case 3:
ASSERT_EQ(props.deviceType, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU);
ASSERT_EQ(true, !strcmp("pd1", props.deviceName));
ASSERT_EQ(props.vendorID, 888);
ASSERT_EQ(props.deviceID, 0xAAA002);
break;
case 4:
ASSERT_EQ(props.deviceType, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU);
ASSERT_EQ(true, !strcmp("pd5", props.deviceName));
ASSERT_EQ(props.vendorID, 6940);
ASSERT_EQ(props.deviceID, 0xDDDD001);
break;
case 5:
ASSERT_EQ(props.deviceType, VK_PHYSICAL_DEVICE_TYPE_CPU);
ASSERT_EQ(true, !strcmp("pd2", props.deviceName));
ASSERT_EQ(props.vendorID, 1);
ASSERT_EQ(props.deviceID, 0xBBBB001);
break;
default:
ASSERT_EQ(false, true);
}
}
// Make sure if we call enumerate again, the information is the same
std::array<VkPhysicalDevice, max_phys_devs> physical_devices_again;
ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices_again.data()));
ASSERT_EQ(device_count, max_phys_devs);
for (uint32_t dev = 0; dev < device_count; ++dev) {
ASSERT_EQ(physical_devices[dev], physical_devices_again[dev]);
}
}
TEST(SortedPhysicalDevices, DevicesSortEnabled10AppExt) {
FrameworkEnvironment env{};
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
env.get_test_icd(0).physical_devices.push_back({"pd0", 7});
FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
VK_API_VERSION_1_1, 888, 0xAAA001);
env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
env.get_test_icd(0).physical_devices.push_back({"pd1", 3});
FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
VK_API_VERSION_1_1, 888, 0xAAA002);
env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
env.get_test_icd(1).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
env.get_test_icd(1).physical_devices.push_back({"pd2", 0});
FillInRandomDeviceProps(env.get_test_icd(1).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_CPU, VK_API_VERSION_1_0,
1, 0xBBBB001);
env.get_test_icd(1).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
env.get_test_icd(2).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
env.get_test_icd(2).physical_devices.push_back({"pd3", 1});
FillInRandomDeviceProps(env.get_test_icd(2).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
VK_API_VERSION_1_1, 75, 0xCCCC001);
env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
env.get_test_icd(2).physical_devices.push_back({"pd4", 4});
FillInRandomDeviceProps(env.get_test_icd(2).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
VK_API_VERSION_1_0, 75, 0xCCCC002);
env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
env.get_test_icd(3).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
env.get_test_icd(3).physical_devices.push_back({"pd5", 0});
FillInRandomDeviceProps(env.get_test_icd(3).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU,
VK_API_VERSION_1_1, 6940, 0xDDDD001);
env.get_test_icd(3).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
InstWrapper instance(env.vulkan_functions);
instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
instance.CheckCreate();
auto GetPhysDevProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2KHR>(
instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2KHR"));
ASSERT_NE(GetPhysDevProps2, nullptr);
const uint32_t max_phys_devs = 6;
uint32_t device_count = max_phys_devs;
std::array<VkPhysicalDevice, max_phys_devs> physical_devices;
ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices.data()));
ASSERT_EQ(device_count, max_phys_devs);
for (uint32_t dev = 0; dev < device_count; ++dev) {
VkPhysicalDeviceProperties props{};
instance->vkGetPhysicalDeviceProperties(physical_devices[dev], &props);
VkPhysicalDeviceProperties2KHR props2{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2};
VkPhysicalDevicePCIBusInfoPropertiesEXT pci_bus_info{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT};
props2.pNext = &pci_bus_info;
GetPhysDevProps2(physical_devices[dev], &props2);
switch (dev) {
case 0:
ASSERT_EQ(props.deviceType, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU);
ASSERT_EQ(true, !strcmp("pd3", props.deviceName));
ASSERT_EQ(props.vendorID, 75);
ASSERT_EQ(props.deviceID, 0xCCCC001);
ASSERT_EQ(pci_bus_info.pciBus, 1);
break;
case 1:
ASSERT_EQ(props.deviceType, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU);
ASSERT_EQ(true, !strcmp("pd4", props.deviceName));
ASSERT_EQ(props.vendorID, 75);
ASSERT_EQ(props.deviceID, 0xCCCC002);
ASSERT_EQ(pci_bus_info.pciBus, 4);
break;
case 2:
ASSERT_EQ(props.deviceType, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU);
ASSERT_EQ(true, !strcmp("pd0", props.deviceName));
ASSERT_EQ(props.vendorID, 888);
ASSERT_EQ(props.deviceID, 0xAAA001);
ASSERT_EQ(pci_bus_info.pciBus, 7);
break;
case 3:
ASSERT_EQ(props.deviceType, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU);
ASSERT_EQ(true, !strcmp("pd1", props.deviceName));
ASSERT_EQ(props.vendorID, 888);
ASSERT_EQ(props.deviceID, 0xAAA002);
ASSERT_EQ(pci_bus_info.pciBus, 3);
break;
case 4:
ASSERT_EQ(props.deviceType, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU);
ASSERT_EQ(true, !strcmp("pd5", props.deviceName));
ASSERT_EQ(props.vendorID, 6940);
ASSERT_EQ(props.deviceID, 0xDDDD001);
ASSERT_EQ(pci_bus_info.pciBus, 0);
break;
case 5:
ASSERT_EQ(props.deviceType, VK_PHYSICAL_DEVICE_TYPE_CPU);
ASSERT_EQ(true, !strcmp("pd2", props.deviceName));
ASSERT_EQ(props.vendorID, 1);
ASSERT_EQ(props.deviceID, 0xBBBB001);
ASSERT_EQ(pci_bus_info.pciBus, 0);
break;
default:
ASSERT_EQ(false, true);
}
}
// Make sure if we call enumerate again, the information is the same
std::array<VkPhysicalDevice, max_phys_devs> physical_devices_again;
ASSERT_EQ(VK_SUCCESS, instance->vkEnumeratePhysicalDevices(instance, &device_count, physical_devices_again.data()));
ASSERT_EQ(device_count, max_phys_devs);
for (uint32_t dev = 0; dev < device_count; ++dev) {
ASSERT_EQ(physical_devices[dev], physical_devices_again[dev]);
}
}
TEST(SortedPhysicalDevices, DevicesSortEnabled11) {
FrameworkEnvironment env{};
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
env.get_test_icd(0).set_icd_api_version(VK_API_VERSION_1_1);
env.get_test_icd(0).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
env.get_test_icd(0).physical_devices.push_back({"pd0", 7});
FillInRandomDeviceProps(env.get_test_icd(0).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
@ -2232,37 +2452,40 @@ TEST(SortedPhysicalDevices, DevicesSortEnabled) {
VK_API_VERSION_1_0, 888, 0xAAA002);
env.get_test_icd(0).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
env.get_test_icd(1).set_icd_api_version(VK_API_VERSION_1_1);
env.get_test_icd(1).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
env.get_test_icd(1).physical_devices.push_back({"pd2", 0});
FillInRandomDeviceProps(env.get_test_icd(1).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_CPU, VK_API_VERSION_1_0,
1, 0xBBBB001);
env.get_test_icd(1).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
env.get_test_icd(2).set_icd_api_version(VK_API_VERSION_1_1);
env.get_test_icd(2).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
env.get_test_icd(2).physical_devices.push_back({"pd3", 1});
FillInRandomDeviceProps(env.get_test_icd(2).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
VK_API_VERSION_1_0, 75, 0xCCCC001);
VK_API_VERSION_1_1, 75, 0xCCCC001);
env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
env.get_test_icd(2).physical_devices.push_back({"pd4", 4});
FillInRandomDeviceProps(env.get_test_icd(2).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU,
VK_API_VERSION_1_0, 75, 0xCCCC002);
VK_API_VERSION_1_1, 75, 0xCCCC002);
env.get_test_icd(2).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_0));
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2, VK_API_VERSION_1_1));
env.get_test_icd(3).set_icd_api_version(VK_API_VERSION_1_1);
env.get_test_icd(3).add_instance_extension({VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME});
env.get_test_icd(3).physical_devices.push_back({"pd5", 0});
FillInRandomDeviceProps(env.get_test_icd(3).physical_devices.back().properties, VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU,
VK_API_VERSION_1_0, 6940, 0xDDDD001);
VK_API_VERSION_1_1, 6940, 0xDDDD001);
env.get_test_icd(3).physical_devices.back().extensions.push_back({VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, 0});
InstWrapper instance(env.vulkan_functions);
instance.create_info.add_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
instance.create_info.set_api_version(VK_API_VERSION_1_1);
instance.CheckCreate();
auto GetPhysDevProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2KHR>(
instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2KHR"));
auto GetPhysDevProps2 = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2>(
instance.functions->vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties2"));
ASSERT_NE(GetPhysDevProps2, nullptr);
const uint32_t max_phys_devs = 6;