Fixup windows test infrastructure
authorCharles Giessen <charles@lunarg.com>
Thu, 24 Mar 2022 23:22:16 +0000 (17:22 -0600)
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>
Fri, 25 Mar 2022 01:00:28 +0000 (19:00 -0600)
Cleaned up several bugs in the testing framework in the windows shim.
Rewrote the tests that exercise DXGI/D3DKMT functionality.

tests/framework/icd/test_icd.cpp
tests/framework/icd/test_icd.h
tests/framework/layer/test_layer.h
tests/framework/shim/shim.h
tests/framework/shim/shim_common.cpp
tests/framework/shim/windows_shim.cpp
tests/framework/test_environment.cpp
tests/framework/test_environment.h
tests/loader_regression_tests.cpp
tests/loader_version_tests.cpp

index 0d365322ce6280539c62ec135436e08d1be856a8..0387a48949331b7a665a63c9e3122e479ffe7987 100644 (file)
@@ -1485,20 +1485,15 @@ FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProp
 FRAMEWORK_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID,
                                                                                       uint32_t* pPhysicalDeviceCount,
                                                                                       VkPhysicalDevice* pPhysicalDevices) {
-    icd.called_enumerate_adapter_physical_devices = CalledEnumerateAdapterPhysicalDevices::called;
+    if (adapterLUID.LowPart != icd.adapterLUID.LowPart || adapterLUID.HighPart != icd.adapterLUID.HighPart) {
+        *pPhysicalDeviceCount = 0;
+        return VK_SUCCESS;
+    }
+    icd.called_enumerate_adapter_physical_devices = true;
     VkResult res = test_vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
-    // For this testing, flip order intentaionlly
+    // For this testing, flip order intentionally
     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;
-        }
+        std::reverse(pPhysicalDevices, pPhysicalDevices + *pPhysicalDeviceCount);
     }
     return res;
 }
index a55d15200e76158fa8646d0c40ae834fb2f2cb18..884e334ef4bb2dc1807951c13432628fa07d308a 100644 (file)
@@ -45,7 +45,7 @@ enum class InterfaceVersionCheck {
     version_is_supported
 };
 
-enum class CalledEnumerateAdapterPhysicalDevices { not_called, called, called_but_not_supported };
+enum class CalledEnumerateAdapterPhysicalDevices { not_called, called };
 
 enum class UsingICDProvidedWSI { not_using, is_using };
 
@@ -60,8 +60,7 @@ struct TestICD {
     BUILDER_VALUE(TestICD, uint32_t, max_icd_interface_version, 6)
     uint32_t icd_interface_version_received = 0;
 
-    CalledEnumerateAdapterPhysicalDevices called_enumerate_adapter_physical_devices =
-        CalledEnumerateAdapterPhysicalDevices::not_called;
+    bool called_enumerate_adapter_physical_devices = false;
 
     BUILDER_VALUE(TestICD, bool, enable_icd_wsi, false);
     UsingICDProvidedWSI is_using_icd_wsi = UsingICDProvidedWSI::not_using;
@@ -108,6 +107,10 @@ struct TestICD {
         for (auto& ext : instance_extensions) info.enabled_extensions.push_back(ext.extensionName.data());
         return info;
     }
+
+#if defined(WIN32)
+    BUILDER_VALUE(TestICD, LUID, adapterLUID, {})
+#endif  // defined(WIN32)
 };
 
 using GetTestICDFunc = TestICD* (*)();
index df32ce5dbcbad9123575cb2c9214903bb306d5e2..75cd107417648d789cee07873a5a83fd39d19569 100644 (file)
@@ -96,7 +96,7 @@ struct TestLayer {
 
     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)
+    BUILDER_VALUE(TestLayer, uint32_t, reported_extension_props, 0)
     BUILDER_VALUE(TestLayer, uint32_t, reported_instance_version, VK_API_VERSION_1_0)
     BUILDER_VALUE(TestLayer, uint32_t, implementation_version, 2)
     BUILDER_VALUE(TestLayer, uint32_t, min_implementation_version, 0)
index 7452fd9b26504694e46c65a6590b6dda0adc7585..7498f51c1d5e864cbd0b0e1886e84ebe036ba3f7 100644 (file)
@@ -84,30 +84,29 @@ static std::array<KnownDriverData, 4> known_driver_list = {
 };
 
 struct DXGIAdapter {
-    DXGIAdapter(fs::path const& manifest_path, GpuType gpu_preference, uint32_t known_driver_index, DXGI_ADAPTER_DESC1 desc1,
-                uint32_t adapter_index)
-        : manifest_path(manifest_path),
-          gpu_preference(gpu_preference),
-          known_driver_index(known_driver_index),
-          desc1(desc1),
-          adapter_index(adapter_index) {}
-    fs::path manifest_path;
+    DXGIAdapter(GpuType gpu_preference, DXGI_ADAPTER_DESC1 desc1, uint32_t adapter_index)
+        : gpu_preference(gpu_preference), desc1(desc1), adapter_index(adapter_index) {}
     GpuType gpu_preference = GpuType::unspecified;
-    uint32_t known_driver_index = UINT_MAX;  // index into the known_driver_list, UINT_MAX if it shouldn't index at all.
     DXGI_ADAPTER_DESC1 desc1{};
     uint32_t adapter_index = 0;
 };
 
-struct SHIM_D3DKMT_ADAPTERINFO {
+struct D3DKMT_Adapter {
+    D3DKMT_Adapter() = default;
+    D3DKMT_Adapter(UINT hAdapter, LUID adapter_luid) noexcept : hAdapter(hAdapter), adapter_luid(adapter_luid) {}
+
+    D3DKMT_Adapter& add_driver_manifest_path(fs::path const& src);
+    D3DKMT_Adapter& add_implicit_layer_manifest_path(fs::path const& src);
+    D3DKMT_Adapter& add_explicit_layer_manifest_path(fs::path const& src);
+
     UINT hAdapter;
-    LUID AdapterLuid;
-    ULONG NumOfSources;
-    BOOL bPresentMoveRegionsPreferred;
-};
+    LUID adapter_luid;
+    std::vector<std::wstring> driver_paths;
+    std::vector<std::wstring> implicit_layer_paths;
+    std::vector<std::wstring> explicit_layer_paths;
 
-struct D3DKMT_Adapter {
-    SHIM_D3DKMT_ADAPTERINFO info;
-    fs::path path;
+   private:
+    D3DKMT_Adapter& add_path(fs::path src, std::vector<std::wstring>& dest);
 };
 
 #endif
@@ -132,9 +131,8 @@ struct PlatformShim {
     }
     unsigned long elevation_level = SECURITY_MANDATORY_LOW_RID;
 
-    void add_dxgi_adapter(fs::path const& manifest_path, GpuType gpu_preference, uint32_t known_driver_index,
-                          DXGI_ADAPTER_DESC1 desc1);
-    void add_d3dkmt_adapter(SHIM_D3DKMT_ADAPTERINFO adapter, fs::path const& path);
+    void add_dxgi_adapter(GpuType gpu_preference, DXGI_ADAPTER_DESC1 desc1);
+    void add_d3dkmt_adapter(D3DKMT_Adapter const& adapter);
 
     uint32_t next_adapter_handle = 1;  // increment everytime add_dxgi_adapter is called
     std::vector<DXGIAdapter> dxgi_adapters;
index 57152b4cfc290c540812d352b82a95557de67373..31c61c273d5c0e8c2eee13f9d7119131b14e7423 100644 (file)
@@ -62,6 +62,22 @@ std::vector<std::string> parse_env_var_list(std::string const& var) {
 
 #if defined(WIN32)
 
+D3DKMT_Adapter& D3DKMT_Adapter::add_driver_manifest_path(fs::path const& src) { return add_path(src, driver_paths); }
+D3DKMT_Adapter& D3DKMT_Adapter::add_implicit_layer_manifest_path(fs::path const& src) {
+    return add_path(src, implicit_layer_paths);
+}
+D3DKMT_Adapter& D3DKMT_Adapter::add_explicit_layer_manifest_path(fs::path const& src) {
+    return add_path(src, explicit_layer_paths);
+}
+
+D3DKMT_Adapter& D3DKMT_Adapter::add_path(fs::path src, std::vector<std::wstring>& dest) {
+    std::wstring dest_path;
+    dest_path.resize(src.size());
+    MultiByteToWideChar(CP_UTF8, 0, src.c_str(), static_cast<int>(src.size()), &dest_path[0], static_cast<int>(dest_path.size()));
+    dest.push_back(dest_path);
+    return *this;
+}
+
 std::string category_path_name(ManifestCategory category) {
     if (category == ManifestCategory::implicit_layer) return "ImplicitLayers";
     if (category == ManifestCategory::explicit_layer)
@@ -87,14 +103,11 @@ void PlatformShim::add_manifest(ManifestCategory category, fs::path const& path)
     else
         hkey_local_machine_drivers.emplace_back(path.str());
 }
-void PlatformShim::add_dxgi_adapter(fs::path const& manifest_path, GpuType gpu_preference, uint32_t known_driver_index,
-                                    DXGI_ADAPTER_DESC1 desc1) {
-    dxgi_adapters.push_back(DXGIAdapter(manifest_path, gpu_preference, known_driver_index, desc1, next_adapter_handle++));
+void PlatformShim::add_dxgi_adapter(GpuType gpu_preference, DXGI_ADAPTER_DESC1 desc1) {
+    dxgi_adapters.push_back(DXGIAdapter(gpu_preference, desc1, next_adapter_handle++));
 }
 
-void PlatformShim::add_d3dkmt_adapter(SHIM_D3DKMT_ADAPTERINFO adapter, fs::path const& path) {
-    d3dkmt_adapters.push_back({adapter, path});
-}
+void PlatformShim::add_d3dkmt_adapter(D3DKMT_Adapter const& adapter) { d3dkmt_adapters.push_back(adapter); }
 
 // TODO:
 void PlatformShim::add_CM_Device_ID(std::wstring const& id, fs::path const& icd_path, fs::path const& layer_path) {
index 9a1c6ee380661bd8f4b2b8678c05443bcb77c2dd..ceed8f5644bd0580c7361af80a19d1d723fe9adf 100644 (file)
@@ -59,11 +59,8 @@ NTSTATUS APIENTRY ShimEnumAdapters2(LoaderEnumAdapters2 *adapters) {
     }
     if (adapters->adapters != nullptr) {
         for (size_t i = 0; i < platform_shim.d3dkmt_adapters.size(); i++) {
-            adapters->adapters[i].handle = platform_shim.d3dkmt_adapters[i].info.hAdapter;
-            adapters->adapters[i].luid = platform_shim.d3dkmt_adapters[i].info.AdapterLuid;
-            adapters->adapters[i].source_count = platform_shim.d3dkmt_adapters[i].info.NumOfSources;
-            adapters->adapters[i].present_move_regions_preferred =
-                platform_shim.d3dkmt_adapters[i].info.bPresentMoveRegionsPreferred;
+            adapters->adapters[i].handle = platform_shim.d3dkmt_adapters[i].hAdapter;
+            adapters->adapters[i].luid = platform_shim.d3dkmt_adapters[i].adapter_luid;
         }
         adapters->adapter_count = static_cast<ULONG>(platform_shim.d3dkmt_adapters.size());
     } else {
@@ -76,23 +73,45 @@ NTSTATUS APIENTRY ShimQueryAdapterInfo(const LoaderQueryAdapterInfo *query_info)
         return STATUS_INVALID_PARAMETER;
     }
     auto handle = query_info->handle;
-    auto it = std::find_if(platform_shim.d3dkmt_adapters.begin(), platform_shim.d3dkmt_adapters.end(),
-                           [handle](const D3DKMT_Adapter &adapter) { return handle == adapter.info.hAdapter; });
+    auto &it = std::find_if(platform_shim.d3dkmt_adapters.begin(), platform_shim.d3dkmt_adapters.end(),
+                            [handle](const D3DKMT_Adapter &adapter) { return handle == adapter.hAdapter; });
     if (it == platform_shim.d3dkmt_adapters.end()) {
         return STATUS_INVALID_PARAMETER;
     }
     auto &adapter = *it;
-
     auto *reg_info = reinterpret_cast<LoaderQueryRegistryInfo *>(query_info->private_data);
+
+    std::vector<std::wstring> *paths = nullptr;
+    if (reg_info->value_name[6] == L'D') {  // looking for drivers
+        paths = &adapter.driver_paths;
+    } else if (reg_info->value_name[6] == L'I') {  // looking for implicit layers
+        paths = &adapter.implicit_layer_paths;
+    } else if (reg_info->value_name[6] == L'E') {  // looking for explicit layers
+        paths = &adapter.explicit_layer_paths;
+    }
+
     reg_info->status = LOADER_QUERY_REGISTRY_STATUS_SUCCESS;
     if (reg_info->output_value_size == 0) {
-        reg_info->output_value_size = static_cast<ULONG>(it->path.size());
-    } else if (reg_info->output_value_size == it->path.size()) {
-        std::wstring path_wstr(1, L'\0');
-        path_wstr.assign(it->path.str().begin(), it->path.str().end());
-        wcscpy(&reg_info->output_string[0], path_wstr.c_str());
-    } else if (reg_info->output_value_size == it->path.size()) {
-        reg_info->status = LOADER_QUERY_REGISTRY_STATUS_BUFFER_OVERFLOW;
+        ULONG size = 2;  // final null terminator
+        for (auto const &path : *paths) size = static_cast<ULONG>(path.length() * sizeof(wchar_t));
+        // size in bytes, so multiply path size by two and add 2 for the null terminator
+        reg_info->output_value_size = size;
+        if (size != 2) {
+            // only want to write data if there is path data to write
+            reg_info->status = LOADER_QUERY_REGISTRY_STATUS_BUFFER_OVERFLOW;
+        }
+    } else if (reg_info->output_value_size > 2) {
+        size_t index = 0;
+        for (auto const &path : *paths) {
+            for (auto w : path) {
+                reg_info->output_string[index++] = w;
+            }
+            reg_info->output_string[index++] = L'\0';
+        }
+        // make sure there is a null terminator
+        reg_info->output_string[index++] = L'\0';
+
+        reg_info->status = LOADER_QUERY_REGISTRY_STATUS_SUCCESS;
     }
 
     return STATUS_SUCCESS;
@@ -228,7 +247,7 @@ HRESULT __stdcall ShimEnumAdapters1_6(IDXGIFactory6 *This,
 HRESULT __stdcall ShimEnumAdapterByGpuPreference(IDXGIFactory6 *This, _In_ UINT Adapter, _In_ DXGI_GPU_PREFERENCE GpuPreference,
                                                  _In_ REFIID riid, _COM_Outptr_ void **ppvAdapter) {
     if (Adapter >= platform_shim.dxgi_adapters.size()) {
-        return DXGI_ERROR_INVALID_CALL;
+        return DXGI_ERROR_NOT_FOUND;
     }
     // loader always uses DXGI_GPU_PREFERENCE_UNSPECIFIED
     // Update the shim if this isn't the case
index 8c2b500ac0a447ae1f818df4dc946cd9a4469fa4..89337e07e333b7f7e5b40dab359508f759924d4f 100644 (file)
@@ -166,6 +166,7 @@ TestICD& TestICDHandle::reset_icd() noexcept {
     return *proc_addr_reset_icd();
 }
 fs::path TestICDHandle::get_icd_full_path() noexcept { return icd_library.lib_path; }
+fs::path TestICDHandle::get_icd_manifest_path() noexcept { return manifest_path; }
 
 TestLayerHandle::TestLayerHandle() noexcept {}
 TestLayerHandle::TestLayerHandle(fs::path const& layer_path) noexcept : layer_library(layer_path) {
@@ -181,6 +182,7 @@ TestLayer& TestLayerHandle::reset_layer() noexcept {
     return *proc_addr_reset_layer();
 }
 fs::path TestLayerHandle::get_layer_full_path() noexcept { return layer_library.lib_path; }
+fs::path TestLayerHandle::get_layer_manifest_path() noexcept { return manifest_path; }
 
 FrameworkEnvironment::FrameworkEnvironment(DebugMode debug_mode, bool override_icds, bool override_explicit_layers) noexcept
     : platform_shim(debug_mode),
@@ -223,6 +225,7 @@ void FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept {
                                                       .set_lib_path(fs::fixup_backslashes_in_path(icd_details.icd_path).str())
                                                       .set_api_version(icd_details.api_version)
                                                       .get_manifest_str());
+    icds.back().manifest_path = driver_loc;
 
     if (icd_details.use_env_var_icd_filenames) {
         if (!env_var_vk_icd_filenames.empty()) {
@@ -236,7 +239,7 @@ void FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept {
         }
         add_env_var_vk_icd_filenames += (icd_folder.location() / full_json_name).str();
         set_env_var("VK_ADD_DRIVER_FILES", add_env_var_vk_icd_filenames);
-    } else {
+    } else if (icd_details.add_manifest_to_default_driver_location) {
         platform_shim->add_manifest(ManifestCategory::icd, driver_loc);
     }
 }
@@ -269,6 +272,7 @@ void FrameworkEnvironment::add_explicit_layer(TestLayerDetails layer_details) no
 
 void FrameworkEnvironment::add_layer_impl(TestLayerDetails layer_details, fs::FolderManager& folder_manager,
                                           ManifestCategory category) {
+    size_t new_layers_start = layers.size();
     for (auto& layer : layer_details.layer_manifest.layers) {
         size_t cur_layer_index = layers.size();
         if (!layer.lib_path.str().empty()) {
@@ -289,12 +293,18 @@ void FrameworkEnvironment::add_layer_impl(TestLayerDetails layer_details, fs::Fo
     if (layer_details.add_to_regular_search_paths) {
         auto layer_loc = folder_manager.write_manifest(layer_details.json_name, layer_details.layer_manifest.get_manifest_str());
         platform_shim->add_manifest(category, layer_loc);
+        for (size_t i = new_layers_start; i < layers.size(); i++) {
+            layers.at(i).manifest_path = layer_loc;
+        }
     }
 }
 
 TestICD& FrameworkEnvironment::get_test_icd(int index) noexcept { return icds[index].get_test_icd(); }
 TestICD& FrameworkEnvironment::reset_icd(int index) noexcept { return icds[index].reset_icd(); }
 fs::path FrameworkEnvironment::get_test_icd_path(int index) noexcept { return icds[index].get_icd_full_path(); }
+fs::path FrameworkEnvironment::get_icd_manifest_path(int index) noexcept { return icds[index].get_icd_manifest_path(); }
 
 TestLayer& FrameworkEnvironment::get_test_layer(int index) noexcept { return layers[index].get_test_layer(); }
-TestLayer& FrameworkEnvironment::reset_layer(int index) noexcept { return layers[index].reset_layer(); }
\ No newline at end of file
+TestLayer& FrameworkEnvironment::reset_layer(int index) noexcept { return layers[index].reset_layer(); }
+fs::path FrameworkEnvironment::get_test_layer_path(int index) noexcept { return layers[index].get_layer_full_path(); }
+fs::path FrameworkEnvironment::get_layer_manifest_path(int index) noexcept { return layers[index].get_layer_manifest_path(); }
\ No newline at end of file
index 5f9355c05acfa806eef3464652f024de1492b7f8..88f816d578951fd4e324a6ba594e8ed582f745f4 100644 (file)
@@ -278,23 +278,27 @@ struct TestICDHandle {
     TestICD& reset_icd() noexcept;
     TestICD& get_test_icd() noexcept;
     fs::path get_icd_full_path() noexcept;
+    fs::path get_icd_manifest_path() noexcept;
 
     // Must use statically
     LibraryWrapper icd_library;
     GetTestICDFunc proc_addr_get_test_icd;
     GetNewTestICDFunc proc_addr_reset_icd;
+    fs::path manifest_path;
 };
 struct TestLayerHandle {
     TestLayerHandle() noexcept;
-    TestLayerHandle(fs::path const& icd_path) noexcept;
+    TestLayerHandle(fs::path const& layer_path) noexcept;
     TestLayer& reset_layer() noexcept;
     TestLayer& get_test_layer() noexcept;
     fs::path get_layer_full_path() noexcept;
+    fs::path get_layer_manifest_path() noexcept;
 
     // Must use statically
     LibraryWrapper layer_library;
     GetTestLayerFunc proc_addr_get_test_layer;
     GetNewTestLayerFunc proc_addr_reset_layer;
+    fs::path manifest_path;
 };
 
 struct TestICDDetails {
@@ -305,6 +309,7 @@ struct TestICDDetails {
     BUILDER_VALUE(TestICDDetails, std::string, json_name, "test_icd");
     BUILDER_VALUE(TestICDDetails, bool, use_env_var_icd_filenames, false);
     BUILDER_VALUE(TestICDDetails, bool, use_add_env_var_icd_filenames, false);
+    BUILDER_VALUE(TestICDDetails, bool, add_manifest_to_default_driver_location, true);
     BUILDER_VALUE(TestICDDetails, bool, is_fake, false);
 };
 
@@ -333,10 +338,12 @@ struct FrameworkEnvironment {
     TestICD& get_test_icd(int index = 0) noexcept;
     TestICD& reset_icd(int index = 0) noexcept;
     fs::path get_test_icd_path(int index = 0) noexcept;
+    fs::path get_icd_manifest_path(int index = 0) noexcept;
 
     TestLayer& get_test_layer(int index = 0) noexcept;
     TestLayer& reset_layer(int index = 0) noexcept;
     fs::path get_test_layer_path(int index = 0) noexcept;
+    fs::path get_layer_manifest_path(int index = 0) noexcept;
 
     PlatformShimWrapper platform_shim;
     fs::FolderManager null_folder;
index de313d843880e30487fe3f1456d933d0c03ca47d..a278c3ad7620e3efa5d7bf812c0a32b3c10a489d 100644 (file)
@@ -476,25 +476,29 @@ TEST_F(EnumeratePhysicalDevices, TwoCallIncomplete) {
 
     std::array<VkPhysicalDevice, real_device_count> physical;
 
+    auto temp_ptr = std::unique_ptr<int>(new int());
+    physical[0] = reinterpret_cast<VkPhysicalDevice>(temp_ptr.get());
+    physical[1] = reinterpret_cast<VkPhysicalDevice>(temp_ptr.get());
+
+    // Use zero for the device count so we can get the VK_INCOMPLETE message and verify nothing was written into physical
+    physical_count = 0;
+    ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDevices(inst, &physical_count, physical.data()));
+    ASSERT_EQ(physical_count, 0);
+    ASSERT_EQ(static_cast<void*>(physical[0]), static_cast<void*>(temp_ptr.get()));
+    ASSERT_EQ(static_cast<void*>(physical[1]), static_cast<void*>(temp_ptr.get()));
+
     // Remove one from the physical device count so we can get the VK_INCOMPLETE message
     physical_count = 1;
-
     ASSERT_EQ(VK_INCOMPLETE, inst->vkEnumeratePhysicalDevices(inst, &physical_count, physical.data()));
     ASSERT_EQ(physical_count, 1);
+    ASSERT_EQ(static_cast<void*>(physical[1]), static_cast<void*>(temp_ptr.get()));
 
     physical_count = 2;
     std::array<VkPhysicalDevice, real_device_count> physical_2;
     ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDevices(inst, &physical_count, physical_2.data()));
 
     // Verify that the first physical device shows up in the list of the second ones
-    bool found = false;
-    for (uint32_t dev = 0; dev < physical_count; ++dev) {
-        if (physical_2[dev] == physical[0]) {
-            found = true;
-            break;
-        }
-    }
-    ASSERT_EQ(true, found);
+    ASSERT_TRUE(std::find(physical_2.begin(), physical_2.end(), physical[0]) != physical_2.end());
 }
 
 TEST_F(EnumeratePhysicalDevices, ZeroPhysicalDevices) {
index 8ef47abe7df7518430952ce0478b058e1e68697a..d90f3d4c047aeea36f1d2e118ca45da51f7a8e85 100644 (file)
@@ -105,17 +105,6 @@ TEST_F(ICDInterfaceVersion2Plus, l5_icd5) {
     // normal.
 }
 
-class ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices : public ::testing::Test {
-   protected:
-    virtual void SetUp() {
-        env = std::unique_ptr<FrameworkEnvironment>(new FrameworkEnvironment());
-        env->add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES));
-    }
-
-    virtual void TearDown() { env.reset(); }
-    std::unique_ptr<FrameworkEnvironment> env;
-};
-
 // Need more work to shim dxgi for this test to work
 #if defined(WIN32)
 // Version 6 provides a mechanism to allow the loader to sort physical devices.
@@ -137,213 +126,179 @@ TEST_F(ICDInterfaceVersion2Plus, version_5) {
     ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count,
                                                                            physical_device_handles.data()));
     ASSERT_EQ(physical_count, returned_physical_count);
-    ASSERT_EQ(driver.called_enumerate_adapter_physical_devices, CalledEnumerateAdapterPhysicalDevices::not_called);
+    ASSERT_FALSE(driver.called_enumerate_adapter_physical_devices);
 }
-TEST_F(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, version_6) {
+TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, version_6) {
+    FrameworkEnvironment env{};
+    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES, VK_API_VERSION_1_3}
+                    .set_add_manifest_to_default_driver_location(false));
     // Version 6 provides a mechanism to allow the loader to sort physical devices.
     // The loader will only attempt to sort physical devices on an ICD if version 6 of the interface is supported.
     // This version provides the vk_icdEnumerateAdapterPhysicalDevices function.
-    auto& driver = env->get_test_icd();
+    auto& driver = env.get_test_icd(0);
     driver.physical_devices.emplace_back("physical_device_1");
     driver.physical_devices.emplace_back("physical_device_0");
-    uint32_t physical_count = static_cast<uint32_t>(driver.physical_devices.size());
-    uint32_t returned_physical_count = static_cast<uint32_t>(driver.physical_devices.size());
-    std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
+    uint32_t physical_count = 2;
+    uint32_t returned_physical_count = physical_count;
+    std::vector<VkPhysicalDevice> physical_device_handles{physical_count};
 
     driver.min_icd_interface_version = 6;
 
-    uint32_t driver_index = 2;  // which drive this test pretends to be
-    auto& known_driver = known_driver_list.at(2);
+    auto& known_driver = known_driver_list.at(2);  // which drive this test pretends to be
     DXGI_ADAPTER_DESC1 desc1{};
-    wcsncpy_s(&desc1.Description[0], 128, L"TestDriver1", 128);
+    desc1.AdapterLuid = _LUID{10, 1000};
     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);
+    env.platform_shim->add_dxgi_adapter(GpuType::discrete, desc1);
+    driver.set_adapterLUID(desc1.AdapterLuid);
 
-    InstWrapper inst{env->vulkan_functions};
+    env.platform_shim->add_d3dkmt_adapter(
+        D3DKMT_Adapter{0, desc1.AdapterLuid}.add_driver_manifest_path(env.get_icd_manifest_path(0)));
+
+    InstWrapper inst{env.vulkan_functions};
     inst.CheckCreate();
 
-    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, nullptr));
+    ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, nullptr));
     ASSERT_EQ(physical_count, returned_physical_count);
-    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count,
-                                                                           physical_device_handles.data()));
+    ASSERT_EQ(VK_SUCCESS,
+              env.vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, physical_device_handles.data()));
     ASSERT_EQ(physical_count, returned_physical_count);
-    ASSERT_EQ(driver.called_enumerate_adapter_physical_devices, CalledEnumerateAdapterPhysicalDevices::called);
+    ASSERT_TRUE(driver.called_enumerate_adapter_physical_devices);
+
+    // Make sure that the loader doesn't write past the the end of the pointer
+    auto temp_ptr = std::unique_ptr<int>(new int());
+    for (auto& phys_dev : physical_device_handles) {
+        phys_dev = reinterpret_cast<VkPhysicalDevice>(temp_ptr.get());
+    }
+
+    ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, nullptr));
+    returned_physical_count = 0;
+    ASSERT_EQ(VK_INCOMPLETE,
+              env.vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, physical_device_handles.data()));
+    ASSERT_EQ(0, returned_physical_count);
+    for (auto& phys_dev : physical_device_handles) {
+        ASSERT_EQ(phys_dev, reinterpret_cast<VkPhysicalDevice>(temp_ptr.get()));
+    }
 }
 
-TEST_F(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, EnumAdapters2) {
-    InstWrapper inst{env->vulkan_functions};
-    auto& driver = env->get_test_icd();
+TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, EnumAdapters2) {
+    FrameworkEnvironment env{};
+    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES}
+                    .set_add_manifest_to_default_driver_location(false));
+    InstWrapper inst{env.vulkan_functions};
+    auto& driver = env.get_test_icd();
     driver.physical_devices.emplace_back("physical_device_1");
     driver.physical_devices.emplace_back("physical_device_0");
     uint32_t physical_count = static_cast<uint32_t>(driver.physical_devices.size());
     uint32_t returned_physical_count = static_cast<uint32_t>(driver.physical_devices.size());
     std::vector<VkPhysicalDevice> physical_device_handles = std::vector<VkPhysicalDevice>(physical_count);
 
-    SHIM_D3DKMT_ADAPTERINFO d3dkmt_adapter_info{};
-    d3dkmt_adapter_info.hAdapter = 0;  //
-    d3dkmt_adapter_info.AdapterLuid = _LUID{10, 1000};
-    d3dkmt_adapter_info.NumOfSources = 1;
-    d3dkmt_adapter_info.bPresentMoveRegionsPreferred = true;
-
-    env->platform_shim->add_d3dkmt_adapter(d3dkmt_adapter_info, env->get_test_icd_path());
+    env.platform_shim->add_d3dkmt_adapter(D3DKMT_Adapter{0, _LUID{10, 1000}}.add_driver_manifest_path(env.get_icd_manifest_path()));
 
     inst.CheckCreate();
 
-    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, nullptr));
+    ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, nullptr));
     ASSERT_EQ(physical_count, returned_physical_count);
-    ASSERT_EQ(VK_SUCCESS, env->vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count,
-                                                                           physical_device_handles.data()));
+    ASSERT_EQ(VK_SUCCESS,
+              env.vulkan_functions.vkEnumeratePhysicalDevices(inst.inst, &returned_physical_count, physical_device_handles.data()));
     ASSERT_EQ(physical_count, returned_physical_count);
+    ASSERT_FALSE(driver.called_enumerate_adapter_physical_devices);
 }
 
-TEST_F(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, VerifyPhysDevResults) {
-    auto& driver = env->get_test_icd();
+TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, VerifyPhysDevResults) {
+    FrameworkEnvironment env{};
+    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES}
+                    .set_add_manifest_to_default_driver_location(false));
+    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);
+    const std::vector<std::string> physical_device_names = {"physical_device_4", "physical_device_3", "physical_device_2",
+                                                            "physical_device_1", "physical_device_0"};
+    for (const auto& dev_name : physical_device_names) driver.physical_devices.push_back(dev_name);
 
-    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);
+    auto& known_driver = known_driver_list.at(2);  // which drive this test pretends to be
     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);
+    desc1.AdapterLuid = _LUID{10, 1000};
+    env.platform_shim->add_dxgi_adapter(GpuType::discrete, desc1);
+    env.get_test_icd().set_adapterLUID(desc1.AdapterLuid);
 
-    InstWrapper inst2{env->vulkan_functions};
-    inst2.CheckCreate();
+    env.platform_shim->add_d3dkmt_adapter(D3DKMT_Adapter{0, _LUID{10, 1000}}.add_driver_manifest_path(env.get_icd_manifest_path()));
 
-    // For the test ICD, when the D3D Adapter mechanism is enabled, it should completely swap the order of devices.
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+
+    const size_t phys_dev_count = physical_device_names.size();
+
+    // The test ICD 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()));
+    std::vector<VkPhysicalDevice> adapter_pds{phys_dev_count};
+    uint32_t count = static_cast<uint32_t>(adapter_pds.size());
+    ASSERT_EQ(VK_SUCCESS, env.vulkan_functions.vkEnumeratePhysicalDevices(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()));
+        env.vulkan_functions.vkGetPhysicalDeviceProperties(adapter_pds[dev], &props);
+        std::string dev_name = props.deviceName;
+        // index in reverse
+        ASSERT_EQ(dev_name, physical_device_names[physical_device_names.size() - 1 - dev]);
     }
 }
 
-TEST_F(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, VerifyGroupResults) {
-    auto& driver = env->get_test_icd();
+TEST(ICDInterfaceVersion2PlusEnumerateAdapterPhysicalDevices, VerifyGroupResults) {
+    FrameworkEnvironment env{};
+    env.add_icd(TestICDDetails{TEST_ICD_PATH_VERSION_2_EXPORT_ICD_ENUMERATE_ADAPTER_PHYSICAL_DEVICES}
+                    .set_add_manifest_to_default_driver_location(false));
+    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");
+    const std::vector<std::string> physical_device_names = {"physical_device_4", "physical_device_3", "physical_device_2",
+                                                            "physical_device_1", "physical_device_0"};
+    for (const auto& dev_name : physical_device_names) driver.physical_devices.push_back(dev_name);
+
     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);
+    auto& known_driver = known_driver_list.at(2);  // which driver this test pretends to be
     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);
+    desc1.AdapterLuid = _LUID{10, 1000};
+    env.platform_shim->add_dxgi_adapter(GpuType::discrete, desc1);
+    env.get_test_icd().set_adapterLUID(desc1.AdapterLuid);
 
-    InstWrapper inst2{env->vulkan_functions};
-    inst2.CheckCreate();
+    env.platform_shim->add_d3dkmt_adapter(D3DKMT_Adapter{0, _LUID{10, 1000}}.add_driver_manifest_path(env.get_icd_manifest_path()));
 
-    // For the test ICD, when the D3D Adapter mechanism is enabled, it should completely swap the order of devices.
+    InstWrapper inst{env.vulkan_functions};
+    inst.CheckCreate();
+
+    // The test ICD 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);
-
+    const uint32_t actual_group_count = 3;
+    uint32_t count = actual_group_count;
+    std::array<VkPhysicalDeviceGroupProperties, actual_group_count> groups{};
     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;
+        groups[group].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES;
     }
-    ASSERT_EQ(VK_SUCCESS, inst2->vkEnumeratePhysicalDeviceGroups(inst2, &count, adapter_groups.data()));
+    ASSERT_EQ(VK_SUCCESS, inst->vkEnumeratePhysicalDeviceGroups(inst, &count, groups.data()));
     ASSERT_EQ(actual_group_count, count);
 
+    size_t cur_device_name_index = physical_device_names.size() - 1;  // start at last index and reverse through it
     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) {
+        for (uint32_t dev = 0; dev < 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()));
+            env.vulkan_functions.vkGetPhysicalDeviceProperties(groups[group].physicalDevices[dev], &props);
+            std::string dev_name = props.deviceName;
+            ASSERT_EQ(dev_name, physical_device_names[cur_device_name_index]);
+            cur_device_name_index--;
         }
     }
 }