From fcf23873982e7dbef93eade2fd14409a90512deb Mon Sep 17 00:00:00 2001 From: Mateusz Jablonski Date: Thu, 3 Oct 2019 15:33:18 +0200 Subject: [PATCH] Add tests for selecting KMD adapter Related-To: NEO-3007 Change-Id: I040662e68dccf574b14ecffa02f5427f6ef1899b Signed-off-by: Mateusz Jablonski --- runtime/os_interface/windows/sys_calls.cpp | 7 +- runtime/os_interface/windows/sys_calls.h | 2 + runtime/os_interface/windows/wddm/wddm.cpp | 9 +-- unit_tests/os_interface/windows/sys_calls.cpp | 18 ++++- .../os_interface/windows/ult_dxgi_factory.cpp | 2 + .../os_interface/windows/ult_dxgi_factory.h | 3 +- .../os_interface/windows/wddm20_tests.cpp | 72 +++++++++++++++++++ 7 files changed, 106 insertions(+), 7 deletions(-) diff --git a/runtime/os_interface/windows/sys_calls.cpp b/runtime/os_interface/windows/sys_calls.cpp index 2256c6271c..9499f524c1 100644 --- a/runtime/os_interface/windows/sys_calls.cpp +++ b/runtime/os_interface/windows/sys_calls.cpp @@ -22,7 +22,12 @@ BOOL closeHandle(HANDLE hObject) { BOOL getSystemPowerStatus(LPSYSTEM_POWER_STATUS systemPowerStatusPtr) { return GetSystemPowerStatus(systemPowerStatusPtr); } - +BOOL getModuleHandle(DWORD dwFlags, LPCWSTR lpModuleName, HMODULE *phModule) { + return GetModuleHandleEx(dwFlags, lpModuleName, phModule); +} +DWORD getModuleFileName(HMODULE hModule, LPWSTR lpFilename, DWORD nSize) { + return GetModuleFileName(hModule, lpFilename, nSize); +} } // namespace SysCalls } // namespace NEO diff --git a/runtime/os_interface/windows/sys_calls.h b/runtime/os_interface/windows/sys_calls.h index 4a5c721ff0..9bea6f998c 100644 --- a/runtime/os_interface/windows/sys_calls.h +++ b/runtime/os_interface/windows/sys_calls.h @@ -15,6 +15,8 @@ namespace SysCalls { HANDLE createEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName); BOOL closeHandle(HANDLE hObject); BOOL getSystemPowerStatus(LPSYSTEM_POWER_STATUS systemPowerStatusPtr); +BOOL getModuleHandle(DWORD dwFlags, LPCWSTR lpModuleName, HMODULE *phModule); +DWORD getModuleFileName(HMODULE hModule, LPWSTR lpFilename, DWORD nSize); } // namespace SysCalls diff --git a/runtime/os_interface/windows/wddm/wddm.cpp b/runtime/os_interface/windows/wddm/wddm.cpp index 38f152a57f..e3ecdb5b45 100644 --- a/runtime/os_interface/windows/wddm/wddm.cpp +++ b/runtime/os_interface/windows/wddm/wddm.cpp @@ -21,6 +21,7 @@ #include "runtime/os_interface/windows/gdi_interface.h" #include "runtime/os_interface/windows/kmdaf_listener.h" #include "runtime/os_interface/windows/os_context_win.h" +#include "runtime/os_interface/windows/sys_calls.h" #include "runtime/os_interface/windows/wddm/wddm_interface.h" #include "runtime/os_interface/windows/wddm_allocation.h" #include "runtime/os_interface/windows/wddm_engine_mapper.h" @@ -35,12 +36,12 @@ std::wstring getIgdrclPath() { WCHAR path[255]; HMODULE handle = NULL; - auto status = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | - GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - (LPCWSTR)(&clGetPlatformIDs), &handle); + auto status = NEO::SysCalls::getModuleHandle(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + reinterpret_cast(&getIgdrclPath), &handle); if (status != 0) { - status = GetModuleFileName(handle, path, sizeof(path)); + status = NEO::SysCalls::getModuleFileName(handle, path, sizeof(path)); if (status != 0) { returnValue.append(path); } diff --git a/unit_tests/os_interface/windows/sys_calls.cpp b/unit_tests/os_interface/windows/sys_calls.cpp index 4aa953d9ad..a1a9c10187 100644 --- a/unit_tests/os_interface/windows/sys_calls.cpp +++ b/unit_tests/os_interface/windows/sys_calls.cpp @@ -15,6 +15,8 @@ constexpr uintptr_t dummyHandle = static_cast(0x7); BOOL systemPowerStatusRetVal = 1; BYTE systemPowerStatusACLineStatusOverride = 1; +HMODULE handleValue = reinterpret_cast(dummyHandle); +const wchar_t *igdrclFilePath = L""; HANDLE createEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName) { return reinterpret_cast(dummyHandle); @@ -28,7 +30,21 @@ BOOL getSystemPowerStatus(LPSYSTEM_POWER_STATUS systemPowerStatusPtr) { systemPowerStatusPtr->ACLineStatus = systemPowerStatusACLineStatusOverride; return systemPowerStatusRetVal; } - +BOOL getModuleHandle(DWORD dwFlags, LPCWSTR lpModuleName, HMODULE *phModule) { + constexpr auto expectedFlags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT; + if (dwFlags != expectedFlags) { + return FALSE; + } + *phModule = handleValue; + return TRUE; +} +DWORD getModuleFileName(HMODULE hModule, LPWSTR lpFilename, DWORD nSize) { + if (hModule != handleValue) { + return FALSE; + } + lstrcpyW(lpFilename, igdrclFilePath); + return TRUE; +} } // namespace SysCalls } // namespace NEO diff --git a/unit_tests/os_interface/windows/ult_dxgi_factory.cpp b/unit_tests/os_interface/windows/ult_dxgi_factory.cpp index 98ddc8d8e2..1f551bbcf9 100644 --- a/unit_tests/os_interface/windows/ult_dxgi_factory.cpp +++ b/unit_tests/os_interface/windows/ult_dxgi_factory.cpp @@ -22,4 +22,6 @@ void WINAPI ULTGetSystemInfo(SYSTEM_INFO *pSystemInfo) { pSystemInfo->lpMaximumApplicationAddress = is32bit ? (LPVOID)MemoryConstants::max32BitAppAddress : (LPVOID)MemoryConstants::max64BitAppAddress; } +const wchar_t *UltIDXGIAdapter1::description = L"Intel"; + } // namespace NEO diff --git a/unit_tests/os_interface/windows/ult_dxgi_factory.h b/unit_tests/os_interface/windows/ult_dxgi_factory.h index 0603dae1b1..70cdd2b9e0 100644 --- a/unit_tests/os_interface/windows/ult_dxgi_factory.h +++ b/unit_tests/os_interface/windows/ult_dxgi_factory.h @@ -15,6 +15,7 @@ namespace NEO { class UltIDXGIAdapter1 : public IDXGIAdapter1 { public: + const static wchar_t *description; // IDXGIAdapter1 HRESULT STDMETHODCALLTYPE GetDesc1( _Out_ DXGI_ADAPTER_DESC1 *pDesc) { @@ -22,7 +23,7 @@ class UltIDXGIAdapter1 : public IDXGIAdapter1 { if (pDesc == nullptr) { return S_FALSE; } - swprintf(pDesc->Description, 128, L"Intel"); + swprintf(pDesc->Description, 128, description); pDesc->AdapterLuid.HighPart = 0x1234; pDesc->DeviceId = 0x1234; return S_OK; diff --git a/unit_tests/os_interface/windows/wddm20_tests.cpp b/unit_tests/os_interface/windows/wddm20_tests.cpp index f63ce66dee..4ebed74ddc 100644 --- a/unit_tests/os_interface/windows/wddm20_tests.cpp +++ b/unit_tests/os_interface/windows/wddm20_tests.cpp @@ -20,10 +20,12 @@ #include "runtime/os_interface/windows/wddm_allocation.h" #include "runtime/os_interface/windows/wddm_engine_mapper.h" #include "runtime/os_interface/windows/wddm_memory_manager.h" +#include "unit_tests/helpers/variable_backup.h" #include "unit_tests/mocks/mock_gfx_partition.h" #include "unit_tests/mocks/mock_gmm_resource_info.h" #include "unit_tests/mocks/mock_memory_manager.h" #include "unit_tests/os_interface/windows/mock_wddm_allocation.h" +#include "unit_tests/os_interface/windows/ult_dxgi_factory.h" #include "unit_tests/os_interface/windows/wddm_fixture.h" #include "gtest/gtest.h" @@ -31,6 +33,12 @@ #include #include +namespace NEO { +namespace SysCalls { +extern const wchar_t *igdrclFilePath; +} +} // namespace NEO + using namespace NEO; namespace GmmHelperFunctions { @@ -84,6 +92,70 @@ TEST_F(Wddm20Tests, givenNullPageTableManagerAndRenderCompressedResourceWhenMapp EXPECT_TRUE(wddm->mapGpuVirtualAddress(&allocation)); } +TEST(Wddm20EnumAdaptersTest, WhenAdapterDescriptionContainsDCHDAndgdrclPathDoesntContainDchDThenAdapterIsNotOpened) { + VariableBackup descriptionBackup(&UltIDXGIAdapter1::description); + descriptionBackup = L"Intel DCH-D"; + VariableBackup igdrclPathBackup(&SysCalls::igdrclFilePath); + igdrclPathBackup = L"intel_dch.inf"; + + struct MockWddm : Wddm { + using Wddm::openAdapter; + }; + + MockWddm wddm; + bool isOpened = wddm.openAdapter(); + + EXPECT_FALSE(isOpened); +} + +TEST(Wddm20EnumAdaptersTest, WhenAdapterDescriptionContainsDCHIAndgdrclPathDoesntContainDchIThenAdapterIsNotOpened) { + VariableBackup descriptionBackup(&UltIDXGIAdapter1::description); + descriptionBackup = L"Intel DCH-I"; + VariableBackup igdrclPathBackup(&SysCalls::igdrclFilePath); + igdrclPathBackup = L"intel_dch.inf"; + + struct MockWddm : Wddm { + using Wddm::openAdapter; + }; + + auto wddm = std::make_unique(); + bool isOpened = wddm->openAdapter(); + + EXPECT_FALSE(isOpened); +} + +TEST(Wddm20EnumAdaptersTest, WhenAdapterDescriptionContainsDCHDAndgdrclPathContainsDchDThenAdapterIsOpened) { + VariableBackup descriptionBackup(&UltIDXGIAdapter1::description); + descriptionBackup = L"Intel DCH-D"; + VariableBackup igdrclPathBackup(&SysCalls::igdrclFilePath); + igdrclPathBackup = L"intel_dch_d.inf"; + + struct MockWddm : Wddm { + using Wddm::openAdapter; + }; + + auto wddm = std::make_unique(); + bool isOpened = wddm->openAdapter(); + + EXPECT_TRUE(isOpened); +} + +TEST(Wddm20EnumAdaptersTest, WhenAdapterDescriptionContainsDCHIAndgdrclPathContainsDchIThenAdapterIsOpened) { + VariableBackup descriptionBackup(&UltIDXGIAdapter1::description); + descriptionBackup = L"Intel DCH-I"; + VariableBackup igdrclPathBackup(&SysCalls::igdrclFilePath); + igdrclPathBackup = L"intel_dch_i.inf"; + + struct MockWddm : Wddm { + using Wddm::openAdapter; + }; + + auto wddm = std::make_unique(); + bool isOpened = wddm->openAdapter(); + + EXPECT_TRUE(isOpened); +} + TEST(Wddm20EnumAdaptersTest, expectTrue) { HardwareInfo outHwInfo;