diff options
author | Charles Giessen <charles@lunarg.com> | 2022-03-25 02:22:16 +0300 |
---|---|---|
committer | Charles Giessen <46324611+charles-lunarg@users.noreply.github.com> | 2022-03-25 04:00:28 +0300 |
commit | ea503f36e64f90dd52b2b3b7f7fd88fa62b61d3c (patch) | |
tree | e98e87f7563a0983202f9e08c5441fec3cefbdb9 | |
parent | 2d1860d23819e7162beb3cc66fd32c82af462b76 (diff) |
Fixup windows test infrastructure
Cleaned up several bugs in the testing framework in the windows shim.
Rewrote the tests that exercise DXGI/D3DKMT functionality.
-rw-r--r-- | tests/framework/icd/test_icd.cpp | 19 | ||||
-rw-r--r-- | tests/framework/icd/test_icd.h | 9 | ||||
-rw-r--r-- | tests/framework/layer/test_layer.h | 2 | ||||
-rw-r--r-- | tests/framework/shim/shim.h | 38 | ||||
-rw-r--r-- | tests/framework/shim/shim_common.cpp | 25 | ||||
-rw-r--r-- | tests/framework/shim/windows_shim.cpp | 51 | ||||
-rw-r--r-- | tests/framework/test_environment.cpp | 14 | ||||
-rw-r--r-- | tests/framework/test_environment.h | 9 | ||||
-rw-r--r-- | tests/loader_regression_tests.cpp | 22 | ||||
-rw-r--r-- | tests/loader_version_tests.cpp | 249 |
10 files changed, 221 insertions, 217 deletions
diff --git a/tests/framework/icd/test_icd.cpp b/tests/framework/icd/test_icd.cpp index 0d365322c..0387a4894 100644 --- a/tests/framework/icd/test_icd.cpp +++ b/tests/framework/icd/test_icd.cpp @@ -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; } diff --git a/tests/framework/icd/test_icd.h b/tests/framework/icd/test_icd.h index a55d15200..884e334ef 100644 --- a/tests/framework/icd/test_icd.h +++ b/tests/framework/icd/test_icd.h @@ -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* (*)(); diff --git a/tests/framework/layer/test_layer.h b/tests/framework/layer/test_layer.h index df32ce5db..75cd10741 100644 --- a/tests/framework/layer/test_layer.h +++ b/tests/framework/layer/test_layer.h @@ -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) diff --git a/tests/framework/shim/shim.h b/tests/framework/shim/shim.h index 7452fd9b2..7498f51c1 100644 --- a/tests/framework/shim/shim.h +++ b/tests/framework/shim/shim.h @@ -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; diff --git a/tests/framework/shim/shim_common.cpp b/tests/framework/shim/shim_common.cpp index 57152b4cf..31c61c273 100644 --- a/tests/framework/shim/shim_common.cpp +++ b/tests/framework/shim/shim_common.cpp @@ -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) { diff --git a/tests/framework/shim/windows_shim.cpp b/tests/framework/shim/windows_shim.cpp index 9a1c6ee38..ceed8f564 100644 --- a/tests/framework/shim/windows_shim.cpp +++ b/tests/framework/shim/windows_shim.cpp @@ -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(®_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 diff --git a/tests/framework/test_environment.cpp b/tests/framework/test_environment.cpp index 8c2b500ac..89337e07e 100644 --- a/tests/framework/test_environment.cpp +++ b/tests/framework/test_environment.cpp @@ -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 diff --git a/tests/framework/test_environment.h b/tests/framework/test_environment.h index 5f9355c05..88f816d57 100644 --- a/tests/framework/test_environment.h +++ b/tests/framework/test_environment.h @@ -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; diff --git a/tests/loader_regression_tests.cpp b/tests/loader_regression_tests.cpp index de313d843..a278c3ad7 100644 --- a/tests/loader_regression_tests.cpp +++ b/tests/loader_regression_tests.cpp @@ -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) { diff --git a/tests/loader_version_tests.cpp b/tests/loader_version_tests.cpp index 8ef47abe7..d90f3d4c0 100644 --- a/tests/loader_version_tests.cpp +++ b/tests/loader_version_tests.cpp @@ -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--; } } } |