Fix Windows build and add proper phys dev group sorting
authorMark Young <marky@lunarg.com>
Tue, 8 Feb 2022 23:58:47 +0000 (16:58 -0700)
committerMark Young <marky@lunarg.com>
Wed, 16 Feb 2022 15:29:42 +0000 (08:29 -0700)
loader/loader.c
loader/loader_linux.c
loader/loader_linux.h
loader/loader_windows.c
loader/loader_windows.h
tests/framework/icd/test_icd.cpp
tests/framework/layer/test_layer.cpp
tests/loader_debug_ext_tests.cpp
tests/loader_version_tests.cpp

index c98a076f146c4b247ef80b51aa341269b3e16b6c..2a8d85991dd554f11fb77e007d9ab2723a5724c5 100644 (file)
@@ -6357,13 +6357,15 @@ VkResult setup_loader_term_phys_devs(struct loader_instance *inst) {
     uint32_t idx = 0;
 
     // Copy over everything found through sorted enumeration
-#if defined(_WIN32)
-    struct loader_phys_dev_per_icd *phys_dev_array = sorted_phys_dev_array;
-    for (uint32_t i = 0; i < sorted_count; ++i) {
-#else
     struct loader_phys_dev_per_icd *phys_dev_array = icd_phys_dev_array;
-    for (uint32_t i = 0; i < inst->total_icd_count; ++i) {
+    uint32_t max_count = inst->total_icd_count;
+#if defined(_WIN32)
+    if (sorted_count > 0) {
+        phys_dev_array = sorted_phys_dev_array;
+        max_count = sorted_count;
+    }
 #endif
+    for (uint32_t i = 0; i < max_count; ++i) {
         for (uint32_t j = 0; j < phys_dev_array[i].device_count; ++j) {
             // Check if this physical device is already in the old buffer
             if (NULL != inst->phys_devs_term) {
@@ -6522,6 +6524,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDevices(VkInstance in
     if (NULL != pPhysicalDevices) {
         if (copy_count > *pPhysicalDeviceCount) {
             copy_count = *pPhysicalDeviceCount;
+            loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
+                       "terminator_EnumeratePhysicalDevices : Trimming device count from %d to %d.", inst->total_gpu_count,
+                       copy_count);
             res = VK_INCOMPLETE;
         }
 
@@ -6875,7 +6880,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups(
     uint32_t cur_icd_group_count = 0;
     VkPhysicalDeviceGroupPropertiesKHR **new_phys_dev_groups = NULL;
     struct loader_physical_device_group_term *local_phys_dev_groups = NULL;
-    bool *local_phys_dev_group_sorted = NULL;
     PFN_vkEnumeratePhysicalDeviceGroups fpEnumeratePhysicalDeviceGroups = NULL;
     struct loader_phys_dev_per_icd *sorted_phys_dev_array = NULL;
     uint32_t sorted_count = 0;
@@ -6941,17 +6945,8 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups(
         // Create a temporary array (on the stack) to keep track of the
         // returned VkPhysicalDevice values.
         local_phys_dev_groups = loader_stack_alloc(sizeof(struct loader_physical_device_group_term) * total_count);
-        local_phys_dev_group_sorted = loader_stack_alloc(sizeof(bool) * total_count);
-        if (NULL == local_phys_dev_groups || NULL == local_phys_dev_group_sorted) {
-            loader_log(inst, VULKAN_LOADER_ERROR_BIT, 0,
-                       "terminator_EnumeratePhysicalDeviceGroups:  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(struct loader_physical_device_group_term) * total_count);
-        memset(local_phys_dev_group_sorted, 0, sizeof(bool) * total_count);
 
 #if defined(_WIN32)
         // Get the physical devices supported by platform sorting mechanism into a separate list
@@ -6966,13 +6961,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups(
         for (uint32_t icd_idx = 0; NULL != icd_term; icd_term = icd_term->next, icd_idx++) {
             uint32_t count_this_time = total_count - cur_icd_group_count;
 
-            // Check if this group can be sorted
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-            bool icd_sorted = sorted_count && (icd_term->scanned_icd->EnumerateAdapterPhysicalDevices != NULL);
-#else
-            bool icd_sorted = false;
-#endif
-
             // 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 = icd_term->dispatch.EnumeratePhysicalDeviceGroupsKHR;
@@ -7009,7 +6997,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups(
                     local_phys_dev_groups[cur_index].icd_index = icd_idx;
                     local_phys_dev_groups[cur_index].group_props.physicalDeviceCount = 1;
                     local_phys_dev_groups[cur_index].group_props.physicalDevices[0] = phys_dev_array[indiv_gpu];
-                    local_phys_dev_group_sorted[cur_index] = icd_sorted;
                 }
 
             } else {
@@ -7022,7 +7009,9 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups(
                     goto out;
                 }
                 if (cur_icd_group_count + count_this_time < *pPhysicalDeviceGroupCount) {
-                    // Can just use passed in structs
+                    // The total amount is still less than the amount of phsyical device group data passed in
+                    // by the callee.  Therefore, we don't have to allocate any temporary structures and we
+                    // can just use the data that was passed in.
                     res = fpEnumeratePhysicalDeviceGroups(icd_term->instance, &count_this_time,
                                                           &pPhysicalDeviceGroupProperties[cur_icd_group_count]);
                     if (res != VK_SUCCESS) {
@@ -7035,12 +7024,13 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups(
                     for (uint32_t group = 0; group < count_this_time; ++group) {
                         uint32_t cur_index = group + cur_icd_group_count;
                         local_phys_dev_groups[cur_index].group_props = pPhysicalDeviceGroupProperties[cur_index];
-                        local_phys_dev_group_sorted[cur_index] = icd_sorted;
                         local_phys_dev_groups[cur_index].this_icd_term = icd_term;
                         local_phys_dev_groups[cur_index].icd_index = icd_idx;
                     }
                 } else {
-                    // Have to use a temporary copy
+                    // There's not enough space in the callee's allocated pPhysicalDeviceGroupProperties structs,
+                    // so we have to allocate temporary versions to collect all the data.  However, we need to make
+                    // sure that at least the ones we do query utilize any pNext data in the callee's version.
                     VkPhysicalDeviceGroupProperties *tmp_group_props =
                         loader_stack_alloc(count_this_time * sizeof(VkPhysicalDeviceGroupProperties));
                     for (uint32_t group = 0; group < count_this_time; group++) {
@@ -7065,7 +7055,6 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups(
                     for (uint32_t group = 0; group < count_this_time; ++group) {
                         uint32_t cur_index = group + cur_icd_group_count;
                         local_phys_dev_groups[cur_index].group_props = tmp_group_props[group];
-                        local_phys_dev_group_sorted[cur_index] = icd_sorted;
                         local_phys_dev_groups[cur_index].this_icd_term = icd_term;
                         local_phys_dev_groups[cur_index].icd_index = icd_idx;
                     }
@@ -7085,11 +7074,20 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups(
 #ifdef LOADER_ENABLE_LINUX_SORT
         if (is_linux_sort_enabled(inst)) {
             // Get the physical devices supported by platform sorting mechanism into a separate list
-            res = linux_read_sorted_physical_device_groups(inst, total_count, local_phys_dev_groups);
+            res = linux_sort_physical_device_groups(inst, total_count, local_phys_dev_groups);
+        }
+#elif defined(_WIN32)
+        // The Windows sorting information is only on physical devices.  We need to take that and convert it to the group
+        // information if it's present.
+        if (sorted_count > 0) {
+            res =
+                windows_sort_physical_device_groups(inst, total_count, local_phys_dev_groups, sorted_count, sorted_phys_dev_array);
         }
 #endif  // LOADER_ENABLE_LINUX_SORT
 
-        // Replace all the physical device IDs with the proper loader values
+        // Just to be safe, make sure we successfully completed setup_loader_term_phys_devs above
+        // before attempting to do the following.  By verifying that setup_loader_term_phys_devs ran
+        // first, it guarantees that each physical device will have a loader-specific handle.
         if (NULL != inst->phys_devs_term) {
             for (uint32_t group = 0; group < total_count; group++) {
                 for (uint32_t group_gpu = 0; group_gpu < local_phys_dev_groups[group].group_props.physicalDeviceCount;
@@ -7118,42 +7116,15 @@ VKAPI_ATTR VkResult VKAPI_CALL terminator_EnumeratePhysicalDeviceGroups(
 
         uint32_t idx = 0;
 
-#if defined(_WIN32)
-        // Copy over everything found through sorted enumeration
-        for (uint32_t i = 0; i < sorted_count; ++i) {
-            // Find the VkPhysicalDeviceGroupProperties object in local_phys_dev_groups
-            VkPhysicalDeviceGroupProperties *group_properties = NULL;
-            for (uint32_t group = 0; group < total_count; group++) {
-                if (sorted_phys_dev_array[i].device_count != local_phys_dev_groups[group].group_props.physicalDeviceCount) {
-                    continue;
-                }
-
-                bool match = true;
-                for (uint32_t group_gpu = 0; group_gpu < local_phys_dev_groups[group].group_props.physicalDeviceCount;
-                     group_gpu++) {
-                    if (sorted_phys_dev_array[i].physical_devices[group_gpu] !=
-                        ((struct loader_physical_device_term *)local_phys_dev_groups[group].group_props.physicalDevices[group_gpu])
-                            ->phys_dev) {
-                        match = false;
-                        break;
-                    }
-                }
-
-                if (match) {
-                    group_properties = &local_phys_dev_groups[group].group_props;
-                }
-            }
-#else  // ! WIN32
-       // 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++) {
+        // Copy or create everything to fill the new array of physical device groups
+        for (uint32_t group = 0; group < total_count; group++) {
             // Skip groups which have been included through sorting
-            if (local_phys_dev_group_sorted[new_idx] || local_phys_dev_groups[new_idx].group_props.physicalDeviceCount == 0) {
+            if (local_phys_dev_groups[group].group_props.physicalDeviceCount == 0) {
                 continue;
             }
 
             // Find the VkPhysicalDeviceGroupProperties object in local_phys_dev_groups
-            VkPhysicalDeviceGroupProperties *group_properties = &local_phys_dev_groups[new_idx].group_props;
-#endif
+            VkPhysicalDeviceGroupProperties *group_properties = &local_phys_dev_groups[group].group_props;
 
             // 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_term; old_idx++) {
@@ -7268,6 +7239,9 @@ out:
         if (NULL != pPhysicalDeviceGroupProperties) {
             if (copy_count > *pPhysicalDeviceGroupCount) {
                 copy_count = *pPhysicalDeviceGroupCount;
+                loader_log(inst, VULKAN_LOADER_INFO_BIT, 0,
+                           "terminator_EnumeratePhysicalDeviceGroups : Trimming device count from %d to %d.",
+                           inst->phys_dev_group_count_term, copy_count);
                 res = VK_INCOMPLETE;
             }
 
index 05951cccd54a861c96de34a894b55ebeb06411f0..1aa7c45b358ab86213f88b92501ec9a4e477ef47 100644 (file)
@@ -341,17 +341,16 @@ out:
     return res;
 }
 
-// This function allocates an array in sorted_devices which must be freed by the caller if not null
-VkResult linux_read_sorted_physical_device_groups(struct loader_instance *inst, uint32_t group_count,
-                                                  struct loader_physical_device_group_term *sorted_group_term) {
+// This function sorts an array of physical device groups
+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;
     if (inst->app_api_major_version >= 1 && inst->app_api_minor_version >= 1) {
         is_vulkan_1_1 = true;
     }
 
-    loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
-               "linux_read_sorted_physical_device_groups:  Original order:");
+    loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, "linux_sort_physical_device_groups:  Original order:");
 
     for (uint32_t group = 0; group < group_count; ++group) {
         loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, "           Group %u", group);
@@ -428,7 +427,8 @@ VkResult linux_read_sorted_physical_device_groups(struct loader_instance *inst,
 
         // 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;
+            sorted_group_term[group].group_props.physicalDevices[dev] =
+                sorted_group_term[group].internal_device_info[dev].physical_device;
         }
     }
 
@@ -436,8 +436,7 @@ VkResult linux_read_sorted_physical_device_groups(struct loader_instance *inst,
     qsort(sorted_group_term, group_count, sizeof(struct loader_physical_device_group_term), compare_device_groups);
 
     if (loader_get_debug_level() & (VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT)) {
-        loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0,
-                   "linux_read_sorted_physical_device_groups:  Sorted order:");
+        loader_log(inst, VULKAN_LOADER_INFO_BIT | VULKAN_LOADER_DRIVER_BIT, 0, "linux_sort_physical_device_groups:  Sorted order:");
         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) {
index 5546cbf71a7eb312196267ef39b8f0091667b473..9a78f421ed4a2f8f041f589328e465b7bd6fd325 100644 (file)
@@ -31,8 +31,8 @@ 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);
 
-// This function allocates an array in sorted_devices which must be freed by the caller if not null
-VkResult linux_read_sorted_physical_device_groups(struct loader_instance *inst, uint32_t group_count,
-                                                  struct loader_physical_device_group_term *sorted_group_term);
+// This function sorts an array in physical device groups
+VkResult linux_sort_physical_device_groups(struct loader_instance *inst, uint32_t group_count,
+                                           struct loader_physical_device_group_term *sorted_group_term);
 
 #endif  // LOADER_ENABLE_LINUX_SORT
\ No newline at end of file
index 361a18ca2ed6b0491cdb61ff69ab4581875e9354..a16019bd65805f712e63eec605b4bf4ea0d03eac 100644 (file)
@@ -910,4 +910,74 @@ VkLoaderFeatureFlags windows_initialize_dxgi(void) {
     return feature_flags;
 }
 
+// Sort the VkPhysicalDevices that are part of the current group with the list passed in from the sorted list.
+// Multiple groups could have devices out of the same sorted list, however, a single group's devices must all come
+// from the same sorted list.
+void windows_sort_devices_in_group(struct loader_instance *inst, struct VkPhysicalDeviceGroupProperties *group_props,
+                                   struct loader_phys_dev_per_icd *icd_sorted_list) {
+    uint32_t cur_index = 0;
+    for (uint32_t dev = 0; dev < icd_sorted_list->device_count; ++dev) {
+        for (uint32_t grp_dev = cur_index; grp_dev < group_props->physicalDeviceCount; ++grp_dev) {
+            if (icd_sorted_list->physical_devices[dev] == group_props->physicalDevices[grp_dev]) {
+                if (cur_index != grp_dev) {
+                    VkPhysicalDevice swap_dev = group_props->physicalDevices[cur_index];
+                    group_props->physicalDevices[cur_index] = group_props->physicalDevices[grp_dev];
+                    group_props->physicalDevices[grp_dev] = swap_dev;
+                }
+                cur_index++;
+                break;
+            }
+        }
+    }
+    if (cur_index == 0) {
+        loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
+                   "windows_sort_devices_in_group:  Never encountered a device in the sorted list group");
+    }
+}
+
+// This function sorts an array in physical device groups based on the sorted physical device information
+VkResult windows_sort_physical_device_groups(struct loader_instance *inst, const uint32_t group_count,
+                                             struct loader_physical_device_group_term *sorted_group_term,
+                                             const uint32_t sorted_device_count,
+                                             struct loader_phys_dev_per_icd *sorted_phys_dev_array) {
+    if (0 == group_count || NULL == sorted_group_term) {
+        loader_log(inst, VULKAN_LOADER_WARN_BIT, 0,
+                   "windows_sort_physical_device_groups: Called with invalid information (Group count %d, Sorted Info %p)",
+                   group_count, sorted_group_term);
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+
+    uint32_t new_index = 0;
+    for (uint32_t icd = 0; icd < sorted_device_count; ++icd) {
+        for (uint32_t dev = 0; dev < sorted_phys_dev_array[icd].device_count; ++dev) {
+            // Find a group associated with a given device
+            for (uint32_t group = new_index; group < group_count; ++group) {
+                bool device_found = false;
+                // Look for the current sorted device in a group and put it in the correct location if it isn't already
+                for (uint32_t grp_dev = 0; grp_dev < sorted_group_term[group].group_props.physicalDeviceCount; ++grp_dev) {
+                    if (sorted_group_term[group].group_props.physicalDevices[grp_dev] ==
+                        sorted_phys_dev_array[icd].physical_devices[dev]) {
+                        // First, sort devices inside of group to be in priority order
+                        windows_sort_devices_in_group(inst, &sorted_group_term[group].group_props, &sorted_phys_dev_array[icd]);
+
+                        // Second, move the group up in priority if it needs to be
+                        if (new_index != group) {
+                            struct loader_physical_device_group_term tmp = sorted_group_term[new_index];
+                            sorted_group_term[new_index] = sorted_group_term[group];
+                            sorted_group_term[group] = tmp;
+                        }
+                        device_found = true;
+                        new_index++;
+                        break;
+                    }
+                }
+                if (device_found) {
+                    break;
+                }
+            }
+        }
+    }
+    return VK_SUCCESS;
+}
+
 #endif  // _WIN32
\ No newline at end of file
index 8591841107f7e7cacae1fea5520db0dcf04d2a16..a02151b052f6c05978855abc5974a93a808b2830 100644 (file)
@@ -102,6 +102,12 @@ VkResult windows_read_data_files_in_registry(const struct loader_instance *inst,
 VkResult windows_read_sorted_physical_devices(struct loader_instance *inst, struct loader_phys_dev_per_icd **sorted_devices,
                                               uint32_t *sorted_count);
 
+// This function sorts an array in physical device groups based on the sorted physical device information
+VkResult windows_sort_physical_device_groups(struct loader_instance *inst, const uint32_t group_count,
+                                             struct loader_physical_device_group_term *sorted_group_term,
+                                             const uint32_t sorted_device_count,
+                                             struct loader_phys_dev_per_icd *sorted_phys_dev_array);
+
 // Creates a DXGI factory
 // Returns VkLoaderFeatureFlags containing VK_LOADER_FEATURE_PHYSICAL_DEVICE_SORTING if successful, otherwise 0
 VkLoaderFeatureFlags windows_initialize_dxgi(void);
index cee7a03ebcc6948fb1703eb1d392bb326ae00540..8460a5aed468ca49847fd3cd45873ac071b6f175 100644 (file)
@@ -231,7 +231,7 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDeviceGroups(
 
         uint32_t group_count = 0;
         if (0 == icd.physical_device_groups.size()) {
-            group_count = icd.physical_devices.size();
+            group_count = static_cast<uint32_t>(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;
@@ -244,7 +244,7 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDeviceGroups(
                     icd.physical_devices[device_group].vk_physical_device.handle;
             }
         } else {
-            group_count = icd.physical_device_groups.size();
+            group_count = static_cast<uint32_t>(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;
@@ -1434,9 +1434,21 @@ FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDe
                                                                                       uint32_t* pPhysicalDeviceCount,
                                                                                       VkPhysicalDevice* pPhysicalDevices) {
     icd.called_enumerate_adapter_physical_devices = CalledEnumerateAdapterPhysicalDevices::called;
-    return test_vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
-
-    return VK_SUCCESS;
+    VkResult res = test_vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
+    // For this testing, flip order intentaionlly
+    if (nullptr != pPhysicalDevices) {
+        for (uint32_t lower = 0; lower < *pPhysicalDeviceCount; ++lower) {
+            uint32_t upper = *pPhysicalDeviceCount - lower - 1;
+            // In case of odd numbered list we don't want to waste resources flipping itself
+            if (upper == lower) {
+                break;
+            }
+            VkPhysicalDevice temp = pPhysicalDevices[lower];
+            pPhysicalDevices[lower] = pPhysicalDevices[upper];
+            pPhysicalDevices[upper] = temp;
+        }
+    }
+    return res;
 }
 #endif  // defined(WIN32)
 #endif  // TEST_ICD_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES
index 5eaa1a2bef68ca8fc9f66834cf09f227d1cf4bd1..1f8c68f8047dd1914c2f788eb1fe8146a9fd349a 100644 (file)
@@ -246,7 +246,7 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDevices(VkInstance instan
 
 #if TEST_PHYSDEV_LAYER_ADD
         // Insert a new device in the beginning, middle, and end
-        uint32_t middle = tmp_vector.size() / 2;
+        uint32_t middle = static_cast<uint32_t>(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);
@@ -260,7 +260,7 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDevices(VkInstance instan
 
 #if TEST_PHYSDEV_LAYER_REORDER
         // Flip the order of items
-        for (int32_t dev = tmp_vector.size() - 1; dev >= 0; --dev) {
+        for (int32_t dev = static_cast<int32_t>(tmp_vector.size() - 1); dev >= 0; --dev) {
             layer.complete_physical_devices.push_back(tmp_vector[dev]);
         }
 #else   // !TEST_PHYSDEV_LAYER_REORDER
@@ -272,9 +272,9 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDevices(VkInstance instan
     }
 
     if (nullptr == pPhysicalDevices) {
-        *pPhysicalDeviceCount = layer.complete_physical_devices.size();
+        *pPhysicalDeviceCount = static_cast<uint32_t>(layer.complete_physical_devices.size());
     } else {
-        uint32_t adj_count = layer.complete_physical_devices.size();
+        uint32_t adj_count = static_cast<uint32_t>(layer.complete_physical_devices.size());
         if (*pPhysicalDeviceCount < adj_count) {
             adj_count = *pPhysicalDeviceCount;
             res = VK_INCOMPLETE;
@@ -378,7 +378,7 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDeviceGroups(
 
 #if TEST_PHYSDEV_LAYER_REORDER
         // Flip the order of items
-        for (int32_t dev = tmp_vector.size() - 1; dev >= 0; --dev) {
+        for (int32_t dev = static_cast<int32_t>(tmp_vector.size() - 1); dev >= 0; --dev) {
             layer.complete_physical_device_groups.push_back(tmp_vector[dev]);
         }
 #else   // !TEST_PHYSDEV_LAYER_REORDER
@@ -390,9 +390,9 @@ VKAPI_ATTR VkResult VKAPI_CALL test_vkEnumeratePhysicalDeviceGroups(
     }
 
     if (nullptr == pPhysicalDeviceGroupProperties) {
-        *pPhysicalDeviceGroupCount = layer.complete_physical_device_groups.size();
+        *pPhysicalDeviceGroupCount = static_cast<uint32_t>(layer.complete_physical_device_groups.size());
     } else {
-        uint32_t adj_count = layer.complete_physical_device_groups.size();
+        uint32_t adj_count = static_cast<uint32_t>(layer.complete_physical_device_groups.size());
         if (*pPhysicalDeviceGroupCount < adj_count) {
             adj_count = *pPhysicalDeviceGroupCount;
             res = VK_INCOMPLETE;
index e9c297c3bd5a0744ae502f8085b15885df824431..5e9ce16c66f2372727e6b57831dbff483787d52d 100644 (file)
@@ -254,7 +254,7 @@ TEST_F(SeparateReport, ErrorInEnumDevs) {
 // Test report created outside of vkCreateInstance with info in vkEnumeratePhysicalDevices.
 // This should not be logged because type is wrong.
 TEST_F(SeparateReport, InfoInEnumDevsIgnored) {
-    expected_message = "Trimming device count down by application request";
+    expected_message = "Trimming device count from 6 to 5";
     expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
     expected_flag = VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
 
@@ -279,7 +279,7 @@ TEST_F(SeparateReport, InfoInEnumDevsIgnored) {
 // Test report created outside of vkCreateInstance with info in vkEnumeratePhysicalDevices.
 // This should be logged because type is correct.
 TEST_F(SeparateReport, InfoInEnumDevs) {
-    expected_message = "Trimming device count down by application request";
+    expected_message = "Trimming device count from 6 to 5";
     expected_object_type = VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT;
     expected_flag = VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
 
@@ -720,7 +720,7 @@ TEST_F(SeparateMessenger, ErrorInEnumDevs) {
 // Test debug utils created outside of vkCreateInstance with info in vkEnumeratePhysicalDevices.
 // This should not be logged because type is wrong.
 TEST_F(SeparateMessenger, InfoInEnumDevsIgnoredType) {
-    expected_message = "Trimming device count down by application request";
+    expected_message = "Trimming device count from 6 to 5";
     expected_object_type = VK_OBJECT_TYPE_INSTANCE;
     expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
     expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
@@ -751,7 +751,7 @@ TEST_F(SeparateMessenger, InfoInEnumDevsIgnoredType) {
 // Test debug utils created outside of vkCreateInstance with info in vkEnumeratePhysicalDevices.
 // This should not be logged because severity is wrong.
 TEST_F(SeparateMessenger, InfoInEnumDevsIgnoredSeverity) {
-    expected_message = "Trimming device count down by application request";
+    expected_message = "Trimming device count from 6 to 5";
     expected_object_type = VK_OBJECT_TYPE_INSTANCE;
     expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
     expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
@@ -783,7 +783,7 @@ TEST_F(SeparateMessenger, InfoInEnumDevsIgnoredSeverity) {
 
 // Test debug utils created outside of vkCreateInstance with info in vkEnumeratePhysicalDevices.
 TEST_F(SeparateMessenger, InfoInEnumDevs) {
-    expected_message = "Trimming device count down by application request";
+    expected_message = "Trimming device count from 6 to 5";
     expected_object_type = VK_OBJECT_TYPE_INSTANCE;
     expected_message_flags = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
     expected_severity_flags = VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
index a4fd5cf71a0275dbfc2dfb2287981adf96d53eb2..27a86c45c59c4fde1ca18b87c73f0d60455b152c 100644 (file)
@@ -265,6 +265,156 @@ TEST_F(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, EnumAdapters2) {
                                                                            physical_device_handles.data()));
     ASSERT_EQ(physical_count, returned_physical_count);
 }
+
+TEST_F(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, VerifyPhysDevResults) {
+    auto& driver = env->get_test_icd();
+    driver.min_icd_interface_version = 6;
+    driver.set_icd_api_version(VK_API_VERSION_1_1);
+    driver.physical_devices.emplace_back("physical_device_4");
+    driver.physical_devices.emplace_back("physical_device_3");
+    driver.physical_devices.emplace_back("physical_device_2");
+    driver.physical_devices.emplace_back("physical_device_1");
+    driver.physical_devices.emplace_back("physical_device_0");
+
+    InstWrapper inst1{env->vulkan_functions};
+    inst1.CheckCreate();
+
+    const uint32_t phys_dev_count = 5;
+    uint32_t count = phys_dev_count;
+    std::array<VkPhysicalDevice, phys_dev_count> original_pds;
+    std::array<std::string, phys_dev_count> original_pds_name;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumeratePhysicalDevices(inst1.inst, &count, original_pds.data()));
+    ASSERT_EQ(phys_dev_count, count);
+
+    for (uint32_t dev = 0; dev < phys_dev_count; ++dev) {
+        VkPhysicalDeviceProperties props;
+        env->vulkan_functions.vkGetPhysicalDeviceProperties(original_pds[dev], &props);
+        original_pds_name[dev] = props.deviceName;
+    }
+
+    uint32_t driver_index = 2;  // which drive this test pretends to be
+    auto& known_driver = known_driver_list.at(2);
+    DXGI_ADAPTER_DESC1 desc1{};
+    wcsncpy_s(&desc1.Description[0], 128, L"TestDriver1", 128);
+    desc1.VendorId = known_driver.vendor_id;
+    desc1.AdapterLuid;
+    desc1.Flags = DXGI_ADAPTER_FLAG_NONE;
+    env->platform_shim->add_dxgi_adapter(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES, GpuType::discrete,
+                                         driver_index, desc1);
+
+    InstWrapper inst2{env->vulkan_functions};
+    inst2.CheckCreate();
+
+    // For the test ICD, when the D3D Adapter mechanism is enabled, it should completely swap the order of devices.
+    // Since we can't compare VkPhysicalDevice handles because they will be different per VkInstance, we will
+    // compare the property names returned, which should still be equal.
+
+    std::array<VkPhysicalDevice, phys_dev_count> adapter_pds;
+    std::array<std::string, phys_dev_count> adapter_pds_name;
+    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumeratePhysicalDevices(inst1.inst, &count, adapter_pds.data()));
+    ASSERT_EQ(phys_dev_count, count);
+
+    for (uint32_t dev = 0; dev < phys_dev_count; ++dev) {
+        VkPhysicalDeviceProperties props;
+        env->vulkan_functions.vkGetPhysicalDeviceProperties(adapter_pds[dev], &props);
+        adapter_pds_name[dev] = props.deviceName;
+    }
+
+    for (uint32_t lower = 0; lower < phys_dev_count; ++lower) {
+        uint32_t upper = phys_dev_count - lower - 1;
+        ASSERT_EQ(true, string_eq(adapter_pds_name[upper].c_str(), original_pds_name[lower].c_str()));
+    }
+}
+
+TEST_F(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, VerifyGroupResults) {
+    auto& driver = env->get_test_icd();
+    driver.min_icd_interface_version = 6;
+    driver.set_icd_api_version(VK_API_VERSION_1_1);
+    driver.physical_devices.emplace_back("physical_device_4");
+    driver.physical_devices.emplace_back("physical_device_3");
+    driver.physical_devices.emplace_back("physical_device_2");
+    driver.physical_devices.emplace_back("physical_device_1");
+    driver.physical_devices.emplace_back("physical_device_0");
+    driver.physical_device_groups.emplace_back(driver.physical_devices[0]);
+    driver.physical_device_groups.back().use_physical_device(driver.physical_devices[1]);
+    driver.physical_device_groups.emplace_back(driver.physical_devices[2]);
+    driver.physical_device_groups.emplace_back(driver.physical_devices[3]);
+    driver.physical_device_groups.back().use_physical_device(driver.physical_devices[4]);
+
+    InstWrapper inst1{env->vulkan_functions};
+    inst1.CheckCreate();
+
+    const uint32_t actual_group_count = 3;
+    uint32_t count = actual_group_count;
+    std::array<VkPhysicalDeviceGroupProperties, actual_group_count> original_groups{};
+    std::vector<std::vector<std::string>> original_strings;
+    original_strings.resize(actual_group_count);
+    for (uint32_t group = 0; group < actual_group_count; ++group) {
+        original_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
+        original_groups[group].pNext = nullptr;
+    }
+    ASSERT_EQ(VK_SUCCESS, inst1->vkEnumeratePhysicalDeviceGroups(inst1, &count, original_groups.data()));
+    ASSERT_EQ(actual_group_count, count);
+
+    for (uint32_t group = 0; group < actual_group_count; ++group) {
+        original_strings[group].resize(original_groups[group].physicalDeviceCount);
+        for (uint32_t dev = 0; dev < original_groups[group].physicalDeviceCount; ++dev) {
+            VkPhysicalDeviceProperties props;
+            env->vulkan_functions.vkGetPhysicalDeviceProperties(original_groups[group].physicalDevices[dev], &props);
+            original_strings[group][dev] = props.deviceName;
+        }
+    }
+
+    uint32_t driver_index = 2;  // which drive this test pretends to be
+    auto& known_driver = known_driver_list.at(2);
+    DXGI_ADAPTER_DESC1 desc1{};
+    wcsncpy_s(&desc1.Description[0], 128, L"TestDriver1", 128);
+    desc1.VendorId = known_driver.vendor_id;
+    desc1.AdapterLuid;
+    desc1.Flags = DXGI_ADAPTER_FLAG_NONE;
+    env->platform_shim->add_dxgi_adapter(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES, GpuType::discrete,
+                                         driver_index, desc1);
+
+    InstWrapper inst2{env->vulkan_functions};
+    inst2.CheckCreate();
+
+    // For the test ICD, when the D3D Adapter mechanism is enabled, it should completely swap the order of devices.
+    // Since we can't compare VkPhysicalDevice handles because they will be different per VkInstance, we will
+    // compare the property names returned, which should still be equal.
+    // And, since this is device groups, the groups themselves should also be in reverse order with the devices
+    // inside each group in revers order.
+
+    std::array<VkPhysicalDeviceGroupProperties, actual_group_count> adapter_groups{};
+    std::vector<std::vector<std::string>> adapter_strings;
+    adapter_strings.resize(actual_group_count);
+
+    for (uint32_t group = 0; group < actual_group_count; ++group) {
+        adapter_groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
+        adapter_groups[group].pNext = nullptr;
+    }
+    ASSERT_EQ(VK_SUCCESS, inst2->vkEnumeratePhysicalDeviceGroups(inst2, &count, adapter_groups.data()));
+    ASSERT_EQ(actual_group_count, count);
+
+    for (uint32_t group = 0; group < actual_group_count; ++group) {
+        adapter_strings[group].resize(adapter_groups[group].physicalDeviceCount);
+        for (uint32_t dev = 0; dev < adapter_groups[group].physicalDeviceCount; ++dev) {
+            VkPhysicalDeviceProperties props;
+            env->vulkan_functions.vkGetPhysicalDeviceProperties(adapter_groups[group].physicalDevices[dev], &props);
+            adapter_strings[group][dev] = props.deviceName;
+        }
+    }
+
+    for (uint32_t lower_group = 0; lower_group < actual_group_count; ++lower_group) {
+        uint32_t upper_group = actual_group_count - lower_group - 1;
+        ASSERT_EQ(original_groups[lower_group].physicalDeviceCount, adapter_groups[upper_group].physicalDeviceCount);
+        for (uint32_t lower_dev = 0; lower_dev < original_groups[lower_group].physicalDeviceCount; ++lower_dev) {
+            uint32_t upper_dev = original_groups[lower_group].physicalDeviceCount - lower_dev - 1;
+            ASSERT_EQ(true,
+                      string_eq(adapter_strings[upper_group][upper_dev].c_str(), original_strings[lower_group][lower_dev].c_str()));
+        }
+    }
+}
+
 #endif  // defined(WIN32)
 
 TEST(MultipleICDConfig, Basic) {