mirror of
https://github.com/openharmony/third_party_vulkan-loader.git
synced 2026-07-19 17:13:36 -04:00
Loader single EnumPhysDev call through layers
The loader trampoline previously would query all devices every time vkEnumeratePhysicalDevices was called. To do this, it would make two calls every time: - First, it would ignore the passed in user values - Second, it would query the total number of available devices. - Third, it would query the values for every available device This resulted in layers reporting 2 vkEnumeratePhysicalDevices call for every 1 the application made which could get very polluted in output. It didn't break any functionality, just made things messy. This change removes that behavior and adds a bunch of test cases to verify nothing broke in the move.
This commit is contained in:
+510
-407
File diff suppressed because it is too large
Load Diff
+5
-5
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2014-2021 The Khronos Group Inc.
|
||||
* Copyright (c) 2014-2021 Valve Corporation
|
||||
* Copyright (c) 2014-2021 LunarG, Inc.
|
||||
* Copyright (c) 2014-2022 The Khronos Group Inc.
|
||||
* Copyright (c) 2014-2022 Valve Corporation
|
||||
* Copyright (c) 2014-2022 LunarG, Inc.
|
||||
* Copyright (C) 2015 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -164,8 +164,8 @@ VkResult loader_validate_device_extensions(struct loader_instance *this_instance
|
||||
const struct loader_layer_list *activated_device_layers,
|
||||
const struct loader_extension_list *icd_exts, const VkDeviceCreateInfo *pCreateInfo);
|
||||
|
||||
VkResult setup_loader_tramp_phys_devs(struct loader_instance *inst);
|
||||
VkResult setup_loader_term_phys_devs(struct loader_instance *inst);
|
||||
VkResult setup_loader_tramp_phys_devs(struct loader_instance *inst, uint32_t phys_dev_count, VkPhysicalDevice *phys_devs);
|
||||
VkResult setup_loader_tramp_phys_dev_groups(struct loader_instance *inst, uint32_t group_count, VkPhysicalDeviceGroupProperties *groups);
|
||||
|
||||
VkStringErrorFlags vk_string_validate(const int max_length, const char *char_array);
|
||||
char *loader_get_next_path(char *path);
|
||||
|
||||
@@ -271,8 +271,6 @@ struct loader_instance {
|
||||
// device stored internal to the public structures.
|
||||
uint32_t phys_dev_group_count_term;
|
||||
struct VkPhysicalDeviceGroupProperties **phys_dev_groups_term;
|
||||
uint32_t phys_dev_group_count_tramp;
|
||||
struct VkPhysicalDeviceGroupProperties **phys_dev_groups_tramp;
|
||||
|
||||
struct loader_instance *next;
|
||||
|
||||
|
||||
@@ -219,7 +219,8 @@ static void linux_env_var_default_device(struct loader_instance *inst, uint32_t
|
||||
for (int32_t i = 0; i < (int32_t)device_count; ++i) {
|
||||
if (sorted_device_info[i].vendor_id == vendor_id && sorted_device_info[i].device_id == device_id) {
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
|
||||
"linux_env_var_default_device: Found default at index %u \'%s\'", i, sorted_device_info[i].device_name);
|
||||
"linux_env_var_default_device: Found default at index %u \'%s\'", i,
|
||||
sorted_device_info[i].device_name);
|
||||
sorted_device_info[i].default_device = true;
|
||||
break;
|
||||
}
|
||||
@@ -424,6 +425,11 @@ VkResult linux_read_sorted_physical_device_groups(struct loader_instance *inst,
|
||||
// Sort GPUs in each group
|
||||
qsort(sorted_group_term[group].internal_device_info, sorted_group_term[group].group_props.physicalDeviceCount,
|
||||
sizeof(struct LinuxSortedDeviceInfo), compare_devices);
|
||||
|
||||
// Match the externally used physical device list with the sorted physical device list for this group.
|
||||
for (uint32_t dev = 0; dev < sorted_group_term[group].group_props.physicalDeviceCount; ++dev) {
|
||||
sorted_group_term[group].group_props.physicalDevices[dev] = sorted_group_term[group].internal_device_info[dev].physical_device;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort device groups by PCI info
|
||||
@@ -435,8 +441,9 @@ VkResult linux_read_sorted_physical_device_groups(struct loader_instance *inst,
|
||||
for (uint32_t group = 0; group < group_count; ++group) {
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, " Group %u", group);
|
||||
for (uint32_t gpu = 0; gpu < sorted_group_term[group].group_props.physicalDeviceCount; ++gpu) {
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, " [%u] %s %s", gpu,
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, " [%u] %s %p %s", gpu,
|
||||
sorted_group_term[group].internal_device_info[gpu].device_name,
|
||||
sorted_group_term[group].internal_device_info[gpu].physical_device,
|
||||
(sorted_group_term[group].internal_device_info[gpu].default_device ? "[default]" : ""));
|
||||
}
|
||||
}
|
||||
|
||||
+14
-241
@@ -724,13 +724,6 @@ LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance,
|
||||
loader_instance_heap_free(ptr_instance, ptr_instance->phys_devs_tramp);
|
||||
}
|
||||
|
||||
if (ptr_instance->phys_dev_groups_tramp) {
|
||||
for (uint32_t i = 0; i < ptr_instance->phys_dev_group_count_tramp; i++) {
|
||||
loader_instance_heap_free(ptr_instance, ptr_instance->phys_dev_groups_tramp[i]);
|
||||
}
|
||||
loader_instance_heap_free(ptr_instance, ptr_instance->phys_dev_groups_tramp);
|
||||
}
|
||||
|
||||
if (messenger_setup) {
|
||||
loader_log(ptr_instance, VULKAN_LOADER_INFO_BIT, 0,
|
||||
"vkDestroyInstance: destroying temporary instance debug util messenger");
|
||||
@@ -760,8 +753,6 @@ LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkDestroyInstance(VkInstance instance,
|
||||
LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
|
||||
VkPhysicalDevice *pPhysicalDevices) {
|
||||
VkResult res = VK_SUCCESS;
|
||||
uint32_t count;
|
||||
uint32_t i;
|
||||
struct loader_instance *inst;
|
||||
|
||||
loader_platform_thread_lock_mutex(&loader_lock);
|
||||
@@ -784,38 +775,16 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstan
|
||||
// Setup the trampoline loader physical devices. This will actually
|
||||
// call down and setup the terminator loader physical devices during the
|
||||
// process.
|
||||
VkResult setup_res = setup_loader_tramp_phys_devs(inst);
|
||||
if (setup_res != VK_SUCCESS && setup_res != VK_INCOMPLETE) {
|
||||
res = setup_res;
|
||||
goto out;
|
||||
}
|
||||
|
||||
count = inst->phys_dev_count_tramp;
|
||||
|
||||
if (inst->phys_dev_count_tramp != inst->total_gpu_count) {
|
||||
loader_log(inst, VULKAN_LOADER_WARN_BIT | VULKAN_LOADER_LAYER_BIT, 0,
|
||||
"vkEnumeratePhysicalDevices: One or more layers modified physical devices!"
|
||||
"Count returned by ICDs = %d, count returned above layers = %d",
|
||||
inst->total_gpu_count, inst->phys_dev_count_tramp);
|
||||
}
|
||||
res = inst->disp->layer_inst_disp.EnumeratePhysicalDevices(inst->instance, pPhysicalDeviceCount, pPhysicalDevices);
|
||||
|
||||
// Wrap the PhysDev object for loader usage, return wrapped objects
|
||||
if (NULL != pPhysicalDevices) {
|
||||
if (inst->phys_dev_count_tramp > *pPhysicalDeviceCount) {
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
|
||||
"vkEnumeratePhysicalDevices: Trimming device count down"
|
||||
" by application request from %d to %d physical devices",
|
||||
inst->phys_dev_count_tramp, *pPhysicalDeviceCount);
|
||||
count = *pPhysicalDeviceCount;
|
||||
res = VK_INCOMPLETE;
|
||||
}
|
||||
for (i = 0; i < count; i++) {
|
||||
pPhysicalDevices[i] = (VkPhysicalDevice)inst->phys_devs_tramp[i];
|
||||
if (NULL != pPhysicalDevices && (VK_SUCCESS == res || VK_INCOMPLETE == res)) {
|
||||
VkResult update_res = setup_loader_tramp_phys_devs(inst, *pPhysicalDeviceCount, pPhysicalDevices);
|
||||
if (VK_SUCCESS != update_res) {
|
||||
res = update_res;
|
||||
}
|
||||
}
|
||||
|
||||
*pPhysicalDeviceCount = count;
|
||||
|
||||
out:
|
||||
|
||||
loader_platform_thread_unlock_mutex(&loader_lock);
|
||||
@@ -2516,193 +2485,9 @@ LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands(VkCommandBuffer co
|
||||
|
||||
// ---- Vulkan core 1.1 trampolines
|
||||
|
||||
VkResult setupLoaderTrampPhysDevGroups(VkInstance instance, struct loader_instance *inst) {
|
||||
VkResult res = VK_SUCCESS;
|
||||
uint32_t total_count = 0;
|
||||
VkPhysicalDeviceGroupPropertiesKHR **new_phys_dev_groups = NULL;
|
||||
VkPhysicalDeviceGroupPropertiesKHR *local_phys_dev_groups = NULL;
|
||||
PFN_vkEnumeratePhysicalDeviceGroups fpEnumeratePhysicalDeviceGroups = NULL;
|
||||
|
||||
// Get the function pointer to use to call into the ICD. This could be the core or KHR version
|
||||
if (inst->enabled_known_extensions.khr_device_group_creation) {
|
||||
fpEnumeratePhysicalDeviceGroups = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroupsKHR;
|
||||
} else {
|
||||
fpEnumeratePhysicalDeviceGroups = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroups;
|
||||
}
|
||||
|
||||
// Setup the trampoline loader physical devices. This will actually
|
||||
// call down and setup the terminator loader physical devices during the
|
||||
// process.
|
||||
VkResult setup_res = setup_loader_tramp_phys_devs(inst);
|
||||
if (setup_res != VK_SUCCESS && setup_res != VK_INCOMPLETE) {
|
||||
res = setup_res;
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Query how many physical device groups there
|
||||
res = fpEnumeratePhysicalDeviceGroups(inst->instance, &total_count, NULL);
|
||||
if (res != VK_SUCCESS) {
|
||||
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
|
||||
"setupLoaderTrampPhysDevGroups: Failed during dispatch call of "
|
||||
"\'EnumeratePhysicalDeviceGroupsKHR\' to lower layers or "
|
||||
"loader to get count.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Create an array for the new physical device groups, which will be stored
|
||||
// in the instance for the trampoline code.
|
||||
new_phys_dev_groups = (VkPhysicalDeviceGroupPropertiesKHR **)loader_instance_heap_alloc(
|
||||
inst, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHR *), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
|
||||
if (NULL == new_phys_dev_groups) {
|
||||
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
|
||||
"setupLoaderTrampPhysDevGroups: Failed to allocate new physical device"
|
||||
" group array of size %d",
|
||||
total_count);
|
||||
res = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
memset(new_phys_dev_groups, 0, total_count * sizeof(VkPhysicalDeviceGroupPropertiesKHR *));
|
||||
|
||||
// Create a temporary array (on the stack) to keep track of the
|
||||
// returned VkPhysicalDevice values.
|
||||
local_phys_dev_groups = loader_stack_alloc(sizeof(VkPhysicalDeviceGroupPropertiesKHR) * total_count);
|
||||
if (NULL == local_phys_dev_groups) {
|
||||
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
|
||||
"setupLoaderTrampPhysDevGroups: Failed to allocate local "
|
||||
"physical device group array of size %d",
|
||||
total_count);
|
||||
res = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
// Initialize the memory to something valid
|
||||
memset(local_phys_dev_groups, 0, sizeof(VkPhysicalDeviceGroupPropertiesKHR) * total_count);
|
||||
for (uint32_t group = 0; group < total_count; group++) {
|
||||
local_phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR;
|
||||
local_phys_dev_groups[group].pNext = NULL;
|
||||
local_phys_dev_groups[group].subsetAllocation = false;
|
||||
}
|
||||
|
||||
// Call down and get the content
|
||||
fpEnumeratePhysicalDeviceGroups(inst->instance, &total_count, local_phys_dev_groups);
|
||||
if (VK_SUCCESS != res) {
|
||||
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
|
||||
"setupLoaderTrampPhysDevGroups: Failed during dispatch call of "
|
||||
"\'EnumeratePhysicalDeviceGroupsKHR\' to lower layers or "
|
||||
"loader to get content.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Replace all the physical device IDs with the proper loader values
|
||||
for (uint32_t group = 0; group < total_count; group++) {
|
||||
for (uint32_t group_gpu = 0; group_gpu < local_phys_dev_groups[group].physicalDeviceCount; group_gpu++) {
|
||||
bool found = false;
|
||||
for (uint32_t tramp_gpu = 0; tramp_gpu < inst->phys_dev_count_tramp; tramp_gpu++) {
|
||||
if (local_phys_dev_groups[group].physicalDevices[group_gpu] == inst->phys_devs_tramp[tramp_gpu]->phys_dev) {
|
||||
local_phys_dev_groups[group].physicalDevices[group_gpu] = (VkPhysicalDevice)inst->phys_devs_tramp[tramp_gpu];
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
|
||||
"setupLoaderTrampPhysDevGroups: Failed to find GPU %d in group %d"
|
||||
" returned by \'EnumeratePhysicalDeviceGroupsKHR\' in list returned"
|
||||
" by \'EnumeratePhysicalDevices\'",
|
||||
group_gpu, group);
|
||||
res = VK_ERROR_INITIALIZATION_FAILED;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy or create everything to fill the new array of physical device groups
|
||||
for (uint32_t new_idx = 0; new_idx < total_count; new_idx++) {
|
||||
// Check if this physical device group with the same contents is already in the old buffer
|
||||
for (uint32_t old_idx = 0; old_idx < inst->phys_dev_group_count_tramp; old_idx++) {
|
||||
if (local_phys_dev_groups[new_idx].physicalDeviceCount == inst->phys_dev_groups_tramp[old_idx]->physicalDeviceCount) {
|
||||
bool found_all_gpus = true;
|
||||
for (uint32_t old_gpu = 0; old_gpu < inst->phys_dev_groups_tramp[old_idx]->physicalDeviceCount; old_gpu++) {
|
||||
bool found_gpu = false;
|
||||
for (uint32_t new_gpu = 0; new_gpu < local_phys_dev_groups[new_idx].physicalDeviceCount; new_gpu++) {
|
||||
if (local_phys_dev_groups[new_idx].physicalDevices[new_gpu] ==
|
||||
inst->phys_dev_groups_tramp[old_idx]->physicalDevices[old_gpu]) {
|
||||
found_gpu = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_gpu) {
|
||||
found_all_gpus = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found_all_gpus) {
|
||||
continue;
|
||||
} else {
|
||||
new_phys_dev_groups[new_idx] = inst->phys_dev_groups_tramp[old_idx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this physical device group isn't in the old buffer, create it
|
||||
if (NULL == new_phys_dev_groups[new_idx]) {
|
||||
new_phys_dev_groups[new_idx] = (VkPhysicalDeviceGroupPropertiesKHR *)loader_instance_heap_alloc(
|
||||
inst, sizeof(VkPhysicalDeviceGroupPropertiesKHR), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
|
||||
if (NULL == new_phys_dev_groups[new_idx]) {
|
||||
loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
|
||||
"setupLoaderTrampPhysDevGroups: Failed to allocate "
|
||||
"physical device group trampoline object %d",
|
||||
new_idx);
|
||||
total_count = new_idx;
|
||||
res = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
memcpy(new_phys_dev_groups[new_idx], &local_phys_dev_groups[new_idx], sizeof(VkPhysicalDeviceGroupPropertiesKHR));
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (VK_SUCCESS != res) {
|
||||
if (NULL != new_phys_dev_groups) {
|
||||
for (uint32_t i = 0; i < total_count; i++) {
|
||||
loader_instance_heap_free(inst, new_phys_dev_groups[i]);
|
||||
}
|
||||
loader_instance_heap_free(inst, new_phys_dev_groups);
|
||||
}
|
||||
total_count = 0;
|
||||
} else {
|
||||
// Free everything that didn't carry over to the new array of
|
||||
// physical device groups
|
||||
if (NULL != inst->phys_dev_groups_tramp) {
|
||||
for (uint32_t i = 0; i < inst->phys_dev_group_count_tramp; i++) {
|
||||
bool found = false;
|
||||
for (uint32_t j = 0; j < total_count; j++) {
|
||||
if (inst->phys_dev_groups_tramp[i] == new_phys_dev_groups[j]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
loader_instance_heap_free(inst, inst->phys_dev_groups_tramp[i]);
|
||||
}
|
||||
}
|
||||
loader_instance_heap_free(inst, inst->phys_dev_groups_tramp);
|
||||
}
|
||||
|
||||
// Swap in the new physical device group list
|
||||
inst->phys_dev_group_count_tramp = total_count;
|
||||
inst->phys_dev_groups_tramp = new_phys_dev_groups;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups(
|
||||
VkInstance instance, uint32_t *pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties *pPhysicalDeviceGroupProperties) {
|
||||
VkResult res = VK_SUCCESS;
|
||||
uint32_t count;
|
||||
uint32_t i;
|
||||
struct loader_instance *inst = NULL;
|
||||
|
||||
loader_platform_thread_lock_mutex(&loader_lock);
|
||||
@@ -2723,31 +2508,19 @@ LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups(
|
||||
goto out;
|
||||
}
|
||||
|
||||
VkResult setup_res = setupLoaderTrampPhysDevGroups(instance, inst);
|
||||
if (VK_SUCCESS != setup_res) {
|
||||
res = setup_res;
|
||||
goto out;
|
||||
}
|
||||
|
||||
count = inst->phys_dev_group_count_tramp;
|
||||
|
||||
// Setup the trampoline loader physical devices. This will actually
|
||||
// call down and setup the terminator loader physical devices during the
|
||||
// process.
|
||||
res = inst->disp->layer_inst_disp.EnumeratePhysicalDeviceGroups(inst->instance, pPhysicalDeviceGroupCount,
|
||||
pPhysicalDeviceGroupProperties);
|
||||
// Wrap the PhysDev object for loader usage, return wrapped objects
|
||||
if (NULL != pPhysicalDeviceGroupProperties) {
|
||||
if (inst->phys_dev_group_count_tramp > *pPhysicalDeviceGroupCount) {
|
||||
loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
|
||||
"vkEnumeratePhysicalDeviceGroupsKHR: Trimming device group count down"
|
||||
" by application request from %d to %d physical device groups",
|
||||
inst->phys_dev_group_count_tramp, *pPhysicalDeviceGroupCount);
|
||||
count = *pPhysicalDeviceGroupCount;
|
||||
res = VK_INCOMPLETE;
|
||||
}
|
||||
for (i = 0; i < count; i++) {
|
||||
memcpy(&pPhysicalDeviceGroupProperties[i], inst->phys_dev_groups_tramp[i], sizeof(VkPhysicalDeviceGroupPropertiesKHR));
|
||||
if (NULL != pPhysicalDeviceGroupProperties && (VK_SUCCESS == res || VK_INCOMPLETE == res)) {
|
||||
VkResult update_res = setup_loader_tramp_phys_dev_groups(inst, *pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
|
||||
if (VK_SUCCESS != update_res) {
|
||||
res = update_res;
|
||||
}
|
||||
}
|
||||
|
||||
*pPhysicalDeviceGroupCount = count;
|
||||
|
||||
out:
|
||||
|
||||
loader_platform_thread_unlock_mutex(&loader_lock);
|
||||
|
||||
Binary file not shown.
@@ -76,6 +76,8 @@ struct PhysicalDevice {
|
||||
};
|
||||
|
||||
struct PhysicalDeviceGroup {
|
||||
PhysicalDeviceGroup() {}
|
||||
PhysicalDeviceGroup(PhysicalDevice const& physical_device) { physical_device_handles.push_back(&physical_device); }
|
||||
PhysicalDeviceGroup& use_physical_device(PhysicalDevice const& physical_device) {
|
||||
physical_device_handles.push_back(&physical_device);
|
||||
return *this;
|
||||
|
||||
@@ -209,25 +209,73 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDevices(VkInstance instan
|
||||
// VK_SUCCESS,VK_INCOMPLETE, VK_ERROR_INITIALIZATION_FAILED
|
||||
VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDeviceGroups(
|
||||
VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
|
||||
VkResult result = VK_SUCCESS;
|
||||
|
||||
if (pPhysicalDeviceGroupProperties == nullptr) {
|
||||
*pPhysicalDeviceGroupCount = static_cast<uint32_t>(icd.physical_device_groups.size());
|
||||
} else {
|
||||
for (size_t device_group = 0; device_group < icd.physical_device_groups.size(); device_group++) {
|
||||
if (device_group >= *pPhysicalDeviceGroupCount) {
|
||||
return VK_INCOMPLETE;
|
||||
}
|
||||
pPhysicalDeviceGroupProperties[device_group].subsetAllocation =
|
||||
icd.physical_device_groups[device_group].subset_allocation;
|
||||
uint32_t handles_written = 0;
|
||||
for (size_t i = 0; i < icd.physical_device_groups[device_group].physical_device_handles.size(); i++) {
|
||||
handles_written++;
|
||||
pPhysicalDeviceGroupProperties[device_group].physicalDevices[i] =
|
||||
icd.physical_device_groups[device_group].physical_device_handles[i]->vk_physical_device.handle;
|
||||
}
|
||||
pPhysicalDeviceGroupProperties[device_group].physicalDeviceCount = handles_written;
|
||||
if (0 == icd.physical_device_groups.size()) {
|
||||
*pPhysicalDeviceGroupCount = static_cast<uint32_t>(icd.physical_devices.size());
|
||||
} else {
|
||||
*pPhysicalDeviceGroupCount = static_cast<uint32_t>(icd.physical_device_groups.size());
|
||||
}
|
||||
} else {
|
||||
// NOTE: This is a fake struct to make sure the pNext chain is properly passed down to the ICD
|
||||
// vkEnumeratePhysicalDeviceGroups.
|
||||
// The two versions must match:
|
||||
// "FakePNext" test in loader_regresion_tests.cpp
|
||||
// "test_vkEnumeratePhysicalDeviceGroups" in test_icd.cpp
|
||||
struct FakePnextSharedWithICD {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
uint32_t group_count = 0;
|
||||
if (0 == icd.physical_device_groups.size()) {
|
||||
group_count = icd.physical_devices.size();
|
||||
for (size_t device_group = 0; device_group < icd.physical_devices.size(); device_group++) {
|
||||
if (device_group >= *pPhysicalDeviceGroupCount) {
|
||||
group_count = *pPhysicalDeviceGroupCount;
|
||||
result = VK_INCOMPLETE;
|
||||
break;
|
||||
}
|
||||
pPhysicalDeviceGroupProperties[device_group].subsetAllocation = false;
|
||||
pPhysicalDeviceGroupProperties[device_group].physicalDeviceCount = 1;
|
||||
pPhysicalDeviceGroupProperties[device_group].physicalDevices[0] =
|
||||
icd.physical_devices[device_group].vk_physical_device.handle;
|
||||
}
|
||||
} else {
|
||||
group_count = icd.physical_device_groups.size();
|
||||
for (size_t device_group = 0; device_group < icd.physical_device_groups.size(); device_group++) {
|
||||
if (device_group >= *pPhysicalDeviceGroupCount) {
|
||||
group_count = *pPhysicalDeviceGroupCount;
|
||||
result = VK_INCOMPLETE;
|
||||
break;
|
||||
}
|
||||
pPhysicalDeviceGroupProperties[device_group].subsetAllocation =
|
||||
icd.physical_device_groups[device_group].subset_allocation;
|
||||
uint32_t handles_written = 0;
|
||||
for (size_t i = 0; i < icd.physical_device_groups[device_group].physical_device_handles.size(); i++) {
|
||||
handles_written++;
|
||||
pPhysicalDeviceGroupProperties[device_group].physicalDevices[i] =
|
||||
icd.physical_device_groups[device_group].physical_device_handles[i]->vk_physical_device.handle;
|
||||
}
|
||||
pPhysicalDeviceGroupProperties[device_group].physicalDeviceCount = handles_written;
|
||||
}
|
||||
}
|
||||
// NOTE: The following code is purely to test pNext passing in vkEnumeratePhysicalDevice groups
|
||||
// and includes normally invalid information.
|
||||
for (size_t device_group = 0; device_group < group_count; device_group++) {
|
||||
if (nullptr != pPhysicalDeviceGroupProperties[device_group].pNext) {
|
||||
VkBaseInStructure* base = reinterpret_cast<VkBaseInStructure*>(pPhysicalDeviceGroupProperties[device_group].pNext);
|
||||
if (base->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT) {
|
||||
FakePnextSharedWithICD* fake = reinterpret_cast<FakePnextSharedWithICD*>(base);
|
||||
fake->value = 0xDECAFBAD;
|
||||
}
|
||||
}
|
||||
}
|
||||
*pPhysicalDeviceGroupCount = static_cast<uint32_t>(group_count);
|
||||
}
|
||||
return VK_SUCCESS;
|
||||
return result;
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDebugUtilsMessengerEXT(VkInstance instance,
|
||||
@@ -962,6 +1010,9 @@ PFN_vkVoidFunction get_instance_func_ver_1_1(VkInstance instance, const char* pN
|
||||
if (string_eq(pName, "test_vkEnumerateInstanceVersion")) {
|
||||
return to_vkVoidFunction(test_vkEnumerateInstanceVersion);
|
||||
}
|
||||
if (string_eq(pName, "vkEnumeratePhysicalDeviceGroups")) {
|
||||
return to_vkVoidFunction(test_vkEnumeratePhysicalDeviceGroups);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1225,8 +1276,10 @@ PFN_vkVoidFunction get_instance_func(VkInstance instance, const char* pName) {
|
||||
if (string_eq(pName, "vkCreateInstance")) return to_vkVoidFunction(test_vkCreateInstance);
|
||||
if (string_eq(pName, "vkDestroyInstance")) return to_vkVoidFunction(test_vkDestroyInstance);
|
||||
if (string_eq(pName, "vkEnumeratePhysicalDevices")) return to_vkVoidFunction(test_vkEnumeratePhysicalDevices);
|
||||
if (string_eq(pName, "vkEnumeratePhysicalDeviceGroups") || string_eq(pName, "vkEnumeratePhysicalDeviceGroupsKHR"))
|
||||
return to_vkVoidFunction(test_vkEnumeratePhysicalDeviceGroups);
|
||||
|
||||
if (IsInstanceExtensionEnabled(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME)) {
|
||||
if (string_eq(pName, "vkEnumeratePhysicalDeviceGroupsKHR")) return to_vkVoidFunction(test_vkEnumeratePhysicalDeviceGroups);
|
||||
}
|
||||
|
||||
PFN_vkVoidFunction ret_phys_dev = get_physical_device_func(instance, pName);
|
||||
if (ret_phys_dev != nullptr) return ret_phys_dev;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The Khronos Group Inc.
|
||||
* Copyright (c) 2021 Valve Corporation
|
||||
* Copyright (c) 2021 LunarG, Inc.
|
||||
* Copyright (c) 2021-2022 The Khronos Group Inc.
|
||||
* Copyright (c) 2021-2022 Valve Corporation
|
||||
* Copyright (c) 2021-2022 LunarG, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and/or associated documentation files (the "Materials"), to
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# ~~~
|
||||
# Copyright (c) 2021 Valve Corporation
|
||||
# Copyright (c) 2021 LunarG, Inc.
|
||||
# Copyright (c) 2021-2022 Valve Corporation
|
||||
# Copyright (c) 2021-2022 LunarG, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -27,6 +27,7 @@ target_compile_definitions(test_layer_deps INTERFACE
|
||||
|
||||
target_link_libraries(test_layer_deps INTERFACE testing_framework_util)
|
||||
|
||||
# Interface testing layer
|
||||
set(TEST_LAYER_SOURCES test_layer.cpp test_layer.h)
|
||||
|
||||
set(TEST_LAYER_BASE_EXPORTS TEST_LAYER_EXPORT_ENUMERATE_FUNCTIONS=1)
|
||||
@@ -53,6 +54,48 @@ target_link_libraries(test_layer_export_version_2 PRIVATE test_layer_deps)
|
||||
target_compile_definitions(test_layer_export_version_2 PRIVATE
|
||||
${TEST_LAYER_VERSION_0_EXPORTS} ${TEST_LAYER_VERSION_1_EXPORTS} ${TEST_LAYER_VERSION_2_EXPORTS} )
|
||||
|
||||
# Physical device list altering layer (add phys dev, remove phys dev, re-order phys devs)
|
||||
set(PHYSDEV_LAYER_ADD_EXPORTS
|
||||
${TEST_LAYER_VERSION_0_EXPORTS} ${TEST_LAYER_VERSION_1_EXPORTS} ${TEST_LAYER_VERSION_2_EXPORTS}
|
||||
TEST_LAYER_NAME="VkLayer_LunarG_add_phys_dev"
|
||||
TEST_PHYSDEV_LAYER_ADD=1
|
||||
)
|
||||
set(PHYSDEV_REMOVE_EXPORTS
|
||||
${TEST_LAYER_VERSION_0_EXPORTS} ${TEST_LAYER_VERSION_1_EXPORTS} ${TEST_LAYER_VERSION_2_EXPORTS}
|
||||
TEST_LAYER_NAME="VkLayer_LunarG_remove_phys_dev"
|
||||
TEST_PHYSDEV_LAYER_REMOVE=1
|
||||
)
|
||||
set(PHYSDEV_LAYER_REORDER_EXPORTS
|
||||
${TEST_LAYER_VERSION_0_EXPORTS} ${TEST_LAYER_VERSION_1_EXPORTS} ${TEST_LAYER_VERSION_2_EXPORTS}
|
||||
TEST_LAYER_NAME="VkLayer_LunarG_reorder_phys_dev"
|
||||
TEST_PHYSDEV_LAYER_REORDER=1
|
||||
)
|
||||
set(PHYSDEV_LAYER_ALL_EXPORTS
|
||||
${TEST_LAYER_VERSION_0_EXPORTS} ${TEST_LAYER_VERSION_1_EXPORTS} ${TEST_LAYER_VERSION_2_EXPORTS}
|
||||
TEST_LAYER_NAME="VkLayer_LunarG_all_phys_dev"
|
||||
TEST_PHYSDEV_LAYER_ADD=1
|
||||
TEST_PHYSDEV_LAYER_REMOVE=1
|
||||
TEST_PHYSDEV_LAYER_REORDER=1
|
||||
)
|
||||
|
||||
add_library(test_layer_physdev_add SHARED ${TEST_LAYER_SOURCES})
|
||||
target_link_libraries(test_layer_physdev_add PRIVATE test_layer_deps)
|
||||
target_compile_definitions(test_layer_physdev_add PRIVATE ${PHYSDEV_LAYER_ADD_EXPORTS})
|
||||
|
||||
add_library(test_layer_physdev_remove SHARED ${TEST_LAYER_SOURCES})
|
||||
target_link_libraries(test_layer_physdev_remove PRIVATE test_layer_deps)
|
||||
target_compile_definitions(test_layer_physdev_remove PRIVATE ${PHYSDEV_REMOVE_EXPORTS})
|
||||
|
||||
add_library(test_layer_physdev_reorder SHARED ${TEST_LAYER_SOURCES})
|
||||
target_link_libraries(test_layer_physdev_reorder PRIVATE test_layer_deps)
|
||||
target_compile_definitions(test_layer_physdev_reorder PRIVATE ${PHYSDEV_LAYER_REORDER_EXPORTS})
|
||||
|
||||
add_library(test_layer_physdev_all SHARED ${TEST_LAYER_SOURCES})
|
||||
target_link_libraries(test_layer_physdev_all PRIVATE test_layer_deps)
|
||||
target_compile_definitions(test_layer_physdev_all PRIVATE ${PHYSDEV_LAYER_ALL_EXPORTS})
|
||||
|
||||
# Wrap Objects layer which wraps dispatchable handles to test that the loader will properly
|
||||
# work in the case where handles in the terminator don't match handles in the trampoline portion.
|
||||
set(WRAP_LAYER_VERSION_1_EXPORTS
|
||||
TEST_LAYER_EXPORT_DIRECT_DISP=1
|
||||
TEST_LAYER_EXPORT_MAINT_1=1
|
||||
@@ -83,11 +126,16 @@ add_library(test_layer_wrap_objects_3 SHARED wrap_objects)
|
||||
target_link_libraries(test_layer_wrap_objects_3 PRIVATE test_layer_deps)
|
||||
target_compile_definitions(test_layer_wrap_objects_3 PRIVATE ${WRAP_LAYER_VERSION_3_EXPORTS})
|
||||
|
||||
# Windows requires export definitions for these layers
|
||||
if(WIN32)
|
||||
target_sources(test_layer_export_base PRIVATE export_definitions/test_layer_base.def)
|
||||
target_sources(test_layer_export_version_0 PRIVATE export_definitions/test_layer_0.def)
|
||||
target_sources(test_layer_export_version_1 PRIVATE export_definitions/test_layer_1.def)
|
||||
target_sources(test_layer_export_version_2 PRIVATE export_definitions/test_layer_2.def)
|
||||
target_sources(test_layer_physdev_add PRIVATE export_definitions/test_layer_2.def)
|
||||
target_sources(test_layer_physdev_remove PRIVATE export_definitions/test_layer_2.def)
|
||||
target_sources(test_layer_physdev_reorder PRIVATE export_definitions/test_layer_2.def)
|
||||
target_sources(test_layer_physdev_all PRIVATE export_definitions/test_layer_2.def)
|
||||
target_sources(test_layer_wrap_objects PRIVATE export_definitions/test_layer_wrap_objects.def)
|
||||
target_sources(test_layer_wrap_objects_1 PRIVATE export_definitions/test_layer_wrap_objects.def)
|
||||
target_sources(test_layer_wrap_objects_2 PRIVATE export_definitions/test_layer_wrap_objects.def)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The Khronos Group Inc.
|
||||
* Copyright (c) 2021 Valve Corporation
|
||||
* Copyright (c) 2021 LunarG, Inc.
|
||||
* Copyright (c) 2021-2022 The Khronos Group Inc.
|
||||
* Copyright (c) 2021-2022 Valve Corporation
|
||||
* Copyright (c) 2021-2022 LunarG, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and/or associated documentation files (the "Materials"), to
|
||||
@@ -74,6 +74,10 @@
|
||||
#define LAYER_EXPORT_NEGOTIATE_LOADER_LAYER_INTERFACE_VERSION 0
|
||||
#endif
|
||||
|
||||
#ifndef TEST_LAYER_NAME
|
||||
#define TEST_LAYER_NAME "VkLayer_LunarG_test_layer"
|
||||
#endif
|
||||
|
||||
TestLayer layer;
|
||||
extern "C" {
|
||||
FRAMEWORK_EXPORT TestLayer* get_test_layer_func() { return &layer; }
|
||||
@@ -107,7 +111,7 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceLayerProperties(uint32_t*
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateInstanceExtensionProperties(const char* pLayerName, uint32_t* pPropertyCount,
|
||||
VkExtensionProperties* pProperties) {
|
||||
if (pLayerName && string_eq(pLayerName, layer.unique_name.c_str())) {
|
||||
if (pLayerName && string_eq(pLayerName, TEST_LAYER_NAME)) {
|
||||
*pPropertyCount = 0;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
@@ -122,7 +126,7 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceLayerProperties(VkPhysicalD
|
||||
VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char* pLayerName,
|
||||
uint32_t* pPropertyCount,
|
||||
VkExtensionProperties* pProperties) {
|
||||
if (pLayerName && string_eq(pLayerName, layer.unique_name.c_str())) {
|
||||
if (pLayerName && string_eq(pLayerName, TEST_LAYER_NAME)) {
|
||||
*pPropertyCount = 0;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
@@ -171,7 +175,7 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateInstance(const VkInstanceCreateInfo*
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL test_override_vkCreateInstance(const VkInstanceCreateInfo* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) {
|
||||
const VkAllocationCallbacks* pAllocator, VkInstance* pInstance) {
|
||||
return VK_ERROR_INVALID_SHADER_NV;
|
||||
}
|
||||
|
||||
@@ -214,6 +218,195 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkCreateDevice(VkPhysicalDevice physicalDevi
|
||||
return result;
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount,
|
||||
VkPhysicalDevice* pPhysicalDevices) {
|
||||
#if !TEST_PHYSDEV_LAYER_REMOVE && !TEST_PHYSDEV_LAYER_ADD && !TEST_PHYSDEV_LAYER_REORDER
|
||||
return layer.instance_dispatch_table.EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
|
||||
#else // TEST_PHYSDEV_LAYER_REMOVE || TEST_PHYSDEV_LAYER_ADD || TEST_PHYSDEV_LAYER_REORDER
|
||||
VkResult res = VK_SUCCESS;
|
||||
|
||||
if (layer.complete_physical_devices.size() == 0) {
|
||||
// Get list of all physical devices from lower down
|
||||
// NOTE: This only works if we don't test changing the number of devices
|
||||
// underneath us when using this test.
|
||||
uint32_t icd_count = 0;
|
||||
layer.instance_dispatch_table.EnumeratePhysicalDevices(instance, &icd_count, nullptr);
|
||||
std::vector<VkPhysicalDevice> tmp_vector;
|
||||
tmp_vector.resize(icd_count);
|
||||
layer.instance_dispatch_table.EnumeratePhysicalDevices(instance, &icd_count, tmp_vector.data());
|
||||
layer.complete_physical_devices.clear();
|
||||
|
||||
#if TEST_PHYSDEV_LAYER_REMOVE
|
||||
// Erase the 3rd and 4th items
|
||||
layer.removed_physical_devices.push_back(tmp_vector[3]);
|
||||
layer.removed_physical_devices.push_back(tmp_vector[4]);
|
||||
tmp_vector.erase(tmp_vector.begin() + 3);
|
||||
tmp_vector.erase(tmp_vector.begin() + 3);
|
||||
#endif // TEST_PHYSDEV_LAYER_REMOVE
|
||||
|
||||
#if TEST_PHYSDEV_LAYER_ADD
|
||||
// Insert a new device in the beginning, middle, and end
|
||||
uint32_t middle = tmp_vector.size() / 2;
|
||||
VkPhysicalDevice new_phys_dev = reinterpret_cast<VkPhysicalDevice>((size_t)(0xABCD0000));
|
||||
layer.added_physical_devices.push_back(new_phys_dev);
|
||||
tmp_vector.insert(tmp_vector.begin(), new_phys_dev);
|
||||
new_phys_dev = reinterpret_cast<VkPhysicalDevice>((size_t)(0xBADC0000));
|
||||
layer.added_physical_devices.push_back(new_phys_dev);
|
||||
tmp_vector.insert(tmp_vector.begin() + middle, new_phys_dev);
|
||||
new_phys_dev = reinterpret_cast<VkPhysicalDevice>((size_t)(0xDCBA0000));
|
||||
layer.added_physical_devices.push_back(new_phys_dev);
|
||||
tmp_vector.push_back(new_phys_dev);
|
||||
#endif // TEST_PHYSDEV_LAYER_ADD
|
||||
|
||||
#if TEST_PHYSDEV_LAYER_REORDER
|
||||
// Flip the order of items
|
||||
for (int32_t dev = tmp_vector.size() - 1; dev >= 0; --dev) {
|
||||
layer.complete_physical_devices.push_back(tmp_vector[dev]);
|
||||
}
|
||||
#else // !TEST_PHYSDEV_LAYER_REORDER
|
||||
// Otherwise, keep the order the same
|
||||
for (uint32_t dev = 0; dev < tmp_vector.size(); ++dev) {
|
||||
layer.complete_physical_devices.push_back(tmp_vector[dev]);
|
||||
}
|
||||
#endif // !TEST_PHYSDEV_LAYER_REORDER
|
||||
}
|
||||
|
||||
if (nullptr == pPhysicalDevices) {
|
||||
*pPhysicalDeviceCount = layer.complete_physical_devices.size();
|
||||
} else {
|
||||
uint32_t adj_count = layer.complete_physical_devices.size();
|
||||
if (*pPhysicalDeviceCount < adj_count) {
|
||||
adj_count = *pPhysicalDeviceCount;
|
||||
res = VK_INCOMPLETE;
|
||||
}
|
||||
for (uint32_t dev = 0; dev < adj_count; ++dev) {
|
||||
pPhysicalDevices[dev] = layer.complete_physical_devices[dev];
|
||||
}
|
||||
*pPhysicalDeviceCount = adj_count;
|
||||
}
|
||||
|
||||
return res;
|
||||
#endif // TEST_PHYSDEV_LAYER_REMOVE || TEST_PHYSDEV_LAYER_ADD || TEST_PHYSDEV_LAYER_REORDER
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL test_vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
|
||||
VkPhysicalDeviceProperties* pProperties) {
|
||||
#if TEST_PHYSDEV_LAYER_REMOVE || TEST_PHYSDEV_LAYER_ADD || TEST_PHYSDEV_LAYER_REORDER
|
||||
if (std::find(layer.removed_physical_devices.begin(), layer.removed_physical_devices.end(), physicalDevice) !=
|
||||
layer.removed_physical_devices.end()) {
|
||||
// Should not get here since the application should not know about those devices
|
||||
assert(false);
|
||||
} else if (std::find(layer.added_physical_devices.begin(), layer.added_physical_devices.end(), physicalDevice) !=
|
||||
layer.added_physical_devices.end()) {
|
||||
// Added device so put in some placeholder info we can test against
|
||||
pProperties->apiVersion = VK_API_VERSION_1_2;
|
||||
pProperties->driverVersion = VK_MAKE_API_VERSION(0, 12, 14, 196);
|
||||
pProperties->vendorID = 0xDECAFBAD;
|
||||
pProperties->deviceID = 0xDEADBADD;
|
||||
#if defined(_WIN32)
|
||||
strncpy_s(pProperties->deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, "physdev_added_xx", 17);
|
||||
#else
|
||||
strncpy(pProperties->deviceName, "physdev_added_xx", VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
|
||||
#endif
|
||||
} else {
|
||||
#else // !TEST_PHYSDEV_LAYER_REMOVE && !TEST_PHYSDEV_LAYER_ADD && !TEST_PHYSDEV_LAYER_REORDER
|
||||
{
|
||||
#endif
|
||||
// Not an affected device so just return
|
||||
layer.instance_dispatch_table.GetPhysicalDeviceProperties(physicalDevice, pProperties);
|
||||
}
|
||||
}
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDeviceGroups(
|
||||
VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
|
||||
#if !TEST_PHYSDEV_LAYER_REMOVE && !TEST_PHYSDEV_LAYER_ADD && !TEST_PHYSDEV_LAYER_REORDER
|
||||
return layer.instance_dispatch_table.EnumeratePhysicalDeviceGroups(instance, pPhysicalDeviceGroupCount,
|
||||
pPhysicalDeviceGroupProperties);
|
||||
#else // TEST_PHYSDEV_LAYER_REMOVE || TEST_PHYSDEV_LAYER_ADD || TEST_PHYSDEV_LAYER_REORDER
|
||||
VkResult res = VK_SUCCESS;
|
||||
|
||||
if (layer.complete_physical_device_groups.size() == 0) {
|
||||
uint32_t fake_count = 1000;
|
||||
// Call EnumerateDevices to add remove devices as needed
|
||||
test_vkEnumeratePhysicalDevices(instance, &fake_count, nullptr);
|
||||
|
||||
// Get list of all physical devices from lower down
|
||||
// NOTE: This only works if we don't test changing the number of devices
|
||||
// underneath us when using this test.
|
||||
uint32_t icd_group_count = 0;
|
||||
layer.instance_dispatch_table.EnumeratePhysicalDeviceGroups(instance, &icd_group_count, nullptr);
|
||||
std::vector<VkPhysicalDeviceGroupProperties> tmp_vector(icd_group_count);
|
||||
for (uint32_t group = 0; group < icd_group_count; ++group) {
|
||||
tmp_vector[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
|
||||
}
|
||||
layer.instance_dispatch_table.EnumeratePhysicalDeviceGroups(instance, &icd_group_count, tmp_vector.data());
|
||||
layer.complete_physical_device_groups.clear();
|
||||
|
||||
#if TEST_PHYSDEV_LAYER_REMOVE
|
||||
// Now, if a device has been removed, and it was the only group, we need to remove the group as well.
|
||||
for (uint32_t rem_dev = 0; rem_dev < layer.removed_physical_devices.size(); ++rem_dev) {
|
||||
for (uint32_t group = 0; group < icd_group_count; ++group) {
|
||||
for (uint32_t grp_dev = 0; grp_dev < tmp_vector[group].physicalDeviceCount; ++grp_dev) {
|
||||
if (tmp_vector[group].physicalDevices[grp_dev] == layer.removed_physical_devices[rem_dev]) {
|
||||
for (uint32_t cp_item = grp_dev + 1; cp_item < tmp_vector[group].physicalDeviceCount; ++cp_item) {
|
||||
tmp_vector[group].physicalDevices[grp_dev] = tmp_vector[group].physicalDevices[cp_item];
|
||||
}
|
||||
tmp_vector[group].physicalDeviceCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (uint32_t group = 0; group < tmp_vector.size(); ++group) {
|
||||
if (tmp_vector[group].physicalDeviceCount == 0) {
|
||||
layer.removed_physical_device_groups.push_back(tmp_vector[group]);
|
||||
tmp_vector.erase(tmp_vector.begin() + group);
|
||||
--group;
|
||||
}
|
||||
}
|
||||
#endif // TEST_PHYSDEV_LAYER_REMOVE
|
||||
|
||||
#if TEST_PHYSDEV_LAYER_ADD
|
||||
// Add a new group for each physical device not associated with a current group
|
||||
for (uint32_t dev = 0; dev < layer.added_physical_devices.size(); ++dev) {
|
||||
VkPhysicalDeviceGroupProperties props{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES};
|
||||
props.physicalDeviceCount = 1;
|
||||
props.physicalDevices[0] = layer.added_physical_devices[dev];
|
||||
tmp_vector.push_back(props);
|
||||
layer.added_physical_device_groups.push_back(props);
|
||||
}
|
||||
#endif // TEST_PHYSDEV_LAYER_ADD
|
||||
|
||||
#if TEST_PHYSDEV_LAYER_REORDER
|
||||
// Flip the order of items
|
||||
for (int32_t dev = tmp_vector.size() - 1; dev >= 0; --dev) {
|
||||
layer.complete_physical_device_groups.push_back(tmp_vector[dev]);
|
||||
}
|
||||
#else // !TEST_PHYSDEV_LAYER_REORDER
|
||||
// Otherwise, keep the order the same
|
||||
for (uint32_t dev = 0; dev < tmp_vector.size(); ++dev) {
|
||||
layer.complete_physical_device_groups.push_back(tmp_vector[dev]);
|
||||
}
|
||||
#endif // !TEST_PHYSDEV_LAYER_REORDER
|
||||
}
|
||||
|
||||
if (nullptr == pPhysicalDeviceGroupProperties) {
|
||||
*pPhysicalDeviceGroupCount = layer.complete_physical_device_groups.size();
|
||||
} else {
|
||||
uint32_t adj_count = layer.complete_physical_device_groups.size();
|
||||
if (*pPhysicalDeviceGroupCount < adj_count) {
|
||||
adj_count = *pPhysicalDeviceGroupCount;
|
||||
res = VK_INCOMPLETE;
|
||||
}
|
||||
for (uint32_t dev = 0; dev < adj_count; ++dev) {
|
||||
pPhysicalDeviceGroupProperties[dev] = layer.complete_physical_device_groups[dev];
|
||||
}
|
||||
*pPhysicalDeviceGroupCount = adj_count;
|
||||
}
|
||||
|
||||
return res;
|
||||
#endif // TEST_PHYSDEV_LAYER_REMOVE || TEST_PHYSDEV_LAYER_ADD || TEST_PHYSDEV_LAYER_REORDER
|
||||
}
|
||||
|
||||
// device functions
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL test_vkDestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator) {
|
||||
@@ -244,6 +437,9 @@ VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL get_instance_func(VkInstance instance,
|
||||
if (string_eq(pName, "vkEnumerateDeviceLayerProperties")) return to_vkVoidFunction(test_vkEnumerateDeviceLayerProperties);
|
||||
if (string_eq(pName, "vkEnumerateDeviceExtensionProperties"))
|
||||
return to_vkVoidFunction(test_vkEnumerateDeviceExtensionProperties);
|
||||
if (string_eq(pName, "vkEnumeratePhysicalDevices")) return to_vkVoidFunction(test_vkEnumeratePhysicalDevices);
|
||||
if (string_eq(pName, "vkEnumeratePhysicalDeviceGroups")) return to_vkVoidFunction(test_vkEnumeratePhysicalDeviceGroups);
|
||||
if (string_eq(pName, "vkGetPhysicalDeviceProperties")) return to_vkVoidFunction(test_vkGetPhysicalDeviceProperties);
|
||||
if (string_eq(pName, "vkCreateInstance")) return to_vkVoidFunction(test_vkCreateInstance);
|
||||
if (string_eq(pName, "vkDestroyInstance")) return to_vkVoidFunction(test_vkDestroyInstance);
|
||||
if (string_eq(pName, "vkCreateDevice")) return to_vkVoidFunction(test_vkCreateDevice);
|
||||
@@ -326,13 +522,27 @@ FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProper
|
||||
VkExtensionProperties* pProperties) {
|
||||
return test_vkEnumerateDeviceExtensionProperties(physicalDevice, pLayerName, pPropertyCount, pProperties);
|
||||
}
|
||||
FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount,
|
||||
VkPhysicalDevice* pPhysicalDevices) {
|
||||
return test_vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
|
||||
}
|
||||
FRAMEWORK_EXPORT VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
|
||||
VkPhysicalDeviceProperties* pProperties) {
|
||||
return test_vkGetPhysicalDeviceProperties(physicalDevice, pProperties);
|
||||
}
|
||||
FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups(
|
||||
VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) {
|
||||
return test_vkEnumeratePhysicalDeviceGroups(instance, pPhysicalDeviceGroupCount, pPhysicalDeviceGroupProperties);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TEST_LAYER_EXPORT_LAYER_NAMED_GIPA
|
||||
FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_layer_GetInstanceProcAddr(VkInstance instance, const char* pName) {
|
||||
return get_instance_func(instance, pName);
|
||||
}
|
||||
FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_override_vkGetInstanceProcAddr(VkInstance instance, const char* pName) {
|
||||
FRAMEWORK_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL test_override_vkGetInstanceProcAddr(VkInstance instance,
|
||||
const char* pName) {
|
||||
if (string_eq(pName, "vkCreateInstance")) return to_vkVoidFunction(test_override_vkCreateInstance);
|
||||
return get_instance_func(instance, pName);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The Khronos Group Inc.
|
||||
* Copyright (c) 2021 Valve Corporation
|
||||
* Copyright (c) 2021 LunarG, Inc.
|
||||
* Copyright (c) 2021-2022 The Khronos Group Inc.
|
||||
* Copyright (c) 2021-2022 Valve Corporation
|
||||
* Copyright (c) 2021-2022 LunarG, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and/or associated documentation files (the "Materials"), to
|
||||
@@ -80,6 +80,21 @@ Interface Version 2
|
||||
|
||||
// Added manifest version 1.1.0
|
||||
|
||||
// vkEnumeratePhysicalDevices and vkEnumeratePhysicalDeviceGroups add a new item
|
||||
#ifndef TEST_PHYSDEV_LAYER_ADD
|
||||
#define TEST_PHYSDEV_LAYER_ADD 0
|
||||
#endif
|
||||
|
||||
// vkEnumeratePhysicalDevices and vkEnumeratePhysicalDeviceGroups remove an item
|
||||
#ifndef TEST_PHYSDEV_LAYER_REMOVE
|
||||
#define TEST_PHYSDEV_LAYER_REMOVE 0
|
||||
#endif
|
||||
|
||||
// vkEnumeratePhysicalDevices and vkEnumeratePhysicalDeviceGroups reorders items
|
||||
#ifndef TEST_PHYSDEV_LAYER_REORDER
|
||||
#define TEST_PHYSDEV_LAYER_REORDER 0
|
||||
#endif
|
||||
|
||||
struct TestLayer;
|
||||
|
||||
// Callbacks allow tests to implement custom functionality without modifying the layer binary
|
||||
@@ -94,7 +109,6 @@ struct TestLayer {
|
||||
|
||||
BUILDER_VALUE(TestLayer, bool, is_meta_layer, false)
|
||||
|
||||
BUILDER_VALUE(TestLayer, std::string, unique_name, {})
|
||||
BUILDER_VALUE(TestLayer, uint32_t, api_version, VK_API_VERSION_1_0)
|
||||
BUILDER_VALUE(TestLayer, uint32_t, reported_layer_props, 1)
|
||||
BUILDER_VALUE(TestLayer, uint32_t, reported_extension_props, 1)
|
||||
@@ -119,6 +133,14 @@ struct TestLayer {
|
||||
BUILDER_VALUE(TestLayer, std::function<VkResult(TestLayer& layer)>, create_instance_callback, {})
|
||||
// Called in vkCreateDevice after calling down the chain & returning
|
||||
BUILDER_VALUE(TestLayer, std::function<VkResult(TestLayer& layer)>, create_device_callback, {})
|
||||
#if TEST_PHYSDEV_LAYER_REMOVE || TEST_PHYSDEV_LAYER_ADD || TEST_PHYSDEV_LAYER_REORDER
|
||||
BUILDER_VECTOR(TestLayer, VkPhysicalDevice, complete_physical_devices, complete_physical_device)
|
||||
BUILDER_VECTOR(TestLayer, VkPhysicalDevice, removed_physical_devices, removed_physical_device)
|
||||
BUILDER_VECTOR(TestLayer, VkPhysicalDevice, added_physical_devices, added_physical_device)
|
||||
BUILDER_VECTOR(TestLayer, VkPhysicalDeviceGroupProperties, complete_physical_device_groups, complete_physical_device_group)
|
||||
BUILDER_VECTOR(TestLayer, VkPhysicalDeviceGroupProperties, removed_physical_device_groups, removed_physical_device_group)
|
||||
BUILDER_VECTOR(TestLayer, VkPhysicalDeviceGroupProperties, added_physical_device_groups, added_physical_device_group)
|
||||
#endif // TEST_PHYSDEV_LAYER_REMOVE || TEST_PHYSDEV_LAYER_ADD || TEST_PHYSDEV_LAYER_REORDER
|
||||
|
||||
PFN_vkGetInstanceProcAddr next_vkGetInstanceProcAddr = VK_NULL_HANDLE;
|
||||
PFN_GetPhysicalDeviceProcAddr next_GetPhysicalDeviceProcAddr = VK_NULL_HANDLE;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2021 Valve Corporation
|
||||
* Copyright (c) 2015-2021 LunarG, Inc.
|
||||
* Copyright (c) 2015-2022 Valve Corporation
|
||||
* Copyright (c) 2015-2022 LunarG, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -425,14 +425,25 @@ VKAPI_ATTR VkResult VKAPI_CALL wrap_vkEnumerateDeviceExtensionProperties(VkPhysi
|
||||
ext_count = 0;
|
||||
#if TEST_LAYER_EXPORT_MAINT_1
|
||||
if (ext_count < count) {
|
||||
#if defined(_WIN32)
|
||||
strncpy_s(pProperties[ext_count].extensionName, VK_MAX_EXTENSION_NAME_SIZE, VK_KHR_MAINTENANCE1_EXTENSION_NAME,
|
||||
strlen(VK_KHR_MAINTENANCE1_EXTENSION_NAME) + 1);
|
||||
#else
|
||||
strcpy(pProperties[ext_count].extensionName, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
|
||||
#endif
|
||||
pProperties[ext_count].specVersion = 2;
|
||||
ext_count++;
|
||||
}
|
||||
#endif
|
||||
#if TEST_LAYER_EXPORT_PRESENT_IMAGE
|
||||
if (ext_count < count) {
|
||||
#if defined(_WIN32)
|
||||
strncpy_s(pProperties[ext_count].extensionName, VK_MAX_EXTENSION_NAME_SIZE,
|
||||
VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME,
|
||||
strlen(VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME) + 1);
|
||||
#else
|
||||
strcpy(pProperties[ext_count].extensionName, VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME);
|
||||
#endif
|
||||
pProperties[ext_count].specVersion = 1;
|
||||
ext_count++;
|
||||
}
|
||||
|
||||
@@ -782,7 +782,7 @@ TEST_F(SeparateMessenger, InfoInEnumDevsIgnoredSeverity) {
|
||||
}
|
||||
|
||||
// Test debug utils created outside of vkCreateInstance with info in vkEnumeratePhysicalDevices.
|
||||
TEST_F(SeparateMessenger, DebugUtilsInfoInEnumDevs) {
|
||||
TEST_F(SeparateMessenger, InfoInEnumDevs) {
|
||||
expected_message = "Trimming device count down by application request";
|
||||
expected_object_type = VK_OBJECT_TYPE_INSTANCE;
|
||||
expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The Khronos Group Inc.
|
||||
* Copyright (c) 2021 Valve Corporation
|
||||
* Copyright (c) 2021 LunarG, Inc.
|
||||
* Copyright (c) 2021-2022 The Khronos Group Inc.
|
||||
* Copyright (c) 2021-2022 Valve Corporation
|
||||
* Copyright (c) 2021-2022 LunarG, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and/or associated documentation files (the "Materials"), to
|
||||
@@ -45,6 +45,7 @@ class LayerExtensions : public LayerTests {};
|
||||
class MetaLayers : public LayerTests {};
|
||||
class OverrideMetaLayer : public LayerTests {};
|
||||
class LayerCreateInstance : public LayerTests {};
|
||||
class LayerPhysDeviceMod : public LayerTests {};
|
||||
|
||||
void CheckLogForLayerString(FrameworkEnvironment& env, const char* implicit_layer_name, bool check_for_enable) {
|
||||
{
|
||||
@@ -2776,3 +2777,544 @@ TEST(TestLayers, DeviceLayerNotPresent) {
|
||||
dev.create_info.add_layer(explicit_layer_name);
|
||||
dev.CheckCreate(phys_dev);
|
||||
}
|
||||
|
||||
TEST_F(LayerPhysDeviceMod, AddPhysicalDevices) {
|
||||
FrameworkEnvironment env;
|
||||
env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
|
||||
.set_name("VkLayer_LunarG_add_phys_dev")
|
||||
.set_lib_path(TEST_LAYER_PHYSDEV_ADD)
|
||||
.set_api_version(VK_API_VERSION_1_1)
|
||||
.set_disable_environment("TEST_DISABLE_ADD_PHYS_DEV")),
|
||||
"test_layer_remove.json");
|
||||
|
||||
for (uint32_t icd = 0; icd < 2; ++icd) {
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
|
||||
auto& cur_icd = env.get_test_icd(icd);
|
||||
cur_icd.icd_api_version = VK_API_VERSION_1_2;
|
||||
VkPhysicalDeviceProperties properties{};
|
||||
properties.apiVersion = VK_API_VERSION_1_2;
|
||||
properties.vendorID = 0x11000000 + (icd << 6);
|
||||
char vendor_char = 'a' + icd;
|
||||
for (uint32_t dev = 0; dev < 3; ++dev) {
|
||||
properties.deviceID = properties.vendorID + dev;
|
||||
properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
|
||||
char dev_char = '0' + dev;
|
||||
std::string dev_name = "physdev_";
|
||||
dev_name += vendor_char;
|
||||
dev_name += "_";
|
||||
dev_name += dev_char;
|
||||
#if defined(_WIN32)
|
||||
strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1);
|
||||
#else
|
||||
strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
|
||||
#endif
|
||||
cur_icd.add_physical_device({});
|
||||
cur_icd.physical_devices.back().set_properties(properties);
|
||||
}
|
||||
cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
|
||||
cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
|
||||
cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
|
||||
}
|
||||
const uint32_t icd_devices = 6;
|
||||
|
||||
InstWrapper inst{env.vulkan_functions};
|
||||
inst.create_info.set_api_version(VK_API_VERSION_1_1);
|
||||
inst.CheckCreate();
|
||||
|
||||
uint32_t dev_count = 0;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &dev_count, nullptr));
|
||||
ASSERT_GT(dev_count, icd_devices);
|
||||
|
||||
auto not_exp_physical_devices = std::vector<VkPhysicalDevice>(icd_devices);
|
||||
uint32_t returned_phys_dev_count = icd_devices;
|
||||
ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, not_exp_physical_devices.data()));
|
||||
ASSERT_EQ(icd_devices, returned_phys_dev_count);
|
||||
|
||||
auto physical_devices = std::vector<VkPhysicalDevice>(dev_count);
|
||||
returned_phys_dev_count = dev_count;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, physical_devices.data()));
|
||||
ASSERT_EQ(dev_count, returned_phys_dev_count);
|
||||
|
||||
uint32_t diff_count = dev_count - icd_devices;
|
||||
uint32_t found_incomplete = 0;
|
||||
uint32_t found_added_count = 0;
|
||||
for (uint32_t dev = 0; dev < dev_count; ++dev) {
|
||||
VkPhysicalDeviceProperties props{};
|
||||
inst->vkGetPhysicalDeviceProperties(physical_devices[dev], &props);
|
||||
if (string_eq(props.deviceName, "physdev_added_xx")) {
|
||||
found_added_count++;
|
||||
}
|
||||
for (uint32_t incomp = 0; incomp < icd_devices; ++incomp) {
|
||||
if (not_exp_physical_devices[incomp] == physical_devices[dev]) {
|
||||
found_incomplete++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We should have added the number of diff items, and the incomplete count should match the number of
|
||||
// original physical devices.
|
||||
ASSERT_EQ(found_added_count, diff_count);
|
||||
ASSERT_EQ(found_incomplete, icd_devices);
|
||||
}
|
||||
|
||||
TEST_F(LayerPhysDeviceMod, RemovePhysicalDevices) {
|
||||
FrameworkEnvironment env;
|
||||
env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
|
||||
.set_name("VkLayer_LunarG_remove_phys_dev")
|
||||
.set_lib_path(TEST_LAYER_PHYSDEV_REMOVE)
|
||||
.set_api_version(VK_API_VERSION_1_1)
|
||||
.set_disable_environment("TEST_DISABLE_REMOVE_PHYS_DEV")),
|
||||
"test_layer_remove.json");
|
||||
|
||||
for (uint32_t icd = 0; icd < 2; ++icd) {
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
|
||||
auto& cur_icd = env.get_test_icd(icd);
|
||||
cur_icd.icd_api_version = VK_API_VERSION_1_2;
|
||||
VkPhysicalDeviceProperties properties{};
|
||||
properties.apiVersion = VK_API_VERSION_1_2;
|
||||
properties.vendorID = 0x11000000 + (icd << 6);
|
||||
char vendor_char = 'a' + icd;
|
||||
for (uint32_t dev = 0; dev < 3; ++dev) {
|
||||
properties.deviceID = properties.vendorID + dev;
|
||||
properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
|
||||
char dev_char = '0' + dev;
|
||||
std::string dev_name = "physdev_";
|
||||
dev_name += vendor_char;
|
||||
dev_name += "_";
|
||||
dev_name += dev_char;
|
||||
#if defined(_WIN32)
|
||||
strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1);
|
||||
#else
|
||||
strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
|
||||
#endif
|
||||
cur_icd.add_physical_device({});
|
||||
cur_icd.physical_devices.back().set_properties(properties);
|
||||
}
|
||||
cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
|
||||
cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
|
||||
cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
|
||||
}
|
||||
const uint32_t icd_devices = 6;
|
||||
|
||||
InstWrapper inst{env.vulkan_functions};
|
||||
inst.create_info.set_api_version(VK_API_VERSION_1_1);
|
||||
inst.CheckCreate();
|
||||
|
||||
uint32_t dev_count = 0;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &dev_count, nullptr));
|
||||
ASSERT_LT(dev_count, icd_devices);
|
||||
|
||||
auto physical_devices = std::vector<VkPhysicalDevice>(dev_count);
|
||||
uint32_t returned_phys_dev_count = dev_count;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, physical_devices.data()));
|
||||
ASSERT_EQ(dev_count, returned_phys_dev_count);
|
||||
}
|
||||
|
||||
TEST_F(LayerPhysDeviceMod, ReorderPhysicalDevices) {
|
||||
FrameworkEnvironment env;
|
||||
env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
|
||||
.set_name("VkLayer_LunarG_reorder_phys_dev")
|
||||
.set_lib_path(TEST_LAYER_PHYSDEV_REORDER)
|
||||
.set_api_version(VK_API_VERSION_1_1)
|
||||
.set_disable_environment("TEST_DISABLE_REORDER_PHYS_DEV")),
|
||||
"test_layer_reorder.json");
|
||||
|
||||
for (uint32_t icd = 0; icd < 2; ++icd) {
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
|
||||
auto& cur_icd = env.get_test_icd(icd);
|
||||
cur_icd.icd_api_version = VK_API_VERSION_1_2;
|
||||
VkPhysicalDeviceProperties properties{};
|
||||
properties.apiVersion = VK_API_VERSION_1_2;
|
||||
properties.vendorID = 0x11000000 + (icd << 6);
|
||||
char vendor_char = 'a' + icd;
|
||||
for (uint32_t dev = 0; dev < 3; ++dev) {
|
||||
properties.deviceID = properties.vendorID + dev;
|
||||
properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
|
||||
char dev_char = '0' + dev;
|
||||
std::string dev_name = "physdev_";
|
||||
dev_name += vendor_char;
|
||||
dev_name += "_";
|
||||
dev_name += dev_char;
|
||||
#if defined(_WIN32)
|
||||
strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1);
|
||||
#else
|
||||
strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
|
||||
#endif
|
||||
cur_icd.add_physical_device({});
|
||||
cur_icd.physical_devices.back().set_properties(properties);
|
||||
}
|
||||
cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
|
||||
cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
|
||||
cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
|
||||
}
|
||||
const uint32_t icd_devices = 6;
|
||||
|
||||
InstWrapper inst{env.vulkan_functions};
|
||||
inst.create_info.set_api_version(VK_API_VERSION_1_1);
|
||||
inst.CheckCreate();
|
||||
|
||||
uint32_t dev_count = 0;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &dev_count, nullptr));
|
||||
ASSERT_EQ(dev_count, icd_devices);
|
||||
|
||||
auto physical_devices = std::vector<VkPhysicalDevice>(dev_count);
|
||||
uint32_t returned_phys_dev_count = dev_count;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, physical_devices.data()));
|
||||
ASSERT_EQ(dev_count, returned_phys_dev_count);
|
||||
}
|
||||
|
||||
TEST_F(LayerPhysDeviceMod, AddRemoveAndReorderPhysicalDevices) {
|
||||
FrameworkEnvironment env;
|
||||
env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
|
||||
.set_name("VkLayer_LunarG_all_phys_dev")
|
||||
.set_lib_path(TEST_LAYER_PHYSDEV_ALL)
|
||||
.set_api_version(VK_API_VERSION_1_1)
|
||||
.set_disable_environment("TEST_DISABLE_ALL_PHYS_DEV")),
|
||||
"test_layer_all.json");
|
||||
|
||||
for (uint32_t icd = 0; icd < 2; ++icd) {
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
|
||||
auto& cur_icd = env.get_test_icd(icd);
|
||||
cur_icd.icd_api_version = VK_API_VERSION_1_2;
|
||||
VkPhysicalDeviceProperties properties{};
|
||||
properties.apiVersion = VK_API_VERSION_1_2;
|
||||
properties.vendorID = 0x11000000 + (icd << 6);
|
||||
char vendor_char = 'a' + icd;
|
||||
for (uint32_t dev = 0; dev < 3; ++dev) {
|
||||
properties.deviceID = properties.vendorID + dev;
|
||||
properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
|
||||
char dev_char = '0' + dev;
|
||||
std::string dev_name = "physdev_";
|
||||
dev_name += vendor_char;
|
||||
dev_name += "_";
|
||||
dev_name += dev_char;
|
||||
#if defined(_WIN32)
|
||||
strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1);
|
||||
#else
|
||||
strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
|
||||
#endif
|
||||
cur_icd.add_physical_device({});
|
||||
cur_icd.physical_devices.back().set_properties(properties);
|
||||
}
|
||||
cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
|
||||
cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
|
||||
cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
|
||||
}
|
||||
const uint32_t icd_devices = 6;
|
||||
|
||||
InstWrapper inst{env.vulkan_functions};
|
||||
inst.create_info.set_api_version(VK_API_VERSION_1_1);
|
||||
inst.CheckCreate();
|
||||
|
||||
uint32_t dev_count = 0;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &dev_count, nullptr));
|
||||
ASSERT_GT(dev_count, icd_devices);
|
||||
|
||||
auto physical_devices = std::vector<VkPhysicalDevice>(dev_count);
|
||||
uint32_t returned_phys_dev_count = dev_count;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &returned_phys_dev_count, physical_devices.data()));
|
||||
ASSERT_EQ(dev_count, returned_phys_dev_count);
|
||||
|
||||
uint32_t found_added_count = 0;
|
||||
for (uint32_t dev = 0; dev < dev_count; ++dev) {
|
||||
VkPhysicalDeviceProperties props{};
|
||||
inst->vkGetPhysicalDeviceProperties(physical_devices[dev], &props);
|
||||
if (string_eq(props.deviceName, "physdev_added_xx")) {
|
||||
found_added_count++;
|
||||
}
|
||||
}
|
||||
|
||||
// Should see 2 removed, but 3 added so a diff count of 1
|
||||
uint32_t diff_count = dev_count - icd_devices;
|
||||
ASSERT_EQ(1, diff_count);
|
||||
ASSERT_EQ(found_added_count, 3);
|
||||
}
|
||||
|
||||
static bool GroupsAreTheSame(VkPhysicalDeviceGroupProperties a, VkPhysicalDeviceGroupProperties b) {
|
||||
if (a.physicalDeviceCount != b.physicalDeviceCount) {
|
||||
return false;
|
||||
}
|
||||
for (uint32_t dev = 0; dev < a.physicalDeviceCount; ++dev) {
|
||||
if (a.physicalDevices[dev] != b.physicalDevices[dev]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_F(LayerPhysDeviceMod, AddPhysicalDeviceGroups) {
|
||||
FrameworkEnvironment env;
|
||||
env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
|
||||
.set_name("VkLayer_LunarG_add_phys_dev")
|
||||
.set_lib_path(TEST_LAYER_PHYSDEV_ADD)
|
||||
.set_api_version(VK_API_VERSION_1_1)
|
||||
.set_disable_environment("TEST_DISABLE_ADD_PHYS_DEV")),
|
||||
"test_layer_remove.json");
|
||||
|
||||
for (uint32_t icd = 0; icd < 2; ++icd) {
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
|
||||
auto& cur_icd = env.get_test_icd(icd);
|
||||
cur_icd.icd_api_version = VK_API_VERSION_1_2;
|
||||
VkPhysicalDeviceProperties properties{};
|
||||
properties.apiVersion = VK_API_VERSION_1_2;
|
||||
properties.vendorID = 0x11000000 + (icd << 6);
|
||||
char vendor_char = 'a' + icd;
|
||||
for (uint32_t dev = 0; dev < 3; ++dev) {
|
||||
properties.deviceID = properties.vendorID + dev;
|
||||
properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
|
||||
char dev_char = '0' + dev;
|
||||
std::string dev_name = "physdev_";
|
||||
dev_name += vendor_char;
|
||||
dev_name += "_";
|
||||
dev_name += dev_char;
|
||||
#if defined(_WIN32)
|
||||
strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1);
|
||||
#else
|
||||
strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
|
||||
#endif
|
||||
cur_icd.add_physical_device({});
|
||||
cur_icd.physical_devices.back().set_properties(properties);
|
||||
}
|
||||
cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
|
||||
cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
|
||||
cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
|
||||
}
|
||||
const uint32_t icd_groups = 4;
|
||||
|
||||
InstWrapper inst{env.vulkan_functions};
|
||||
inst.create_info.set_api_version(VK_API_VERSION_1_1);
|
||||
inst.CheckCreate();
|
||||
|
||||
uint32_t grp_count = 0;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &grp_count, nullptr));
|
||||
ASSERT_GT(grp_count, icd_groups);
|
||||
|
||||
auto not_exp_phys_dev_groups = std::vector<VkPhysicalDeviceGroupProperties>(icd_groups);
|
||||
for (uint32_t group = 0; group < icd_groups; ++group) {
|
||||
not_exp_phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
|
||||
}
|
||||
uint32_t returned_group_count = icd_groups;
|
||||
ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, not_exp_phys_dev_groups.data()));
|
||||
ASSERT_EQ(icd_groups, returned_group_count);
|
||||
|
||||
auto phys_dev_groups = std::vector<VkPhysicalDeviceGroupProperties>(grp_count);
|
||||
for (uint32_t group = 0; group < grp_count; ++group) {
|
||||
phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
|
||||
}
|
||||
returned_group_count = grp_count;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, phys_dev_groups.data()));
|
||||
ASSERT_EQ(grp_count, returned_group_count);
|
||||
|
||||
uint32_t diff_count = grp_count - icd_groups;
|
||||
uint32_t found_incomplete = 0;
|
||||
uint32_t found_added_count = 0;
|
||||
for (uint32_t grp = 0; grp < grp_count; ++grp) {
|
||||
// Shortcut, only groups with 1 device could be added in the newly added count
|
||||
if (1 == phys_dev_groups[grp].physicalDeviceCount) {
|
||||
for (uint32_t dev = 0; dev < phys_dev_groups[grp].physicalDeviceCount; ++dev) {
|
||||
VkPhysicalDeviceProperties props{};
|
||||
inst->vkGetPhysicalDeviceProperties(phys_dev_groups[grp].physicalDevices[dev], &props);
|
||||
if (string_eq(props.deviceName, "physdev_added_xx")) {
|
||||
found_added_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (uint32_t incomp = 0; incomp < icd_groups; ++incomp) {
|
||||
if (GroupsAreTheSame(not_exp_phys_dev_groups[incomp], phys_dev_groups[grp])) {
|
||||
found_incomplete++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We should have added the number of diff items, and the incomplete count should match the number of
|
||||
// original physical devices.
|
||||
ASSERT_EQ(found_added_count, diff_count);
|
||||
ASSERT_EQ(found_incomplete, icd_groups);
|
||||
}
|
||||
|
||||
TEST_F(LayerPhysDeviceMod, RemovePhysicalDeviceGroups) {
|
||||
FrameworkEnvironment env;
|
||||
env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
|
||||
.set_name("VkLayer_LunarG_remove_phys_dev")
|
||||
.set_lib_path(TEST_LAYER_PHYSDEV_REMOVE)
|
||||
.set_api_version(VK_API_VERSION_1_1)
|
||||
.set_disable_environment("TEST_DISABLE_REMOVE_PHYS_DEV")),
|
||||
"test_layer_remove.json");
|
||||
|
||||
for (uint32_t icd = 0; icd < 2; ++icd) {
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
|
||||
auto& cur_icd = env.get_test_icd(icd);
|
||||
cur_icd.icd_api_version = VK_API_VERSION_1_2;
|
||||
VkPhysicalDeviceProperties properties{};
|
||||
properties.apiVersion = VK_API_VERSION_1_2;
|
||||
properties.vendorID = 0x11000000 + (icd << 6);
|
||||
char vendor_char = 'a' + icd;
|
||||
for (uint32_t dev = 0; dev < 3; ++dev) {
|
||||
properties.deviceID = properties.vendorID + dev;
|
||||
properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
|
||||
char dev_char = '0' + dev;
|
||||
std::string dev_name = "physdev_";
|
||||
dev_name += vendor_char;
|
||||
dev_name += "_";
|
||||
dev_name += dev_char;
|
||||
strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
|
||||
cur_icd.add_physical_device({});
|
||||
cur_icd.physical_devices.back().set_properties(properties);
|
||||
}
|
||||
cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
|
||||
cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
|
||||
cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
|
||||
}
|
||||
const uint32_t icd_groups = 4;
|
||||
|
||||
InstWrapper inst{env.vulkan_functions};
|
||||
inst.create_info.set_api_version(VK_API_VERSION_1_1);
|
||||
inst.CheckCreate();
|
||||
|
||||
uint32_t grp_count = 0;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &grp_count, nullptr));
|
||||
ASSERT_LT(grp_count, icd_groups);
|
||||
|
||||
auto phys_dev_groups = std::vector<VkPhysicalDeviceGroupProperties>(grp_count);
|
||||
for (uint32_t group = 0; group < grp_count; ++group) {
|
||||
phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
|
||||
}
|
||||
uint32_t returned_group_count = grp_count;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, phys_dev_groups.data()));
|
||||
ASSERT_EQ(grp_count, returned_group_count);
|
||||
}
|
||||
|
||||
TEST_F(LayerPhysDeviceMod, ReorderPhysicalDeviceGroups) {
|
||||
FrameworkEnvironment env;
|
||||
env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
|
||||
.set_name("VkLayer_LunarG_reorder_phys_dev")
|
||||
.set_lib_path(TEST_LAYER_PHYSDEV_REORDER)
|
||||
.set_api_version(VK_API_VERSION_1_1)
|
||||
.set_disable_environment("TEST_DISABLE_REORDER_PHYS_DEV")),
|
||||
"test_layer_reorder.json");
|
||||
|
||||
for (uint32_t icd = 0; icd < 2; ++icd) {
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
|
||||
auto& cur_icd = env.get_test_icd(icd);
|
||||
cur_icd.icd_api_version = VK_API_VERSION_1_2;
|
||||
VkPhysicalDeviceProperties properties{};
|
||||
properties.apiVersion = VK_API_VERSION_1_2;
|
||||
properties.vendorID = 0x11000000 + (icd << 6);
|
||||
char vendor_char = 'a' + icd;
|
||||
for (uint32_t dev = 0; dev < 3; ++dev) {
|
||||
properties.deviceID = properties.vendorID + dev;
|
||||
properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
|
||||
char dev_char = '0' + dev;
|
||||
std::string dev_name = "physdev_";
|
||||
dev_name += vendor_char;
|
||||
dev_name += "_";
|
||||
dev_name += dev_char;
|
||||
#if defined(_WIN32)
|
||||
strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1);
|
||||
#else
|
||||
strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
|
||||
#endif
|
||||
cur_icd.add_physical_device({});
|
||||
cur_icd.physical_devices.back().set_properties(properties);
|
||||
}
|
||||
cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
|
||||
cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
|
||||
cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
|
||||
}
|
||||
const uint32_t icd_groups = 4;
|
||||
|
||||
InstWrapper inst{env.vulkan_functions};
|
||||
inst.create_info.set_api_version(VK_API_VERSION_1_1);
|
||||
inst.CheckCreate();
|
||||
|
||||
uint32_t grp_count = 0;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &grp_count, nullptr));
|
||||
ASSERT_EQ(grp_count, icd_groups);
|
||||
|
||||
auto phys_dev_groups = std::vector<VkPhysicalDeviceGroupProperties>(grp_count);
|
||||
for (uint32_t group = 0; group < grp_count; ++group) {
|
||||
phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
|
||||
}
|
||||
uint32_t returned_group_count = grp_count;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, phys_dev_groups.data()));
|
||||
ASSERT_EQ(grp_count, returned_group_count);
|
||||
}
|
||||
|
||||
TEST_F(LayerPhysDeviceMod, AddRemoveAndReorderPhysicalDeviceGroups) {
|
||||
FrameworkEnvironment env;
|
||||
env.add_implicit_layer(ManifestLayer{}.add_layer(ManifestLayer::LayerDescription{}
|
||||
.set_name("VkLayer_LunarG_all_phys_dev")
|
||||
.set_lib_path(TEST_LAYER_PHYSDEV_ALL)
|
||||
.set_api_version(VK_API_VERSION_1_1)
|
||||
.set_disable_environment("TEST_DISABLE_ALL_PHYS_DEV")),
|
||||
"test_layer_all.json");
|
||||
|
||||
for (uint32_t icd = 0; icd < 2; ++icd) {
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
|
||||
auto& cur_icd = env.get_test_icd(icd);
|
||||
cur_icd.icd_api_version = VK_API_VERSION_1_2;
|
||||
VkPhysicalDeviceProperties properties{};
|
||||
properties.apiVersion = VK_API_VERSION_1_2;
|
||||
properties.vendorID = 0x11000000 + (icd << 6);
|
||||
char vendor_char = 'a' + icd;
|
||||
for (uint32_t dev = 0; dev < 3; ++dev) {
|
||||
properties.deviceID = properties.vendorID + dev;
|
||||
properties.deviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
|
||||
char dev_char = '0' + dev;
|
||||
std::string dev_name = "physdev_";
|
||||
dev_name += vendor_char;
|
||||
dev_name += "_";
|
||||
dev_name += dev_char;
|
||||
#if defined(_WIN32)
|
||||
strncpy_s(properties.deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE, dev_name.c_str(), dev_name.length() + 1);
|
||||
#else
|
||||
strncpy(properties.deviceName, dev_name.c_str(), VK_MAX_PHYSICAL_DEVICE_NAME_SIZE);
|
||||
#endif
|
||||
cur_icd.add_physical_device({});
|
||||
cur_icd.physical_devices.back().set_properties(properties);
|
||||
}
|
||||
cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[0]);
|
||||
cur_icd.physical_device_groups.emplace_back(cur_icd.physical_devices[1]);
|
||||
cur_icd.physical_device_groups.back().use_physical_device(cur_icd.physical_devices[2]);
|
||||
}
|
||||
const uint32_t icd_groups = 4;
|
||||
|
||||
InstWrapper inst{env.vulkan_functions};
|
||||
inst.create_info.set_api_version(VK_API_VERSION_1_1);
|
||||
inst.CheckCreate();
|
||||
|
||||
uint32_t grp_count = 0;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &grp_count, nullptr));
|
||||
ASSERT_GT(grp_count, icd_groups);
|
||||
|
||||
auto phys_dev_groups = std::vector<VkPhysicalDeviceGroupProperties>(grp_count);
|
||||
for (uint32_t group = 0; group < grp_count; ++group) {
|
||||
phys_dev_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
|
||||
}
|
||||
uint32_t returned_group_count = grp_count;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, phys_dev_groups.data()));
|
||||
ASSERT_EQ(grp_count, returned_group_count);
|
||||
|
||||
uint32_t diff_count = grp_count - icd_groups;
|
||||
uint32_t found_added_count = 0;
|
||||
for (uint32_t grp = 0; grp < grp_count; ++grp) {
|
||||
// Shortcut, only groups with 1 device could be added in the newly added count
|
||||
if (1 == phys_dev_groups[grp].physicalDeviceCount) {
|
||||
for (uint32_t dev = 0; dev < phys_dev_groups[grp].physicalDeviceCount; ++dev) {
|
||||
VkPhysicalDeviceProperties props{};
|
||||
inst->vkGetPhysicalDeviceProperties(phys_dev_groups[grp].physicalDevices[dev], &props);
|
||||
if (string_eq(props.deviceName, "physdev_added_xx")) {
|
||||
found_added_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Should see 2 devices removed which should result in 1 group removed and since 3
|
||||
// devices were added we should have 3 new groups. So we should have a diff of 2
|
||||
// groups and 3 new groups
|
||||
ASSERT_EQ(2, diff_count);
|
||||
ASSERT_EQ(found_added_count, 3);
|
||||
}
|
||||
|
||||
+1411
-187
File diff suppressed because it is too large
Load Diff
@@ -320,6 +320,94 @@ TEST(MultipleDriverConfig, DifferentICDInterfaceVersions) {
|
||||
ASSERT_EQ(env.vulkan_functions.vkEnumeratePhysicalDevices(inst, &phys_dev_count, phys_devs_array.data()), VK_SUCCESS);
|
||||
ASSERT_EQ(phys_dev_count, 2);
|
||||
}
|
||||
|
||||
TEST(MultipleDriverConfig, DifferentICDsWithDevices) {
|
||||
FrameworkEnvironment env{};
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_ICD_GIPA));
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
|
||||
|
||||
// Make sure the loader returns all devices from all active ICDs. Many of the other
|
||||
// tests add multiple devices to a single ICD, this just makes sure the loader combines
|
||||
// device info across multiple drivers properly.
|
||||
TestICD& icd0 = env.get_test_icd(0);
|
||||
icd0.physical_devices.emplace_back("physical_device_0");
|
||||
icd0.min_icd_interface_version = 5;
|
||||
icd0.max_icd_interface_version = 5;
|
||||
|
||||
TestICD& icd1 = env.get_test_icd(1);
|
||||
icd1.physical_devices.emplace_back("physical_device_1");
|
||||
icd1.physical_devices.emplace_back("physical_device_2");
|
||||
icd1.min_icd_interface_version = 5;
|
||||
icd1.max_icd_interface_version = 5;
|
||||
|
||||
TestICD& icd2 = env.get_test_icd(2);
|
||||
icd2.physical_devices.emplace_back("physical_device_3");
|
||||
icd2.min_icd_interface_version = 5;
|
||||
icd2.max_icd_interface_version = 5;
|
||||
|
||||
InstWrapper inst{env.vulkan_functions};
|
||||
inst.CheckCreate();
|
||||
|
||||
std::array<VkPhysicalDevice, 4> phys_devs_array;
|
||||
uint32_t phys_dev_count = 4;
|
||||
ASSERT_EQ(env.vulkan_functions.vkEnumeratePhysicalDevices(inst, &phys_dev_count, phys_devs_array.data()), VK_SUCCESS);
|
||||
ASSERT_EQ(phys_dev_count, 4);
|
||||
}
|
||||
|
||||
TEST(MultipleDriverConfig, DifferentICDsWithDevicesAndGroups) {
|
||||
FrameworkEnvironment env{};
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_EXPORT_ICD_GIPA));
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2));
|
||||
env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA));
|
||||
|
||||
// The loader has to be able to handle drivers that support device groups in combination
|
||||
// with drivers that don't support device groups. When this is the case, the loader needs
|
||||
// to take every driver that doesn't support device groups and put each of its devices in
|
||||
// a separate group. Then it combines that information with the drivers that support
|
||||
// device groups returned info.
|
||||
|
||||
// ICD 0 : No 1.1 support (so 1 device will become 1 group in loader)
|
||||
TestICD& icd0 = env.get_test_icd(0);
|
||||
icd0.physical_devices.emplace_back("physical_device_0");
|
||||
icd0.min_icd_interface_version = 5;
|
||||
icd0.max_icd_interface_version = 5;
|
||||
icd0.set_icd_api_version(VK_API_VERSION_1_0);
|
||||
|
||||
// ICD 1 : 1.1 support (with 1 group with 2 devices)
|
||||
TestICD& icd1 = env.get_test_icd(1);
|
||||
icd1.physical_devices.emplace_back("physical_device_1");
|
||||
icd1.physical_devices.emplace_back("physical_device_2");
|
||||
icd1.physical_device_groups.emplace_back(icd1.physical_devices[0]);
|
||||
icd1.physical_device_groups.back().use_physical_device(icd1.physical_devices[1]);
|
||||
icd1.min_icd_interface_version = 5;
|
||||
icd1.max_icd_interface_version = 5;
|
||||
icd1.set_icd_api_version(VK_API_VERSION_1_1);
|
||||
|
||||
// ICD 2 : No 1.1 support (so 3 devices will become 3 groups in loader)
|
||||
TestICD& icd2 = env.get_test_icd(2);
|
||||
icd2.physical_devices.emplace_back("physical_device_3");
|
||||
icd2.physical_devices.emplace_back("physical_device_4");
|
||||
icd2.physical_devices.emplace_back("physical_device_5");
|
||||
icd2.min_icd_interface_version = 5;
|
||||
icd2.max_icd_interface_version = 5;
|
||||
icd2.set_icd_api_version(VK_API_VERSION_1_0);
|
||||
|
||||
InstWrapper inst{env.vulkan_functions};
|
||||
inst.create_info.set_api_version(1, 1, 0);
|
||||
inst.CheckCreate();
|
||||
|
||||
uint32_t group_count = static_cast<uint32_t>(5);
|
||||
uint32_t returned_group_count = 0;
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, nullptr));
|
||||
ASSERT_EQ(group_count, returned_group_count);
|
||||
|
||||
std::vector<VkPhysicalDeviceGroupProperties> group_props{};
|
||||
group_props.resize(group_count, VkPhysicalDeviceGroupProperties{VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES});
|
||||
ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &returned_group_count, group_props.data()));
|
||||
ASSERT_EQ(group_count, returned_group_count);
|
||||
}
|
||||
|
||||
// shim function pointers for 1.3
|
||||
// Should use autogen for this - it generates 'shim' functions for validation layers, maybe that could be used here.
|
||||
void test_vkCmdBeginRendering(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin,
|
||||
@@ -668,4 +756,4 @@ TEST(LayerManifest, ExplicitNonVulkanVariant) {
|
||||
inst.CheckCreate(VK_ERROR_LAYER_NOT_PRESENT);
|
||||
ASSERT_TRUE(log.find(std::string("Layer ") + explicit_layer_name +
|
||||
" has an \'api_version\' field which contains a non-zero variant value of 1. Skipping Layer."));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user