2017-12-21 07:45:38 +08:00
|
|
|
/*
|
2019-12-23 21:28:33 +08:00
|
|
|
* Copyright (C) 2017-2020 Intel Corporation
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
2018-09-18 15:11:08 +08:00
|
|
|
* SPDX-License-Identifier: MIT
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2019-11-07 01:14:30 +08:00
|
|
|
#include "core/execution_environment/root_device_environment.h"
|
2020-01-09 23:10:48 +08:00
|
|
|
#include "core/gmm_helper/gmm.h"
|
2019-12-04 19:36:16 +08:00
|
|
|
#include "core/gmm_helper/gmm_helper.h"
|
2019-11-29 22:41:47 +08:00
|
|
|
#include "core/helpers/hw_info.h"
|
2019-12-09 22:29:30 +08:00
|
|
|
#include "core/helpers/options.h"
|
2019-11-19 18:49:19 +08:00
|
|
|
#include "core/os_interface/os_library.h"
|
2020-01-21 22:24:52 +08:00
|
|
|
#include "core/os_interface/os_time.h"
|
2020-01-13 21:47:05 +08:00
|
|
|
#include "core/os_interface/windows/wddm_allocation.h"
|
2019-12-11 19:29:46 +08:00
|
|
|
#include "core/os_interface/windows/wddm_engine_mapper.h"
|
2019-07-15 19:51:08 +08:00
|
|
|
#include "core/unit_tests/helpers/debug_manager_state_restore.h"
|
2018-07-03 16:00:12 +08:00
|
|
|
#include "runtime/execution_environment/execution_environment.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
#include "runtime/memory_manager/os_agnostic_memory_manager.h"
|
2018-08-21 23:36:08 +08:00
|
|
|
#include "runtime/os_interface/windows/os_context_win.h"
|
2019-02-13 00:27:13 +08:00
|
|
|
#include "runtime/os_interface/windows/os_interface.h"
|
2019-02-27 18:39:32 +08:00
|
|
|
#include "runtime/os_interface/windows/wddm/wddm_interface.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
#include "runtime/os_interface/windows/wddm_memory_manager.h"
|
2019-10-03 21:33:18 +08:00
|
|
|
#include "unit_tests/helpers/variable_backup.h"
|
2019-11-07 01:14:30 +08:00
|
|
|
#include "unit_tests/mocks/mock_execution_environment.h"
|
2019-03-01 23:14:28 +08:00
|
|
|
#include "unit_tests/mocks/mock_gfx_partition.h"
|
2018-05-08 02:42:00 +08:00
|
|
|
#include "unit_tests/mocks/mock_gmm_resource_info.h"
|
2019-03-15 17:22:35 +08:00
|
|
|
#include "unit_tests/mocks/mock_memory_manager.h"
|
2019-03-06 15:39:06 +08:00
|
|
|
#include "unit_tests/os_interface/windows/mock_wddm_allocation.h"
|
2019-10-03 21:33:18 +08:00
|
|
|
#include "unit_tests/os_interface/windows/ult_dxgi_factory.h"
|
2019-02-13 00:27:13 +08:00
|
|
|
#include "unit_tests/os_interface/windows/wddm_fixture.h"
|
2019-02-27 18:39:32 +08:00
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
#include "gtest/gtest.h"
|
|
|
|
|
2018-02-28 23:52:08 +08:00
|
|
|
#include <functional>
|
2019-02-27 18:39:32 +08:00
|
|
|
#include <memory>
|
2018-02-28 23:52:08 +08:00
|
|
|
|
2019-10-03 21:33:18 +08:00
|
|
|
namespace NEO {
|
|
|
|
namespace SysCalls {
|
|
|
|
extern const wchar_t *igdrclFilePath;
|
|
|
|
}
|
|
|
|
} // namespace NEO
|
|
|
|
|
2019-03-26 18:59:46 +08:00
|
|
|
using namespace NEO;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-05-08 02:42:00 +08:00
|
|
|
namespace GmmHelperFunctions {
|
|
|
|
Gmm *getGmm(void *ptr, size_t size) {
|
|
|
|
size_t alignedSize = alignSizeWholePage(ptr, size);
|
|
|
|
void *alignedPtr = alignUp(ptr, 4096);
|
|
|
|
|
2019-12-30 21:14:27 +08:00
|
|
|
Gmm *gmm = new Gmm(platform()->peekExecutionEnvironment()->getGmmClientContext(), alignedPtr, alignedSize, false);
|
2018-05-08 02:42:00 +08:00
|
|
|
EXPECT_NE(gmm->gmmResourceInfo.get(), nullptr);
|
|
|
|
return gmm;
|
|
|
|
}
|
|
|
|
} // namespace GmmHelperFunctions
|
|
|
|
|
2018-05-15 18:13:16 +08:00
|
|
|
using Wddm20Tests = WddmTest;
|
2018-08-24 15:27:00 +08:00
|
|
|
using Wddm20WithMockGdiDllTestsWithoutWddmInit = WddmTestWithMockGdiDll;
|
2018-05-15 18:13:16 +08:00
|
|
|
using Wddm20InstrumentationTest = WddmInstrumentationTest;
|
|
|
|
|
2018-08-24 15:27:00 +08:00
|
|
|
struct Wddm20WithMockGdiDllTests : public Wddm20WithMockGdiDllTestsWithoutWddmInit {
|
|
|
|
using Wddm20WithMockGdiDllTestsWithoutWddmInit::TearDown;
|
|
|
|
void SetUp() override {
|
|
|
|
Wddm20WithMockGdiDllTestsWithoutWddmInit::SetUp();
|
2018-08-27 21:48:29 +08:00
|
|
|
init();
|
2018-08-24 15:27:00 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, givenMinWindowsAddressWhenWddmIsInitializedThenWddmUseThisAddress) {
|
2018-02-09 05:52:58 +08:00
|
|
|
uintptr_t expectedAddress = 0x200000;
|
2019-03-26 18:59:46 +08:00
|
|
|
EXPECT_EQ(expectedAddress, NEO::windowsMinAddress);
|
2018-02-12 23:53:20 +08:00
|
|
|
EXPECT_EQ(expectedAddress, wddm->getWddmMinAddress());
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, doubleCreation) {
|
2018-05-08 02:42:00 +08:00
|
|
|
EXPECT_EQ(1u, wddm->createContextResult.called);
|
2019-07-08 19:30:31 +08:00
|
|
|
auto hwInfo = *platformDevices[0];
|
|
|
|
wddm->init(hwInfo);
|
2018-05-08 02:42:00 +08:00
|
|
|
EXPECT_EQ(1u, wddm->createContextResult.called);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-10-03 01:10:29 +08:00
|
|
|
TEST_F(Wddm20Tests, givenNullPageTableManagerAndRenderCompressedResourceWhenMappingGpuVaThenDontUpdateAuxTable) {
|
2019-12-30 21:14:27 +08:00
|
|
|
auto gmm = std::unique_ptr<Gmm>(new Gmm(executionEnvironment->getGmmClientContext(), nullptr, 1, false));
|
2018-01-25 22:10:07 +08:00
|
|
|
auto mockGmmRes = reinterpret_cast<MockGmmResourceInfo *>(gmm->gmmResourceInfo.get());
|
|
|
|
mockGmmRes->setUnifiedAuxTranslationCapable();
|
|
|
|
|
2018-10-03 01:10:29 +08:00
|
|
|
void *fakePtr = reinterpret_cast<void *>(0x100);
|
2019-11-04 23:03:30 +08:00
|
|
|
WddmAllocation allocation(0, GraphicsAllocation::AllocationType::UNKNOWN, fakePtr, 0x2100, nullptr, MemoryPool::MemoryNull);
|
2019-03-12 20:24:58 +08:00
|
|
|
allocation.setDefaultGmm(gmm.get());
|
2019-03-05 16:25:18 +08:00
|
|
|
allocation.getHandleToModify(0u) = ALLOCATION_HANDLE;
|
2018-10-03 01:10:29 +08:00
|
|
|
|
2019-03-18 17:06:01 +08:00
|
|
|
EXPECT_TRUE(wddm->mapGpuVirtualAddress(&allocation));
|
2018-01-25 22:10:07 +08:00
|
|
|
}
|
|
|
|
|
2019-10-03 21:33:18 +08:00
|
|
|
TEST(Wddm20EnumAdaptersTest, WhenAdapterDescriptionContainsDCHDAndgdrclPathDoesntContainDchDThenAdapterIsNotOpened) {
|
|
|
|
VariableBackup<const wchar_t *> descriptionBackup(&UltIDXGIAdapter1::description);
|
|
|
|
descriptionBackup = L"Intel DCH-D";
|
|
|
|
VariableBackup<const wchar_t *> igdrclPathBackup(&SysCalls::igdrclFilePath);
|
|
|
|
igdrclPathBackup = L"intel_dch.inf";
|
|
|
|
|
|
|
|
struct MockWddm : Wddm {
|
|
|
|
using Wddm::openAdapter;
|
|
|
|
|
2019-11-07 01:14:30 +08:00
|
|
|
MockWddm(RootDeviceEnvironment &rootDeviceEnvironment) : Wddm(rootDeviceEnvironment) {}
|
|
|
|
};
|
|
|
|
MockExecutionEnvironment executionEnvironment;
|
|
|
|
RootDeviceEnvironment rootDeviceEnvironment(executionEnvironment);
|
|
|
|
auto wddm = std::make_unique<MockWddm>(rootDeviceEnvironment);
|
|
|
|
bool isOpened = wddm->openAdapter();
|
2019-10-03 21:33:18 +08:00
|
|
|
|
|
|
|
EXPECT_FALSE(isOpened);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(Wddm20EnumAdaptersTest, WhenAdapterDescriptionContainsDCHIAndgdrclPathDoesntContainDchIThenAdapterIsNotOpened) {
|
|
|
|
VariableBackup<const wchar_t *> descriptionBackup(&UltIDXGIAdapter1::description);
|
|
|
|
descriptionBackup = L"Intel DCH-I";
|
|
|
|
VariableBackup<const wchar_t *> igdrclPathBackup(&SysCalls::igdrclFilePath);
|
|
|
|
igdrclPathBackup = L"intel_dch.inf";
|
|
|
|
|
|
|
|
struct MockWddm : Wddm {
|
|
|
|
using Wddm::openAdapter;
|
|
|
|
|
2019-11-07 01:14:30 +08:00
|
|
|
MockWddm(RootDeviceEnvironment &rootDeviceEnvironment) : Wddm(rootDeviceEnvironment) {}
|
|
|
|
};
|
|
|
|
MockExecutionEnvironment executionEnvironment;
|
|
|
|
RootDeviceEnvironment rootDeviceEnvironment(executionEnvironment);
|
|
|
|
auto wddm = std::make_unique<MockWddm>(rootDeviceEnvironment);
|
2019-10-03 21:33:18 +08:00
|
|
|
bool isOpened = wddm->openAdapter();
|
|
|
|
|
|
|
|
EXPECT_FALSE(isOpened);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(Wddm20EnumAdaptersTest, WhenAdapterDescriptionContainsDCHDAndgdrclPathContainsDchDThenAdapterIsOpened) {
|
|
|
|
VariableBackup<const wchar_t *> descriptionBackup(&UltIDXGIAdapter1::description);
|
|
|
|
descriptionBackup = L"Intel DCH-D";
|
|
|
|
VariableBackup<const wchar_t *> igdrclPathBackup(&SysCalls::igdrclFilePath);
|
|
|
|
igdrclPathBackup = L"intel_dch_d.inf";
|
|
|
|
|
|
|
|
struct MockWddm : Wddm {
|
|
|
|
using Wddm::openAdapter;
|
|
|
|
|
2019-11-07 01:14:30 +08:00
|
|
|
MockWddm(RootDeviceEnvironment &rootDeviceEnvironment) : Wddm(rootDeviceEnvironment) {}
|
|
|
|
};
|
|
|
|
MockExecutionEnvironment executionEnvironment;
|
|
|
|
RootDeviceEnvironment rootDeviceEnvironment(executionEnvironment);
|
|
|
|
auto wddm = std::make_unique<MockWddm>(rootDeviceEnvironment);
|
2019-10-03 21:33:18 +08:00
|
|
|
bool isOpened = wddm->openAdapter();
|
|
|
|
|
|
|
|
EXPECT_TRUE(isOpened);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(Wddm20EnumAdaptersTest, WhenAdapterDescriptionContainsDCHIAndgdrclPathContainsDchIThenAdapterIsOpened) {
|
|
|
|
VariableBackup<const wchar_t *> descriptionBackup(&UltIDXGIAdapter1::description);
|
|
|
|
descriptionBackup = L"Intel DCH-I";
|
|
|
|
VariableBackup<const wchar_t *> igdrclPathBackup(&SysCalls::igdrclFilePath);
|
|
|
|
igdrclPathBackup = L"intel_dch_i.inf";
|
|
|
|
|
|
|
|
struct MockWddm : Wddm {
|
|
|
|
using Wddm::openAdapter;
|
|
|
|
|
2019-11-07 01:14:30 +08:00
|
|
|
MockWddm(RootDeviceEnvironment &rootDeviceEnvironment) : Wddm(rootDeviceEnvironment) {}
|
|
|
|
};
|
|
|
|
MockExecutionEnvironment executionEnvironment;
|
|
|
|
RootDeviceEnvironment rootDeviceEnvironment(executionEnvironment);
|
|
|
|
auto wddm = std::make_unique<MockWddm>(rootDeviceEnvironment);
|
2019-10-03 21:33:18 +08:00
|
|
|
bool isOpened = wddm->openAdapter();
|
|
|
|
|
|
|
|
EXPECT_TRUE(isOpened);
|
|
|
|
}
|
|
|
|
|
2018-05-15 18:13:16 +08:00
|
|
|
TEST(Wddm20EnumAdaptersTest, expectTrue) {
|
2018-02-28 23:52:08 +08:00
|
|
|
HardwareInfo outHwInfo;
|
|
|
|
|
2019-05-06 18:33:44 +08:00
|
|
|
const HardwareInfo *hwInfo = platformDevices[0];
|
2019-05-08 22:00:24 +08:00
|
|
|
std::unique_ptr<OsLibrary> mockGdiDll(setAdapterInfo(&hwInfo->platform,
|
|
|
|
&hwInfo->gtSystemInfo,
|
2019-05-06 18:33:44 +08:00
|
|
|
hwInfo->capabilityTable.gpuAddressSpace));
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-11-07 01:14:30 +08:00
|
|
|
MockExecutionEnvironment executionEnvironment;
|
|
|
|
RootDeviceEnvironment rootDeviceEnvironment(executionEnvironment);
|
|
|
|
std::unique_ptr<Wddm> wddm(Wddm::createWddm(rootDeviceEnvironment));
|
2019-07-08 19:30:31 +08:00
|
|
|
bool success = wddm->init(outHwInfo);
|
2018-08-10 17:07:17 +08:00
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_TRUE(success);
|
|
|
|
|
2019-05-08 22:00:24 +08:00
|
|
|
EXPECT_EQ(outHwInfo.platform.eDisplayCoreFamily, hwInfo->platform.eDisplayCoreFamily);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-05-15 18:13:16 +08:00
|
|
|
TEST(Wddm20EnumAdaptersTest, givenEmptyHardwareInfoWhenEnumAdapterIsCalledThenCapabilityTableIsSet) {
|
2018-03-21 17:00:49 +08:00
|
|
|
HardwareInfo outHwInfo = {};
|
2018-02-28 23:52:08 +08:00
|
|
|
|
2019-05-06 18:33:44 +08:00
|
|
|
const HardwareInfo *hwInfo = platformDevices[0];
|
2019-05-08 22:00:24 +08:00
|
|
|
std::unique_ptr<OsLibrary> mockGdiDll(setAdapterInfo(&hwInfo->platform,
|
|
|
|
&hwInfo->gtSystemInfo,
|
2019-05-06 18:33:44 +08:00
|
|
|
hwInfo->capabilityTable.gpuAddressSpace));
|
2018-02-28 23:52:08 +08:00
|
|
|
|
2019-11-07 01:14:30 +08:00
|
|
|
MockExecutionEnvironment executionEnvironment;
|
|
|
|
RootDeviceEnvironment rootDeviceEnvironment(executionEnvironment);
|
|
|
|
std::unique_ptr<Wddm> wddm(Wddm::createWddm(rootDeviceEnvironment));
|
2019-07-08 19:30:31 +08:00
|
|
|
bool success = wddm->init(outHwInfo);
|
2018-02-28 23:52:08 +08:00
|
|
|
EXPECT_TRUE(success);
|
|
|
|
|
2019-05-08 22:00:24 +08:00
|
|
|
EXPECT_EQ(outHwInfo.platform.eDisplayCoreFamily, hwInfo->platform.eDisplayCoreFamily);
|
2018-02-28 23:52:08 +08:00
|
|
|
|
2019-05-06 18:33:44 +08:00
|
|
|
EXPECT_EQ(outHwInfo.capabilityTable.defaultProfilingTimerResolution, hwInfo->capabilityTable.defaultProfilingTimerResolution);
|
|
|
|
EXPECT_EQ(outHwInfo.capabilityTable.clVersionSupport, hwInfo->capabilityTable.clVersionSupport);
|
|
|
|
EXPECT_EQ(outHwInfo.capabilityTable.kmdNotifyProperties.enableKmdNotify, hwInfo->capabilityTable.kmdNotifyProperties.enableKmdNotify);
|
|
|
|
EXPECT_EQ(outHwInfo.capabilityTable.kmdNotifyProperties.delayKmdNotifyMicroseconds, hwInfo->capabilityTable.kmdNotifyProperties.delayKmdNotifyMicroseconds);
|
|
|
|
EXPECT_EQ(outHwInfo.capabilityTable.kmdNotifyProperties.enableQuickKmdSleep, hwInfo->capabilityTable.kmdNotifyProperties.enableQuickKmdSleep);
|
|
|
|
EXPECT_EQ(outHwInfo.capabilityTable.kmdNotifyProperties.delayQuickKmdSleepMicroseconds, hwInfo->capabilityTable.kmdNotifyProperties.delayQuickKmdSleepMicroseconds);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-05-15 18:13:16 +08:00
|
|
|
TEST(Wddm20EnumAdaptersTest, givenUnknownPlatformWhenEnumAdapterIsCalledThenFalseIsReturnedAndOutputIsEmpty) {
|
2019-05-06 18:33:44 +08:00
|
|
|
HardwareInfo outHwInfo = {};
|
2018-02-28 23:52:08 +08:00
|
|
|
|
|
|
|
HardwareInfo hwInfo = *platformDevices[0];
|
2019-05-08 22:00:24 +08:00
|
|
|
hwInfo.platform.eProductFamily = IGFX_UNKNOWN;
|
|
|
|
std::unique_ptr<OsLibrary> mockGdiDll(setAdapterInfo(&hwInfo.platform,
|
|
|
|
&hwInfo.gtSystemInfo,
|
2019-05-06 18:33:44 +08:00
|
|
|
hwInfo.capabilityTable.gpuAddressSpace));
|
|
|
|
|
2019-11-07 01:14:30 +08:00
|
|
|
MockExecutionEnvironment executionEnvironment;
|
|
|
|
RootDeviceEnvironment rootDeviceEnvironment(executionEnvironment);
|
|
|
|
std::unique_ptr<Wddm> wddm(Wddm::createWddm(rootDeviceEnvironment));
|
2019-07-08 19:30:31 +08:00
|
|
|
auto ret = wddm->init(outHwInfo);
|
2018-02-28 23:52:08 +08:00
|
|
|
EXPECT_FALSE(ret);
|
2019-05-06 18:33:44 +08:00
|
|
|
|
|
|
|
// reset mock gdi
|
|
|
|
hwInfo = *platformDevices[0];
|
2019-05-08 22:00:24 +08:00
|
|
|
mockGdiDll.reset(setAdapterInfo(&hwInfo.platform,
|
|
|
|
&hwInfo.gtSystemInfo,
|
2019-05-06 18:33:44 +08:00
|
|
|
hwInfo.capabilityTable.gpuAddressSpace));
|
2018-02-28 23:52:08 +08:00
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, whenInitializeWddmThenContextIsCreated) {
|
2019-03-01 19:21:30 +08:00
|
|
|
auto context = osContext->getWddmContextHandle();
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_TRUE(context != static_cast<D3DKMT_HANDLE>(0));
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, allocation) {
|
2019-03-15 17:22:35 +08:00
|
|
|
OsAgnosticMemoryManager mm(*executionEnvironment);
|
2019-11-04 23:03:30 +08:00
|
|
|
WddmAllocation allocation(0, GraphicsAllocation::AllocationType::UNKNOWN, mm.allocateSystemMemory(100, 0), 100, nullptr, MemoryPool::MemoryNull);
|
2018-05-08 02:42:00 +08:00
|
|
|
Gmm *gmm = GmmHelperFunctions::getGmm(allocation.getUnderlyingBuffer(), allocation.getUnderlyingBufferSize());
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-03-12 20:24:58 +08:00
|
|
|
allocation.setDefaultGmm(gmm);
|
2018-01-08 23:31:29 +08:00
|
|
|
auto status = wddm->createAllocation(&allocation);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-01-08 23:31:29 +08:00
|
|
|
EXPECT_EQ(STATUS_SUCCESS, status);
|
2019-03-05 16:25:18 +08:00
|
|
|
EXPECT_TRUE(allocation.getDefaultHandle() != 0);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-02-27 18:17:17 +08:00
|
|
|
auto error = wddm->destroyAllocation(&allocation, osContext.get());
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_TRUE(error);
|
|
|
|
|
2018-05-08 02:42:00 +08:00
|
|
|
delete gmm;
|
2017-12-21 07:45:38 +08:00
|
|
|
mm.freeSystemMemory(allocation.getUnderlyingBuffer());
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20WithMockGdiDllTests, givenAllocationSmallerUnderlyingThanAlignedSizeWhenCreatedThenWddmUseAligned) {
|
2018-05-08 02:42:00 +08:00
|
|
|
void *ptr = reinterpret_cast<void *>(wddm->virtualAllocAddress + 0x1000);
|
2018-02-02 00:16:36 +08:00
|
|
|
size_t underlyingSize = 0x2100;
|
|
|
|
size_t alignedSize = 0x3000;
|
|
|
|
|
|
|
|
size_t underlyingPages = underlyingSize / MemoryConstants::pageSize;
|
|
|
|
size_t alignedPages = alignedSize / MemoryConstants::pageSize;
|
|
|
|
|
2019-11-04 23:03:30 +08:00
|
|
|
WddmAllocation allocation(0, GraphicsAllocation::AllocationType::UNKNOWN, ptr, 0x2100, nullptr, MemoryPool::MemoryNull);
|
2018-05-08 02:42:00 +08:00
|
|
|
Gmm *gmm = GmmHelperFunctions::getGmm(allocation.getAlignedCpuPtr(), allocation.getAlignedSize());
|
2018-02-02 00:16:36 +08:00
|
|
|
|
2019-03-12 20:24:58 +08:00
|
|
|
allocation.setDefaultGmm(gmm);
|
2018-02-02 00:16:36 +08:00
|
|
|
auto status = wddm->createAllocation(&allocation);
|
|
|
|
|
|
|
|
EXPECT_EQ(STATUS_SUCCESS, status);
|
2019-03-05 16:25:18 +08:00
|
|
|
EXPECT_NE(0, allocation.getDefaultHandle());
|
2018-02-02 00:16:36 +08:00
|
|
|
|
2019-03-18 17:06:01 +08:00
|
|
|
bool ret = wddm->mapGpuVirtualAddress(&allocation);
|
2018-02-07 05:43:38 +08:00
|
|
|
EXPECT_TRUE(ret);
|
|
|
|
|
2018-02-02 00:16:36 +08:00
|
|
|
EXPECT_EQ(alignedPages, getLastCallMapGpuVaArgFcn()->SizeInPages);
|
|
|
|
EXPECT_NE(underlyingPages, getLastCallMapGpuVaArgFcn()->SizeInPages);
|
|
|
|
|
2019-02-27 18:17:17 +08:00
|
|
|
ret = wddm->destroyAllocation(&allocation, osContext.get());
|
2018-02-02 00:16:36 +08:00
|
|
|
EXPECT_TRUE(ret);
|
|
|
|
|
2018-05-08 02:42:00 +08:00
|
|
|
delete gmm;
|
2018-02-02 00:16:36 +08:00
|
|
|
}
|
2019-02-26 15:28:41 +08:00
|
|
|
TEST_F(Wddm20WithMockGdiDllTests, givenReserveCallWhenItIsCalledWithProperParamtersThenAddressInRangeIsReturend) {
|
|
|
|
auto sizeAlignedTo64Kb = 64 * KB;
|
|
|
|
|
|
|
|
auto reservationAddress = wddm->reserveGpuVirtualAddress(wddm->getGfxPartition().Heap32[0].Base,
|
|
|
|
wddm->getGfxPartition().Heap32[0].Limit,
|
|
|
|
sizeAlignedTo64Kb);
|
|
|
|
|
|
|
|
EXPECT_GE(reservationAddress, wddm->getGfxPartition().Heap32[0].Base);
|
|
|
|
auto programmedReserved = getLastCallReserveGpuVaArgFcn();
|
|
|
|
EXPECT_EQ(0llu, programmedReserved->BaseAddress);
|
|
|
|
EXPECT_EQ(wddm->getGfxPartition().Heap32[0].Base, programmedReserved->MinimumAddress);
|
|
|
|
EXPECT_EQ(wddm->getGfxPartition().Heap32[0].Limit, programmedReserved->MaximumAddress);
|
|
|
|
EXPECT_EQ(sizeAlignedTo64Kb, programmedReserved->Size);
|
|
|
|
|
|
|
|
auto pagingQueue = wddm->getPagingQueue();
|
|
|
|
EXPECT_NE(0llu, pagingQueue);
|
|
|
|
EXPECT_EQ(pagingQueue, programmedReserved->hPagingQueue);
|
|
|
|
}
|
2018-02-02 00:16:36 +08:00
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20WithMockGdiDllTests, givenWddmAllocationWhenMappingGpuVaThenUseGmmSize) {
|
2018-07-12 21:42:46 +08:00
|
|
|
void *fakePtr = reinterpret_cast<void *>(0x123);
|
2019-11-04 23:03:30 +08:00
|
|
|
WddmAllocation allocation(0, GraphicsAllocation::AllocationType::UNKNOWN, fakePtr, 100, nullptr, MemoryPool::MemoryNull);
|
2018-07-12 21:42:46 +08:00
|
|
|
std::unique_ptr<Gmm> gmm(GmmHelperFunctions::getGmm(allocation.getAlignedCpuPtr(), allocation.getAlignedSize()));
|
|
|
|
|
2019-03-12 20:24:58 +08:00
|
|
|
allocation.setDefaultGmm(gmm.get());
|
2018-07-12 21:42:46 +08:00
|
|
|
auto status = wddm->createAllocation(&allocation);
|
2019-02-07 22:09:27 +08:00
|
|
|
EXPECT_EQ(STATUS_SUCCESS, status);
|
2018-07-12 21:42:46 +08:00
|
|
|
|
|
|
|
auto mockResourceInfo = static_cast<MockGmmResourceInfo *>(gmm->gmmResourceInfo.get());
|
|
|
|
mockResourceInfo->overrideReturnedSize(allocation.getAlignedSize() + (2 * MemoryConstants::pageSize));
|
|
|
|
|
2019-03-18 17:06:01 +08:00
|
|
|
wddm->mapGpuVirtualAddress(&allocation);
|
2018-07-12 21:42:46 +08:00
|
|
|
|
|
|
|
uint64_t expectedSizeInPages = static_cast<uint64_t>(mockResourceInfo->getSizeAllocation() / MemoryConstants::pageSize);
|
|
|
|
EXPECT_EQ(expectedSizeInPages, getLastCallMapGpuVaArgFcn()->SizeInPages);
|
|
|
|
}
|
|
|
|
|
2019-02-21 23:29:05 +08:00
|
|
|
TEST_F(Wddm20Tests, givenGraphicsAllocationWhenItIsMappedInHeap0ThenItHasGpuAddressWithinHeapInternalLimits) {
|
2018-02-28 15:31:38 +08:00
|
|
|
void *alignedPtr = (void *)0x12000;
|
|
|
|
size_t alignedSize = 0x2000;
|
2019-03-18 17:06:01 +08:00
|
|
|
std::unique_ptr<Gmm> gmm(GmmHelperFunctions::getGmm(alignedPtr, alignedSize));
|
|
|
|
uint64_t gpuAddress = 0u;
|
2019-11-28 21:23:32 +08:00
|
|
|
auto heapBase = wddm->getGfxPartition().Heap32[static_cast<uint32_t>(HeapIndex::HEAP_INTERNAL_DEVICE_MEMORY)].Base;
|
|
|
|
auto heapLimit = wddm->getGfxPartition().Heap32[static_cast<uint32_t>(HeapIndex::HEAP_INTERNAL_DEVICE_MEMORY)].Limit;
|
2018-02-28 15:31:38 +08:00
|
|
|
|
2019-03-18 17:06:01 +08:00
|
|
|
bool ret = wddm->mapGpuVirtualAddress(gmm.get(), ALLOCATION_HANDLE, heapBase, heapLimit, 0u, gpuAddress);
|
2018-02-28 15:31:38 +08:00
|
|
|
EXPECT_TRUE(ret);
|
2019-03-18 17:06:01 +08:00
|
|
|
auto cannonizedHeapBase = GmmHelper::canonize(heapBase);
|
|
|
|
auto cannonizedHeapEnd = GmmHelper::canonize(heapLimit);
|
2018-02-28 15:31:38 +08:00
|
|
|
|
2019-03-18 17:06:01 +08:00
|
|
|
EXPECT_GE(gpuAddress, cannonizedHeapBase);
|
|
|
|
EXPECT_LE(gpuAddress, cannonizedHeapEnd);
|
2018-02-28 15:31:38 +08:00
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20WithMockGdiDllTests, GivenThreeOsHandlesWhenAskedForDestroyAllocationsThenAllMarkedAllocationsAreDestroyed) {
|
2017-12-21 07:45:38 +08:00
|
|
|
OsHandleStorage storage;
|
|
|
|
OsHandle osHandle1 = {0};
|
|
|
|
OsHandle osHandle2 = {0};
|
|
|
|
OsHandle osHandle3 = {0};
|
|
|
|
|
|
|
|
osHandle1.handle = ALLOCATION_HANDLE;
|
|
|
|
osHandle2.handle = ALLOCATION_HANDLE;
|
|
|
|
osHandle3.handle = ALLOCATION_HANDLE;
|
|
|
|
|
|
|
|
storage.fragmentStorageData[0].osHandleStorage = &osHandle1;
|
|
|
|
storage.fragmentStorageData[0].freeTheFragment = true;
|
|
|
|
|
|
|
|
storage.fragmentStorageData[1].osHandleStorage = &osHandle2;
|
|
|
|
storage.fragmentStorageData[1].freeTheFragment = false;
|
|
|
|
|
|
|
|
storage.fragmentStorageData[2].osHandleStorage = &osHandle3;
|
|
|
|
storage.fragmentStorageData[2].freeTheFragment = true;
|
|
|
|
|
|
|
|
D3DKMT_HANDLE handles[3] = {ALLOCATION_HANDLE, ALLOCATION_HANDLE, ALLOCATION_HANDLE};
|
2018-09-06 23:58:32 +08:00
|
|
|
bool retVal = wddm->destroyAllocations(handles, 3, 0);
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_TRUE(retVal);
|
|
|
|
|
|
|
|
auto destroyWithResourceHandleCalled = 0u;
|
|
|
|
D3DKMT_DESTROYALLOCATION2 *ptrToDestroyAlloc2 = nullptr;
|
|
|
|
|
2018-05-08 02:42:00 +08:00
|
|
|
getSizesFcn(destroyWithResourceHandleCalled, ptrToDestroyAlloc2);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
EXPECT_EQ(0u, ptrToDestroyAlloc2->Flags.SynchronousDestroy);
|
|
|
|
EXPECT_EQ(1u, ptrToDestroyAlloc2->Flags.AssumeNotInUse);
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, mapAndFreeGpuVa) {
|
2019-03-15 17:22:35 +08:00
|
|
|
OsAgnosticMemoryManager mm(*executionEnvironment);
|
2019-11-04 23:03:30 +08:00
|
|
|
WddmAllocation allocation(0, GraphicsAllocation::AllocationType::UNKNOWN, mm.allocateSystemMemory(100, 0), 100, nullptr, MemoryPool::MemoryNull);
|
2018-05-08 02:42:00 +08:00
|
|
|
Gmm *gmm = GmmHelperFunctions::getGmm(allocation.getUnderlyingBuffer(), allocation.getUnderlyingBufferSize());
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-03-12 20:24:58 +08:00
|
|
|
allocation.setDefaultGmm(gmm);
|
2018-01-08 23:31:29 +08:00
|
|
|
auto status = wddm->createAllocation(&allocation);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-01-08 23:31:29 +08:00
|
|
|
EXPECT_EQ(STATUS_SUCCESS, status);
|
2019-03-05 16:25:18 +08:00
|
|
|
EXPECT_TRUE(allocation.getDefaultHandle() != 0);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-03-18 17:06:01 +08:00
|
|
|
auto error = wddm->mapGpuVirtualAddress(&allocation);
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_TRUE(error);
|
2019-03-05 21:21:57 +08:00
|
|
|
EXPECT_TRUE(allocation.getGpuAddress() != 0);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-03-05 21:21:57 +08:00
|
|
|
error = wddm->freeGpuVirtualAddress(allocation.getGpuAddressToModify(), allocation.getUnderlyingBufferSize());
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_TRUE(error);
|
2019-03-05 21:21:57 +08:00
|
|
|
EXPECT_TRUE(allocation.getGpuAddress() == 0);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-02-27 18:17:17 +08:00
|
|
|
error = wddm->destroyAllocation(&allocation, osContext.get());
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_TRUE(error);
|
2018-05-08 02:42:00 +08:00
|
|
|
delete gmm;
|
2017-12-21 07:45:38 +08:00
|
|
|
mm.freeSystemMemory(allocation.getUnderlyingBuffer());
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, givenNullAllocationWhenCreateThenAllocateAndMap) {
|
2019-03-15 17:22:35 +08:00
|
|
|
OsAgnosticMemoryManager mm(*executionEnvironment);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-11-04 23:03:30 +08:00
|
|
|
WddmAllocation allocation(0, GraphicsAllocation::AllocationType::UNKNOWN, nullptr, 100, nullptr, MemoryPool::MemoryNull);
|
2018-05-08 02:42:00 +08:00
|
|
|
Gmm *gmm = GmmHelperFunctions::getGmm(allocation.getUnderlyingBuffer(), allocation.getUnderlyingBufferSize());
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-03-12 20:24:58 +08:00
|
|
|
allocation.setDefaultGmm(gmm);
|
2018-01-08 23:31:29 +08:00
|
|
|
auto status = wddm->createAllocation(&allocation);
|
|
|
|
EXPECT_EQ(STATUS_SUCCESS, status);
|
2018-02-07 05:43:38 +08:00
|
|
|
|
2019-03-18 17:06:01 +08:00
|
|
|
bool ret = wddm->mapGpuVirtualAddress(&allocation);
|
2018-02-07 05:43:38 +08:00
|
|
|
EXPECT_TRUE(ret);
|
|
|
|
|
2019-03-05 21:21:57 +08:00
|
|
|
EXPECT_NE(0u, allocation.getGpuAddress());
|
|
|
|
EXPECT_EQ(allocation.getGpuAddress(), GmmHelper::canonize(allocation.getGpuAddress()));
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-05-08 02:42:00 +08:00
|
|
|
delete gmm;
|
2017-12-21 07:45:38 +08:00
|
|
|
mm.freeSystemMemory(allocation.getUnderlyingBuffer());
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, makeResidentNonResident) {
|
2019-03-15 17:22:35 +08:00
|
|
|
OsAgnosticMemoryManager mm(*executionEnvironment);
|
2019-11-04 23:03:30 +08:00
|
|
|
WddmAllocation allocation(0, GraphicsAllocation::AllocationType::UNKNOWN, mm.allocateSystemMemory(100, 0), 100, nullptr, MemoryPool::MemoryNull);
|
2018-05-08 02:42:00 +08:00
|
|
|
Gmm *gmm = GmmHelperFunctions::getGmm(allocation.getUnderlyingBuffer(), allocation.getUnderlyingBufferSize());
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-03-12 20:24:58 +08:00
|
|
|
allocation.setDefaultGmm(gmm);
|
2018-01-08 23:31:29 +08:00
|
|
|
auto status = wddm->createAllocation(&allocation);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-01-08 23:31:29 +08:00
|
|
|
EXPECT_EQ(STATUS_SUCCESS, status);
|
2019-03-05 16:25:18 +08:00
|
|
|
EXPECT_TRUE(allocation.getDefaultHandle() != 0);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-03-18 17:06:01 +08:00
|
|
|
auto error = wddm->mapGpuVirtualAddress(&allocation);
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_TRUE(error);
|
2019-03-05 21:21:57 +08:00
|
|
|
EXPECT_TRUE(allocation.getGpuAddress() != 0);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-03-05 16:25:18 +08:00
|
|
|
error = wddm->makeResident(allocation.getHandles().data(), allocation.getNumHandles(), false, nullptr);
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_TRUE(error);
|
|
|
|
|
|
|
|
uint64_t sizeToTrim;
|
2019-03-05 16:25:18 +08:00
|
|
|
error = wddm->evict(allocation.getHandles().data(), allocation.getNumHandles(), sizeToTrim);
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_TRUE(error);
|
|
|
|
|
2019-02-27 18:17:17 +08:00
|
|
|
auto monitoredFence = osContext->getResidencyController().getMonitoredFence();
|
2017-12-21 07:45:38 +08:00
|
|
|
UINT64 fenceValue = 100;
|
|
|
|
monitoredFence.cpuAddress = &fenceValue;
|
|
|
|
monitoredFence.currentFenceValue = 101;
|
|
|
|
|
2019-02-27 18:17:17 +08:00
|
|
|
error = wddm->destroyAllocation(&allocation, osContext.get());
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
EXPECT_TRUE(error);
|
2018-05-08 02:42:00 +08:00
|
|
|
delete gmm;
|
2017-12-21 07:45:38 +08:00
|
|
|
mm.freeSystemMemory(allocation.getUnderlyingBuffer());
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20WithMockGdiDllTests, givenSharedHandleWhenCreateGraphicsAllocationFromSharedHandleIsCalledThenGraphicsAllocationWithSharedPropertiesIsCreated) {
|
2017-12-21 07:45:38 +08:00
|
|
|
void *pSysMem = (void *)0x1000;
|
2019-12-30 21:14:27 +08:00
|
|
|
std::unique_ptr<Gmm> gmm(new Gmm(executionEnvironment->getGmmClientContext(), pSysMem, 4096u, false));
|
2018-05-08 02:42:00 +08:00
|
|
|
auto status = setSizesFcn(gmm->gmmResourceInfo.get(), 1u, 1024u, 1u);
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_EQ(0u, status);
|
|
|
|
|
2019-03-22 00:45:00 +08:00
|
|
|
MemoryManagerCreate<WddmMemoryManager> mm(false, false, *executionEnvironment);
|
2019-11-07 21:15:04 +08:00
|
|
|
AllocationProperties properties(0, false, 4096u, GraphicsAllocation::AllocationType::SHARED_BUFFER, false);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-04-01 20:04:50 +08:00
|
|
|
auto graphicsAllocation = mm.createGraphicsAllocationFromSharedHandle(ALLOCATION_HANDLE, properties, false);
|
2017-12-21 07:45:38 +08:00
|
|
|
auto wddmAllocation = (WddmAllocation *)graphicsAllocation;
|
|
|
|
ASSERT_NE(nullptr, wddmAllocation);
|
|
|
|
|
|
|
|
EXPECT_EQ(ALLOCATION_HANDLE, wddmAllocation->peekSharedHandle());
|
|
|
|
EXPECT_EQ(RESOURCE_HANDLE, wddmAllocation->resourceHandle);
|
2019-03-05 16:25:18 +08:00
|
|
|
EXPECT_NE(0u, wddmAllocation->getDefaultHandle());
|
|
|
|
EXPECT_EQ(ALLOCATION_HANDLE, wddmAllocation->getDefaultHandle());
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_NE(0u, wddmAllocation->getGpuAddress());
|
|
|
|
EXPECT_EQ(4096u, wddmAllocation->getUnderlyingBufferSize());
|
|
|
|
EXPECT_EQ(nullptr, wddmAllocation->getAlignedCpuPtr());
|
2019-03-12 20:24:58 +08:00
|
|
|
EXPECT_NE(nullptr, wddmAllocation->getDefaultGmm());
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-03-12 20:24:58 +08:00
|
|
|
EXPECT_EQ(4096u, wddmAllocation->getDefaultGmm()->gmmResourceInfo->getSizeAllocation());
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
mm.freeGraphicsMemory(graphicsAllocation);
|
|
|
|
auto destroyWithResourceHandleCalled = 0u;
|
|
|
|
D3DKMT_DESTROYALLOCATION2 *ptrToDestroyAlloc2 = nullptr;
|
|
|
|
|
2018-05-08 02:42:00 +08:00
|
|
|
status = getSizesFcn(destroyWithResourceHandleCalled, ptrToDestroyAlloc2);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
EXPECT_EQ(0u, ptrToDestroyAlloc2->Flags.SynchronousDestroy);
|
|
|
|
EXPECT_EQ(1u, ptrToDestroyAlloc2->Flags.AssumeNotInUse);
|
|
|
|
|
|
|
|
EXPECT_EQ(0u, status);
|
|
|
|
EXPECT_EQ(1u, destroyWithResourceHandleCalled);
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20WithMockGdiDllTests, givenSharedHandleWhenCreateGraphicsAllocationFromSharedHandleIsCalledThenMapGpuVaWithCpuPtrDepensOnBitness) {
|
2017-12-21 07:45:38 +08:00
|
|
|
void *pSysMem = (void *)0x1000;
|
2019-12-30 21:14:27 +08:00
|
|
|
std::unique_ptr<Gmm> gmm(new Gmm(executionEnvironment->getGmmClientContext(), pSysMem, 4096u, false));
|
2018-05-08 02:42:00 +08:00
|
|
|
auto status = setSizesFcn(gmm->gmmResourceInfo.get(), 1u, 1024u, 1u);
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_EQ(0u, status);
|
|
|
|
|
2019-03-22 00:45:00 +08:00
|
|
|
MemoryManagerCreate<WddmMemoryManager> mm(false, false, *executionEnvironment);
|
2019-11-07 21:15:04 +08:00
|
|
|
AllocationProperties properties(0, false, 4096, GraphicsAllocation::AllocationType::SHARED_BUFFER, false);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-04-01 20:04:50 +08:00
|
|
|
auto graphicsAllocation = mm.createGraphicsAllocationFromSharedHandle(ALLOCATION_HANDLE, properties, false);
|
2017-12-21 07:45:38 +08:00
|
|
|
auto wddmAllocation = (WddmAllocation *)graphicsAllocation;
|
|
|
|
ASSERT_NE(nullptr, wddmAllocation);
|
|
|
|
|
2019-03-18 17:06:01 +08:00
|
|
|
if (is32bit && executionEnvironment->isFullRangeSvm()) {
|
2018-08-27 21:48:29 +08:00
|
|
|
EXPECT_NE(wddm->mapGpuVirtualAddressResult.cpuPtrPassed, nullptr);
|
2017-12-21 07:45:38 +08:00
|
|
|
} else {
|
2018-08-27 21:48:29 +08:00
|
|
|
EXPECT_EQ(wddm->mapGpuVirtualAddressResult.cpuPtrPassed, nullptr);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
mm.freeGraphicsMemory(graphicsAllocation);
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, givenWddmCreatedWhenInitedThenMinAddressValid) {
|
2018-01-22 23:43:26 +08:00
|
|
|
uintptr_t expected = windowsMinAddress;
|
|
|
|
uintptr_t actual = wddm->getWddmMinAddress();
|
|
|
|
EXPECT_EQ(expected, actual);
|
|
|
|
}
|
|
|
|
|
2018-08-24 21:23:45 +08:00
|
|
|
HWTEST_F(Wddm20InstrumentationTest, configureDeviceAddressSpaceOnInit) {
|
2017-12-21 07:45:38 +08:00
|
|
|
SYSTEM_INFO sysInfo = {};
|
|
|
|
WddmMock::getSystemInfo(&sysInfo);
|
|
|
|
|
|
|
|
D3DKMT_HANDLE adapterHandle = ADAPTER_HANDLE;
|
|
|
|
D3DKMT_HANDLE deviceHandle = DEVICE_HANDLE;
|
|
|
|
const HardwareInfo hwInfo = *platformDevices[0];
|
2019-05-08 22:00:24 +08:00
|
|
|
BOOLEAN FtrL3IACoherency = hwInfo.featureTable.ftrL3IACoherency ? 1 : 0;
|
2019-10-22 00:30:24 +08:00
|
|
|
uintptr_t maxAddr = hwInfo.capabilityTable.gpuAddressSpace >= MemoryConstants::max64BitAppAddress
|
2018-08-24 21:23:45 +08:00
|
|
|
? reinterpret_cast<uintptr_t>(sysInfo.lpMaximumApplicationAddress) + 1
|
|
|
|
: 0;
|
2017-12-21 07:45:38 +08:00
|
|
|
EXPECT_CALL(*gmmMem, configureDeviceAddressSpace(adapterHandle,
|
|
|
|
deviceHandle,
|
2018-05-08 02:42:00 +08:00
|
|
|
wddm->gdi->escape.mFunc,
|
2017-12-21 07:45:38 +08:00
|
|
|
maxAddr,
|
2018-08-23 17:29:39 +08:00
|
|
|
FtrL3IACoherency))
|
2017-12-21 07:45:38 +08:00
|
|
|
.Times(1)
|
|
|
|
.WillRepeatedly(::testing::Return(true));
|
2019-07-08 19:30:31 +08:00
|
|
|
auto hwInfoMock = *platformDevices[0];
|
|
|
|
wddm->init(hwInfoMock);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20InstrumentationTest, configureDeviceAddressSpaceNoAdapter) {
|
2018-05-08 02:42:00 +08:00
|
|
|
wddm->adapter = static_cast<D3DKMT_HANDLE>(0);
|
2018-08-24 21:23:45 +08:00
|
|
|
EXPECT_CALL(*gmmMem,
|
|
|
|
configureDeviceAddressSpace(static_cast<D3DKMT_HANDLE>(0), ::testing::_, ::testing::_, ::testing::_, ::testing::_))
|
|
|
|
.Times(0);
|
2018-08-23 17:29:39 +08:00
|
|
|
auto ret = wddm->configureDeviceAddressSpace();
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
EXPECT_FALSE(ret);
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20InstrumentationTest, configureDeviceAddressSpaceNoDevice) {
|
2018-05-08 02:42:00 +08:00
|
|
|
wddm->device = static_cast<D3DKMT_HANDLE>(0);
|
2018-08-24 21:23:45 +08:00
|
|
|
EXPECT_CALL(*gmmMem,
|
|
|
|
configureDeviceAddressSpace(::testing::_, static_cast<D3DKMT_HANDLE>(0), ::testing::_, ::testing::_, ::testing::_))
|
|
|
|
.Times(0);
|
2018-08-23 17:29:39 +08:00
|
|
|
auto ret = wddm->configureDeviceAddressSpace();
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
EXPECT_FALSE(ret);
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20InstrumentationTest, configureDeviceAddressSpaceNoEscFunc) {
|
2018-05-08 02:42:00 +08:00
|
|
|
wddm->gdi->escape = static_cast<PFND3DKMT_ESCAPE>(nullptr);
|
2018-08-24 21:23:45 +08:00
|
|
|
EXPECT_CALL(*gmmMem, configureDeviceAddressSpace(::testing::_, ::testing::_, static_cast<PFND3DKMT_ESCAPE>(nullptr), ::testing::_,
|
2017-12-21 07:45:38 +08:00
|
|
|
::testing::_))
|
2018-08-24 21:23:45 +08:00
|
|
|
.Times(0);
|
2018-08-23 17:29:39 +08:00
|
|
|
auto ret = wddm->configureDeviceAddressSpace();
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
EXPECT_FALSE(ret);
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, getMaxApplicationAddress) {
|
2018-05-08 02:42:00 +08:00
|
|
|
uint64_t maxAddr = wddm->getMaxApplicationAddress();
|
2017-12-21 07:45:38 +08:00
|
|
|
if (is32bit) {
|
|
|
|
EXPECT_EQ(maxAddr, MemoryConstants::max32BitAppAddress);
|
|
|
|
} else {
|
|
|
|
EXPECT_EQ(maxAddr, MemoryConstants::max64BitAppAddress);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-24 15:27:00 +08:00
|
|
|
TEST_F(Wddm20WithMockGdiDllTestsWithoutWddmInit, givenUseNoRingFlushesKmdModeDebugFlagToFalseWhenCreateContextIsCalledThenNoRingFlushesKmdModeIsSetToFalse) {
|
2018-02-16 16:07:49 +08:00
|
|
|
DebugManagerStateRestore dbgRestore;
|
|
|
|
DebugManager.flags.UseNoRingFlushesKmdMode.set(false);
|
2018-08-27 21:48:29 +08:00
|
|
|
init();
|
2018-02-16 16:07:49 +08:00
|
|
|
auto createContextParams = this->getCreateContextDataFcn();
|
|
|
|
auto privateData = (CREATECONTEXT_PVTDATA *)createContextParams->pPrivateDriverData;
|
|
|
|
EXPECT_FALSE(!!privateData->NoRingFlushes);
|
|
|
|
}
|
|
|
|
|
2019-10-23 23:16:09 +08:00
|
|
|
TEST_F(Wddm20WithMockGdiDllTestsWithoutWddmInit, givenCreateContextCallWhenDriverHintsItPointsToOpenCL) {
|
|
|
|
init();
|
|
|
|
auto createContextParams = this->getCreateContextDataFcn();
|
|
|
|
EXPECT_EQ(D3DKMT_CLIENTHINT_OPENCL, createContextParams->ClientHint);
|
|
|
|
}
|
|
|
|
|
2018-08-24 15:27:00 +08:00
|
|
|
TEST_F(Wddm20WithMockGdiDllTestsWithoutWddmInit, givenUseNoRingFlushesKmdModeDebugFlagToTrueWhenCreateContextIsCalledThenNoRingFlushesKmdModeIsSetToTrue) {
|
2018-02-16 16:07:49 +08:00
|
|
|
DebugManagerStateRestore dbgRestore;
|
|
|
|
DebugManager.flags.UseNoRingFlushesKmdMode.set(true);
|
2018-08-27 21:48:29 +08:00
|
|
|
init();
|
2018-02-16 16:07:49 +08:00
|
|
|
auto createContextParams = this->getCreateContextDataFcn();
|
|
|
|
auto privateData = (CREATECONTEXT_PVTDATA *)createContextParams->pPrivateDriverData;
|
|
|
|
EXPECT_TRUE(!!privateData->NoRingFlushes);
|
|
|
|
}
|
|
|
|
|
2018-11-26 21:04:52 +08:00
|
|
|
TEST_F(Wddm20WithMockGdiDllTestsWithoutWddmInit, givenEngineTypeWhenCreatingContextThenPassCorrectNodeOrdinal) {
|
|
|
|
init();
|
|
|
|
auto createContextParams = this->getCreateContextDataFcn();
|
2019-05-08 22:00:24 +08:00
|
|
|
UINT expected = WddmEngineMapper::engineNodeMap(HwHelper::get(platformDevices[0]->platform.eRenderCoreFamily).getGpgpuEngineInstances()[0]);
|
2018-11-26 21:04:52 +08:00
|
|
|
EXPECT_EQ(expected, createContextParams->NodeOrdinal);
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20WithMockGdiDllTests, whenCreateContextIsCalledThenDisableHwQueues) {
|
2018-08-10 22:41:44 +08:00
|
|
|
EXPECT_FALSE(wddm->wddmInterface->hwQueuesSupported());
|
2018-05-18 16:18:16 +08:00
|
|
|
EXPECT_EQ(0u, getCreateContextDataFcn()->Flags.HwQueueSupported);
|
2018-05-15 20:07:37 +08:00
|
|
|
}
|
|
|
|
|
2019-12-13 22:47:45 +08:00
|
|
|
TEST_F(Wddm20WithMockGdiDllTests, givenDestructionOsContextWinWhenCallingDestroyMonitorFenceThenDoCallGdiDestroy) {
|
|
|
|
auto fenceHandle = osContext->getResidencyController().getMonitoredFence().fenceHandle;
|
|
|
|
|
|
|
|
osContext.reset(nullptr);
|
|
|
|
EXPECT_EQ(1u, wddmMockInterface->destroyMonitorFenceCalled);
|
|
|
|
EXPECT_EQ(fenceHandle, getDestroySynchronizationObjectDataFcn()->hSyncObject);
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, whenCreateHwQueueIsCalledThenAlwaysReturnFalse) {
|
2019-02-27 18:17:17 +08:00
|
|
|
EXPECT_FALSE(wddm->wddmInterface->createHwQueue(*osContext.get()));
|
2018-05-18 16:18:16 +08:00
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, whenWddmIsInitializedThenGdiDoesntHaveHwQueueDDIs) {
|
2018-05-18 16:18:16 +08:00
|
|
|
EXPECT_EQ(nullptr, wddm->gdi->createHwQueue.mFunc);
|
|
|
|
EXPECT_EQ(nullptr, wddm->gdi->destroyHwQueue.mFunc);
|
|
|
|
EXPECT_EQ(nullptr, wddm->gdi->submitCommandToHwQueue.mFunc);
|
2018-05-15 20:07:37 +08:00
|
|
|
}
|
|
|
|
|
2018-08-24 15:27:00 +08:00
|
|
|
TEST(DebugFlagTest, givenDebugManagerWhenGetForUseNoRingFlushesKmdModeIsCalledThenTrueIsReturned) {
|
2018-03-01 21:44:09 +08:00
|
|
|
EXPECT_TRUE(DebugManager.flags.UseNoRingFlushesKmdMode.get());
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, makeResidentMultipleHandles) {
|
2019-03-05 16:25:18 +08:00
|
|
|
D3DKMT_HANDLE handles[2] = {ALLOCATION_HANDLE, ALLOCATION_HANDLE};
|
2018-05-10 17:42:41 +08:00
|
|
|
gdi->getMakeResidentArg().NumAllocations = 0;
|
|
|
|
gdi->getMakeResidentArg().AllocationList = nullptr;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
bool error = wddm->makeResident(handles, 2, false, nullptr);
|
|
|
|
EXPECT_TRUE(error);
|
|
|
|
|
2018-05-10 17:42:41 +08:00
|
|
|
EXPECT_EQ(2u, gdi->getMakeResidentArg().NumAllocations);
|
|
|
|
EXPECT_EQ(handles, gdi->getMakeResidentArg().AllocationList);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, makeResidentMultipleHandlesWithReturnBytesToTrim) {
|
2019-03-05 16:25:18 +08:00
|
|
|
D3DKMT_HANDLE handles[2] = {ALLOCATION_HANDLE, ALLOCATION_HANDLE};
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-05-10 17:42:41 +08:00
|
|
|
gdi->getMakeResidentArg().NumAllocations = 0;
|
|
|
|
gdi->getMakeResidentArg().AllocationList = nullptr;
|
|
|
|
gdi->getMakeResidentArg().NumBytesToTrim = 30;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
uint64_t bytesToTrim = 0;
|
|
|
|
bool success = wddm->makeResident(handles, 2, false, &bytesToTrim);
|
|
|
|
EXPECT_TRUE(success);
|
|
|
|
|
2018-05-10 17:42:41 +08:00
|
|
|
EXPECT_EQ(gdi->getMakeResidentArg().NumBytesToTrim, bytesToTrim);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, makeNonResidentCallsEvict) {
|
2017-12-21 07:45:38 +08:00
|
|
|
D3DKMT_HANDLE handle = (D3DKMT_HANDLE)0x1234;
|
|
|
|
|
2018-05-10 17:42:41 +08:00
|
|
|
gdi->getEvictArg().AllocationList = nullptr;
|
|
|
|
gdi->getEvictArg().Flags.Value = 0;
|
|
|
|
gdi->getEvictArg().hDevice = 0;
|
|
|
|
gdi->getEvictArg().NumAllocations = 0;
|
|
|
|
gdi->getEvictArg().NumBytesToTrim = 20;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
uint64_t sizeToTrim = 10;
|
2018-05-08 02:42:00 +08:00
|
|
|
wddm->evict(&handle, 1, sizeToTrim);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-05-10 17:42:41 +08:00
|
|
|
EXPECT_EQ(1u, gdi->getEvictArg().NumAllocations);
|
|
|
|
EXPECT_EQ(&handle, gdi->getEvictArg().AllocationList);
|
|
|
|
EXPECT_EQ(wddm->getDevice(), gdi->getEvictArg().hDevice);
|
|
|
|
EXPECT_EQ(0u, gdi->getEvictArg().NumBytesToTrim);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-09-06 23:58:32 +08:00
|
|
|
TEST_F(Wddm20Tests, givenDestroyAllocationWhenItIsCalledThenAllocationIsPassedToDestroyAllocation) {
|
2019-03-05 16:25:18 +08:00
|
|
|
MockWddmAllocation allocation;
|
2019-02-27 18:17:17 +08:00
|
|
|
allocation.getResidencyData().updateCompletionData(10, osContext->getContextId());
|
2017-12-21 07:45:38 +08:00
|
|
|
allocation.handle = ALLOCATION_HANDLE;
|
|
|
|
|
2019-02-27 18:17:17 +08:00
|
|
|
*osContext->getResidencyController().getMonitoredFence().cpuAddress = 10;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-05-10 17:42:41 +08:00
|
|
|
gdi->getWaitFromCpuArg().FenceValueArray = nullptr;
|
|
|
|
gdi->getWaitFromCpuArg().Flags.Value = 0;
|
|
|
|
gdi->getWaitFromCpuArg().hDevice = (D3DKMT_HANDLE)0;
|
|
|
|
gdi->getWaitFromCpuArg().ObjectCount = 0;
|
|
|
|
gdi->getWaitFromCpuArg().ObjectHandleArray = nullptr;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-05-10 17:42:41 +08:00
|
|
|
gdi->getDestroyArg().AllocationCount = 0;
|
|
|
|
gdi->getDestroyArg().Flags.Value = 0;
|
|
|
|
gdi->getDestroyArg().hDevice = (D3DKMT_HANDLE)0;
|
|
|
|
gdi->getDestroyArg().hResource = (D3DKMT_HANDLE)0;
|
|
|
|
gdi->getDestroyArg().phAllocationList = nullptr;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-02-27 18:17:17 +08:00
|
|
|
wddm->destroyAllocation(&allocation, osContext.get());
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-05-10 17:42:41 +08:00
|
|
|
EXPECT_EQ(wddm->getDevice(), gdi->getDestroyArg().hDevice);
|
|
|
|
EXPECT_EQ(1u, gdi->getDestroyArg().AllocationCount);
|
|
|
|
EXPECT_NE(nullptr, gdi->getDestroyArg().phAllocationList);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, WhenLastFenceLessEqualThanMonitoredThenWaitFromCpuIsNotCalled) {
|
2019-03-05 16:25:18 +08:00
|
|
|
MockWddmAllocation allocation;
|
2019-02-27 18:17:17 +08:00
|
|
|
allocation.getResidencyData().updateCompletionData(10, osContext->getContextId());
|
2017-12-21 07:45:38 +08:00
|
|
|
allocation.handle = ALLOCATION_HANDLE;
|
|
|
|
|
2019-02-27 18:17:17 +08:00
|
|
|
*osContext->getResidencyController().getMonitoredFence().cpuAddress = 10;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-05-10 17:42:41 +08:00
|
|
|
gdi->getWaitFromCpuArg().FenceValueArray = nullptr;
|
|
|
|
gdi->getWaitFromCpuArg().Flags.Value = 0;
|
|
|
|
gdi->getWaitFromCpuArg().hDevice = (D3DKMT_HANDLE)0;
|
|
|
|
gdi->getWaitFromCpuArg().ObjectCount = 0;
|
|
|
|
gdi->getWaitFromCpuArg().ObjectHandleArray = nullptr;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-02-27 18:17:17 +08:00
|
|
|
auto status = wddm->waitFromCpu(10, osContext->getResidencyController().getMonitoredFence());
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
EXPECT_TRUE(status);
|
|
|
|
|
2018-05-10 17:42:41 +08:00
|
|
|
EXPECT_EQ(nullptr, gdi->getWaitFromCpuArg().FenceValueArray);
|
|
|
|
EXPECT_EQ((D3DKMT_HANDLE)0, gdi->getWaitFromCpuArg().hDevice);
|
|
|
|
EXPECT_EQ(0u, gdi->getWaitFromCpuArg().ObjectCount);
|
|
|
|
EXPECT_EQ(nullptr, gdi->getWaitFromCpuArg().ObjectHandleArray);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, WhenLastFenceGreaterThanMonitoredThenWaitFromCpuIsCalled) {
|
2019-03-05 16:25:18 +08:00
|
|
|
MockWddmAllocation allocation;
|
2019-02-27 18:17:17 +08:00
|
|
|
allocation.getResidencyData().updateCompletionData(10, osContext->getContextId());
|
2017-12-21 07:45:38 +08:00
|
|
|
allocation.handle = ALLOCATION_HANDLE;
|
|
|
|
|
2019-02-27 18:17:17 +08:00
|
|
|
*osContext->getResidencyController().getMonitoredFence().cpuAddress = 10;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-05-10 17:42:41 +08:00
|
|
|
gdi->getWaitFromCpuArg().FenceValueArray = nullptr;
|
|
|
|
gdi->getWaitFromCpuArg().Flags.Value = 0;
|
|
|
|
gdi->getWaitFromCpuArg().hDevice = (D3DKMT_HANDLE)0;
|
|
|
|
gdi->getWaitFromCpuArg().ObjectCount = 0;
|
|
|
|
gdi->getWaitFromCpuArg().ObjectHandleArray = nullptr;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-02-27 18:17:17 +08:00
|
|
|
auto status = wddm->waitFromCpu(20, osContext->getResidencyController().getMonitoredFence());
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
EXPECT_TRUE(status);
|
|
|
|
|
2018-05-10 17:42:41 +08:00
|
|
|
EXPECT_NE(nullptr, gdi->getWaitFromCpuArg().FenceValueArray);
|
|
|
|
EXPECT_EQ((D3DKMT_HANDLE)wddm->getDevice(), gdi->getWaitFromCpuArg().hDevice);
|
|
|
|
EXPECT_EQ(1u, gdi->getWaitFromCpuArg().ObjectCount);
|
|
|
|
EXPECT_NE(nullptr, gdi->getWaitFromCpuArg().ObjectHandleArray);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, createMonitoredFenceIsInitializedWithFenceValueZeroAndCurrentFenceValueIsSetToOne) {
|
2018-05-10 17:42:41 +08:00
|
|
|
gdi->createSynchronizationObject2 = gdi->createSynchronizationObject2Mock;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-05-10 17:42:41 +08:00
|
|
|
gdi->getCreateSynchronizationObject2Arg().Info.MonitoredFence.InitialFenceValue = 300;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2019-09-13 14:13:02 +08:00
|
|
|
wddm->wddmInterface->createMonitoredFence(*osContext);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-05-10 17:42:41 +08:00
|
|
|
EXPECT_EQ(0u, gdi->getCreateSynchronizationObject2Arg().Info.MonitoredFence.InitialFenceValue);
|
2019-02-27 18:17:17 +08:00
|
|
|
EXPECT_EQ(1u, osContext->getResidencyController().getMonitoredFence().currentFenceValue);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2017-12-22 00:28:17 +08:00
|
|
|
|
2018-01-09 00:35:09 +08:00
|
|
|
NTSTATUS APIENTRY queryResourceInfoMock(D3DKMT_QUERYRESOURCEINFO *pData) {
|
2017-12-22 00:28:17 +08:00
|
|
|
pData->NumAllocations = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, givenOpenSharedHandleWhenZeroAllocationsThenReturnNull) {
|
2017-12-22 00:28:17 +08:00
|
|
|
D3DKMT_HANDLE handle = 0;
|
|
|
|
WddmAllocation *alloc = nullptr;
|
|
|
|
|
2018-05-10 17:42:41 +08:00
|
|
|
gdi->queryResourceInfo = reinterpret_cast<PFND3DKMT_QUERYRESOURCEINFO>(queryResourceInfoMock);
|
2018-05-08 02:42:00 +08:00
|
|
|
auto ret = wddm->openSharedHandle(handle, alloc);
|
2017-12-22 00:28:17 +08:00
|
|
|
|
|
|
|
EXPECT_EQ(false, ret);
|
|
|
|
}
|
2018-01-30 22:07:58 +08:00
|
|
|
|
2018-08-28 18:56:05 +08:00
|
|
|
TEST_F(Wddm20Tests, whenCreateAllocation64kFailsThenReturnFalse) {
|
|
|
|
struct FailingCreateAllocation {
|
|
|
|
static NTSTATUS APIENTRY mockCreateAllocation(D3DKMT_CREATEALLOCATION *param) {
|
|
|
|
return STATUS_GRAPHICS_NO_VIDEO_MEMORY;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
gdi->createAllocation = FailingCreateAllocation::mockCreateAllocation;
|
|
|
|
|
|
|
|
void *fakePtr = reinterpret_cast<void *>(0x123);
|
2019-12-30 21:14:27 +08:00
|
|
|
auto gmm = std::make_unique<Gmm>(executionEnvironment->getGmmClientContext(), fakePtr, 100, false);
|
2019-11-04 23:03:30 +08:00
|
|
|
WddmAllocation allocation(0, GraphicsAllocation::AllocationType::UNKNOWN, fakePtr, 100, nullptr, MemoryPool::MemoryNull);
|
2019-03-12 20:24:58 +08:00
|
|
|
allocation.setDefaultGmm(gmm.get());
|
2018-08-28 18:56:05 +08:00
|
|
|
|
|
|
|
EXPECT_FALSE(wddm->createAllocation64k(&allocation));
|
|
|
|
}
|
|
|
|
|
2018-08-23 17:29:39 +08:00
|
|
|
TEST_F(Wddm20Tests, givenReadOnlyMemoryWhenCreateAllocationFailsWithNoVideoMemoryThenCorrectStatusIsReturned) {
|
2018-03-23 17:07:31 +08:00
|
|
|
class MockCreateAllocation {
|
|
|
|
public:
|
|
|
|
static NTSTATUS APIENTRY mockCreateAllocation(D3DKMT_CREATEALLOCATION *param) {
|
|
|
|
return STATUS_GRAPHICS_NO_VIDEO_MEMORY;
|
|
|
|
};
|
|
|
|
};
|
2018-05-10 17:42:41 +08:00
|
|
|
gdi->createAllocation = MockCreateAllocation::mockCreateAllocation;
|
2018-03-23 17:07:31 +08:00
|
|
|
|
|
|
|
OsHandleStorage handleStorage;
|
|
|
|
OsHandle handle = {0};
|
|
|
|
ResidencyData residency;
|
|
|
|
|
|
|
|
handleStorage.fragmentCount = 1;
|
|
|
|
handleStorage.fragmentStorageData[0].cpuPtr = (void *)0x1000;
|
|
|
|
handleStorage.fragmentStorageData[0].fragmentSize = 0x1000;
|
|
|
|
handleStorage.fragmentStorageData[0].freeTheFragment = false;
|
|
|
|
handleStorage.fragmentStorageData[0].osHandleStorage = &handle;
|
|
|
|
handleStorage.fragmentStorageData[0].residency = &residency;
|
2018-05-08 02:42:00 +08:00
|
|
|
handleStorage.fragmentStorageData[0].osHandleStorage->gmm = GmmHelperFunctions::getGmm(nullptr, 0);
|
2018-03-23 17:07:31 +08:00
|
|
|
|
|
|
|
NTSTATUS result = wddm->createAllocationsAndMapGpuVa(handleStorage);
|
|
|
|
|
|
|
|
EXPECT_EQ(STATUS_GRAPHICS_NO_VIDEO_MEMORY, result);
|
|
|
|
|
2018-05-08 02:42:00 +08:00
|
|
|
delete handleStorage.fragmentStorageData[0].osHandleStorage->gmm;
|
2018-03-23 17:07:31 +08:00
|
|
|
}
|
2018-09-12 20:44:18 +08:00
|
|
|
|
|
|
|
TEST_F(Wddm20Tests, whenContextIsInitializedThenApplyAdditionalContextFlagsIsCalled) {
|
2019-07-08 19:30:31 +08:00
|
|
|
auto hwInfo = *platformDevices[0];
|
|
|
|
auto result = wddm->init(hwInfo);
|
2018-09-12 20:44:18 +08:00
|
|
|
EXPECT_TRUE(result);
|
|
|
|
EXPECT_EQ(1u, wddm->applyAdditionalContextFlagsResult.called);
|
|
|
|
}
|
2018-10-23 22:17:31 +08:00
|
|
|
|
|
|
|
TEST_F(Wddm20Tests, givenTrimCallbackRegistrationIsDisabledInDebugVariableWhenRegisteringCallbackThenReturnNullptr) {
|
|
|
|
DebugManagerStateRestore stateRestore;
|
|
|
|
DebugManager.flags.DoNotRegisterTrimCallback.set(true);
|
2018-10-30 21:40:02 +08:00
|
|
|
WddmResidencyController residencyController{*wddm, 0u};
|
|
|
|
EXPECT_EQ(nullptr, wddm->registerTrimCallback([](D3DKMT_TRIMNOTIFICATION *) {}, residencyController));
|
2018-10-23 22:17:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(Wddm20Tests, givenSuccessWhenRegisteringTrimCallbackThenReturnTrimCallbackHandle) {
|
2018-10-30 21:40:02 +08:00
|
|
|
WddmResidencyController residencyController{*wddm, 0u};
|
|
|
|
auto trimCallbackHandle = wddm->registerTrimCallback([](D3DKMT_TRIMNOTIFICATION *) {}, residencyController);
|
2018-10-23 22:17:31 +08:00
|
|
|
EXPECT_NE(nullptr, trimCallbackHandle);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(Wddm20Tests, givenCorrectArgumentsWhenUnregisteringTrimCallbackThenPassArgumentsToGdiCall) {
|
|
|
|
PFND3DKMT_TRIMNOTIFICATIONCALLBACK callback = [](D3DKMT_TRIMNOTIFICATION *) {};
|
|
|
|
auto trimCallbackHandle = reinterpret_cast<VOID *>(0x9876);
|
|
|
|
|
|
|
|
wddm->unregisterTrimCallback(callback, trimCallbackHandle);
|
|
|
|
EXPECT_EQ(callback, gdi->getUnregisterTrimNotificationArg().Callback);
|
|
|
|
EXPECT_EQ(trimCallbackHandle, gdi->getUnregisterTrimNotificationArg().Handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(Wddm20Tests, givenNullTrimCallbackHandleWhenUnregisteringTrimCallbackThenDoNotDoGdiCall) {
|
|
|
|
PFND3DKMT_TRIMNOTIFICATIONCALLBACK callbackBefore = [](D3DKMT_TRIMNOTIFICATION *) {};
|
|
|
|
auto trimCallbackHandleBefore = reinterpret_cast<VOID *>(0x9876);
|
|
|
|
gdi->getUnregisterTrimNotificationArg().Callback = callbackBefore;
|
|
|
|
gdi->getUnregisterTrimNotificationArg().Handle = trimCallbackHandleBefore;
|
|
|
|
|
|
|
|
wddm->unregisterTrimCallback([](D3DKMT_TRIMNOTIFICATION *) {}, nullptr);
|
|
|
|
EXPECT_EQ(callbackBefore, gdi->getUnregisterTrimNotificationArg().Callback);
|
|
|
|
EXPECT_EQ(trimCallbackHandleBefore, gdi->getUnregisterTrimNotificationArg().Handle);
|
|
|
|
}
|
2019-01-16 22:09:33 +08:00
|
|
|
|
2019-03-06 15:39:06 +08:00
|
|
|
using WddmLockWithMakeResidentTests = Wddm20Tests;
|
|
|
|
|
|
|
|
TEST_F(WddmLockWithMakeResidentTests, givenAllocationThatDoesntNeedMakeResidentBeforeLockWhenLockThenDontStoreItOrCallMakeResident) {
|
2019-07-12 22:50:14 +08:00
|
|
|
EXPECT_TRUE(mockTemporaryResources->resourceHandles.empty());
|
2019-01-16 22:09:33 +08:00
|
|
|
EXPECT_EQ(0u, wddm->makeResidentResult.called);
|
2019-03-06 15:39:06 +08:00
|
|
|
wddm->lockResource(ALLOCATION_HANDLE, false);
|
2019-07-12 22:50:14 +08:00
|
|
|
EXPECT_TRUE(mockTemporaryResources->resourceHandles.empty());
|
2019-01-16 22:09:33 +08:00
|
|
|
EXPECT_EQ(0u, wddm->makeResidentResult.called);
|
2019-03-06 15:39:06 +08:00
|
|
|
wddm->unlockResource(ALLOCATION_HANDLE);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, givenAllocationThatNeedsMakeResidentBeforeLockWhenLockThenCallBlockingMakeResident) {
|
|
|
|
wddm->lockResource(ALLOCATION_HANDLE, true);
|
2019-07-12 22:50:14 +08:00
|
|
|
EXPECT_EQ(1u, mockTemporaryResources->makeResidentResult.called);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, givenAllocationWhenApplyBlockingMakeResidentThenAcquireUniqueLock) {
|
2019-07-12 22:50:14 +08:00
|
|
|
wddm->temporaryResources->makeResidentResource(ALLOCATION_HANDLE);
|
|
|
|
EXPECT_EQ(1u, mockTemporaryResources->acquireLockResult.called);
|
|
|
|
EXPECT_EQ(reinterpret_cast<uint64_t>(&mockTemporaryResources->resourcesLock), mockTemporaryResources->acquireLockResult.uint64ParamPassed);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, givenAllocationWhenApplyBlockingMakeResidentThenCallMakeResidentAndStoreAllocation) {
|
2019-07-12 22:50:14 +08:00
|
|
|
wddm->temporaryResources->makeResidentResource(ALLOCATION_HANDLE);
|
2019-01-16 22:09:33 +08:00
|
|
|
EXPECT_EQ(1u, wddm->makeResidentResult.called);
|
2019-07-12 22:50:14 +08:00
|
|
|
EXPECT_EQ(ALLOCATION_HANDLE, mockTemporaryResources->resourceHandles.back());
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, givenAllocationWhenApplyBlockingMakeResidentThenWaitForCurrentPagingFenceValue) {
|
2019-01-16 22:09:33 +08:00
|
|
|
wddm->mockPagingFence = 0u;
|
|
|
|
wddm->currentPagingFenceValue = 3u;
|
2019-07-12 22:50:14 +08:00
|
|
|
wddm->temporaryResources->makeResidentResource(ALLOCATION_HANDLE);
|
2019-01-16 22:09:33 +08:00
|
|
|
EXPECT_EQ(1u, wddm->makeResidentResult.called);
|
|
|
|
EXPECT_EQ(3u, wddm->mockPagingFence);
|
|
|
|
EXPECT_EQ(3u, wddm->getPagingFenceAddressResult.called);
|
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, givenAllocationWhenApplyBlockingMakeResidentAndMakeResidentCallFailsThenEvictTemporaryResourcesAndRetry) {
|
2019-03-05 16:25:18 +08:00
|
|
|
MockWddmAllocation allocation;
|
2019-07-12 22:50:14 +08:00
|
|
|
allocation.handle = 0x3;
|
2019-11-07 01:14:30 +08:00
|
|
|
GmockWddm gmockWddm(*executionEnvironment->rootDeviceEnvironments[0].get());
|
2019-07-12 22:50:14 +08:00
|
|
|
auto mockTemporaryResources = reinterpret_cast<MockWddmResidentAllocationsContainer *>(gmockWddm.temporaryResources.get());
|
2019-01-16 22:09:33 +08:00
|
|
|
EXPECT_CALL(gmockWddm, makeResident(&allocation.handle, ::testing::_, ::testing::_, ::testing::_)).Times(2).WillRepeatedly(::testing::Return(false));
|
2019-07-12 22:50:14 +08:00
|
|
|
gmockWddm.temporaryResources->makeResidentResource(allocation.handle);
|
|
|
|
EXPECT_EQ(1u, mockTemporaryResources->evictAllResourcesResult.called);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, whenApplyBlockingMakeResidentAndTemporaryResourcesAreEvictedSuccessfullyThenCallMakeResidentOneMoreTime) {
|
2019-03-05 16:25:18 +08:00
|
|
|
MockWddmAllocation allocation;
|
2019-07-12 22:50:14 +08:00
|
|
|
allocation.handle = 0x3;
|
2019-11-07 01:14:30 +08:00
|
|
|
GmockWddm gmockWddm(*executionEnvironment->rootDeviceEnvironments[0].get());
|
2019-07-12 22:50:14 +08:00
|
|
|
auto mockTemporaryResources = reinterpret_cast<MockWddmResidentAllocationsContainer *>(gmockWddm.temporaryResources.get());
|
|
|
|
mockTemporaryResources->resourceHandles.push_back(allocation.handle);
|
2019-01-16 22:09:33 +08:00
|
|
|
EXPECT_CALL(gmockWddm, evict(::testing::_, ::testing::_, ::testing::_)).Times(1).WillRepeatedly(::testing::Return(true));
|
|
|
|
EXPECT_CALL(gmockWddm, makeResident(&allocation.handle, ::testing::_, ::testing::_, ::testing::_)).Times(3).WillRepeatedly(::testing::Return(false));
|
2019-07-12 22:50:14 +08:00
|
|
|
gmockWddm.temporaryResources->makeResidentResource(allocation.handle);
|
|
|
|
EXPECT_EQ(2u, mockTemporaryResources->evictAllResourcesResult.called);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, whenApplyBlockingMakeResidentAndMakeResidentStillFailsThenDontStoreTemporaryResource) {
|
2019-03-05 16:25:18 +08:00
|
|
|
MockWddmAllocation allocation;
|
2019-01-16 22:09:33 +08:00
|
|
|
allocation.handle = 0x2;
|
2019-11-07 01:14:30 +08:00
|
|
|
GmockWddm gmockWddm(*executionEnvironment->rootDeviceEnvironments[0].get());
|
2019-07-12 22:50:14 +08:00
|
|
|
auto mockTemporaryResources = reinterpret_cast<MockWddmResidentAllocationsContainer *>(gmockWddm.temporaryResources.get());
|
|
|
|
mockTemporaryResources->resourceHandles.push_back(0x1);
|
2019-01-16 22:09:33 +08:00
|
|
|
EXPECT_CALL(gmockWddm, evict(::testing::_, ::testing::_, ::testing::_)).Times(1).WillRepeatedly(::testing::Return(true));
|
|
|
|
EXPECT_CALL(gmockWddm, makeResident(&allocation.handle, ::testing::_, ::testing::_, ::testing::_)).Times(3).WillRepeatedly(::testing::Return(false));
|
2019-07-12 22:50:14 +08:00
|
|
|
EXPECT_EQ(1u, mockTemporaryResources->resourceHandles.size());
|
|
|
|
gmockWddm.temporaryResources->makeResidentResource(allocation.handle);
|
|
|
|
EXPECT_EQ(0u, mockTemporaryResources->resourceHandles.size());
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, whenApplyBlockingMakeResidentAndMakeResidentPassesAfterEvictThenStoreTemporaryResource) {
|
2019-03-05 16:25:18 +08:00
|
|
|
MockWddmAllocation allocation;
|
2019-01-16 22:09:33 +08:00
|
|
|
allocation.handle = 0x2;
|
2019-11-07 01:14:30 +08:00
|
|
|
GmockWddm gmockWddm(*executionEnvironment->rootDeviceEnvironments[0].get());
|
2019-07-12 22:50:14 +08:00
|
|
|
auto mockTemporaryResources = reinterpret_cast<MockWddmResidentAllocationsContainer *>(gmockWddm.temporaryResources.get());
|
|
|
|
mockTemporaryResources->resourceHandles.push_back(0x1);
|
2019-01-16 22:09:33 +08:00
|
|
|
EXPECT_CALL(gmockWddm, evict(::testing::_, ::testing::_, ::testing::_)).Times(1).WillRepeatedly(::testing::Return(true));
|
|
|
|
EXPECT_CALL(gmockWddm, makeResident(&allocation.handle, ::testing::_, ::testing::_, ::testing::_)).Times(2).WillOnce(::testing::Return(false)).WillOnce(::testing::Return(true));
|
2019-07-12 22:50:14 +08:00
|
|
|
EXPECT_EQ(1u, mockTemporaryResources->resourceHandles.size());
|
|
|
|
gmockWddm.temporaryResources->makeResidentResource(allocation.handle);
|
|
|
|
EXPECT_EQ(1u, mockTemporaryResources->resourceHandles.size());
|
|
|
|
EXPECT_EQ(0x2, mockTemporaryResources->resourceHandles.back());
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, whenApplyBlockingMakeResidentAndMakeResidentPassesThenStoreTemporaryResource) {
|
2019-03-05 16:25:18 +08:00
|
|
|
MockWddmAllocation allocation;
|
2019-01-16 22:09:33 +08:00
|
|
|
allocation.handle = 0x2;
|
2019-11-07 01:14:30 +08:00
|
|
|
GmockWddm gmockWddm(*executionEnvironment->rootDeviceEnvironments[0].get());
|
2019-07-12 22:50:14 +08:00
|
|
|
auto mockTemporaryResources = reinterpret_cast<MockWddmResidentAllocationsContainer *>(gmockWddm.temporaryResources.get());
|
|
|
|
mockTemporaryResources->resourceHandles.push_back(0x1);
|
2019-01-16 22:09:33 +08:00
|
|
|
EXPECT_CALL(gmockWddm, makeResident(&allocation.handle, ::testing::_, ::testing::_, ::testing::_)).Times(1).WillOnce(::testing::Return(true));
|
2019-07-12 22:50:14 +08:00
|
|
|
gmockWddm.temporaryResources->makeResidentResource(allocation.handle);
|
|
|
|
EXPECT_EQ(2u, mockTemporaryResources->resourceHandles.size());
|
|
|
|
EXPECT_EQ(0x2, mockTemporaryResources->resourceHandles.back());
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, givenNoTemporaryResourcesWhenEvictingAllTemporaryResourcesThenEvictionIsNotApplied) {
|
2019-07-12 22:50:14 +08:00
|
|
|
wddm->getTemporaryResourcesContainer()->evictAllResources();
|
2019-08-29 19:46:49 +08:00
|
|
|
EXPECT_EQ(MemoryOperationsStatus::MEMORY_NOT_FOUND, mockTemporaryResources->evictAllResourcesResult.operationSuccess);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, whenEvictingAllTemporaryResourcesThenAcquireTemporaryResourcesLock) {
|
2019-07-12 22:50:14 +08:00
|
|
|
wddm->getTemporaryResourcesContainer()->evictAllResources();
|
|
|
|
EXPECT_EQ(1u, mockTemporaryResources->acquireLockResult.called);
|
|
|
|
EXPECT_EQ(reinterpret_cast<uint64_t>(&mockTemporaryResources->resourcesLock), mockTemporaryResources->acquireLockResult.uint64ParamPassed);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, whenEvictingAllTemporaryResourcesAndAllEvictionsSucceedThenReturnSuccess) {
|
2019-03-05 16:25:18 +08:00
|
|
|
MockWddmAllocation allocation;
|
2019-11-07 01:14:30 +08:00
|
|
|
GmockWddm gmockWddm(*executionEnvironment->rootDeviceEnvironments[0].get());
|
2019-07-12 22:50:14 +08:00
|
|
|
auto mockTemporaryResources = reinterpret_cast<MockWddmResidentAllocationsContainer *>(gmockWddm.temporaryResources.get());
|
|
|
|
mockTemporaryResources->resourceHandles.push_back(allocation.handle);
|
2019-01-16 22:09:33 +08:00
|
|
|
EXPECT_CALL(gmockWddm, evict(::testing::_, ::testing::_, ::testing::_)).Times(1).WillOnce(::testing::Return(true));
|
2019-07-12 22:50:14 +08:00
|
|
|
gmockWddm.getTemporaryResourcesContainer()->evictAllResources();
|
|
|
|
EXPECT_EQ(1u, mockTemporaryResources->evictAllResourcesResult.called);
|
2019-08-29 19:46:49 +08:00
|
|
|
EXPECT_EQ(MemoryOperationsStatus::SUCCESS, mockTemporaryResources->evictAllResourcesResult.operationSuccess);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, givenThreeAllocationsWhenEvictingAllTemporaryResourcesThenCallEvictForEachAllocationAndCleanList) {
|
2019-11-07 01:14:30 +08:00
|
|
|
GmockWddm gmockWddm(*executionEnvironment->rootDeviceEnvironments[0].get());
|
2019-07-12 22:50:14 +08:00
|
|
|
auto mockTemporaryResources = reinterpret_cast<MockWddmResidentAllocationsContainer *>(gmockWddm.temporaryResources.get());
|
2019-01-16 22:09:33 +08:00
|
|
|
constexpr uint32_t numAllocations = 3u;
|
|
|
|
for (auto i = 0u; i < numAllocations; i++) {
|
2019-07-12 22:50:14 +08:00
|
|
|
mockTemporaryResources->resourceHandles.push_back(i);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-07-12 22:50:14 +08:00
|
|
|
EXPECT_CALL(gmockWddm, evict(::testing::_, ::testing::_, ::testing::_)).Times(1).WillRepeatedly(::testing::Return(true));
|
|
|
|
gmockWddm.getTemporaryResourcesContainer()->evictAllResources();
|
|
|
|
EXPECT_TRUE(mockTemporaryResources->resourceHandles.empty());
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, givenThreeAllocationsWhenEvictingAllTemporaryResourcesAndOneOfThemFailsThenReturnFail) {
|
2019-11-07 01:14:30 +08:00
|
|
|
GmockWddm gmockWddm(*executionEnvironment->rootDeviceEnvironments[0].get());
|
2019-07-12 22:50:14 +08:00
|
|
|
auto mockTemporaryResources = reinterpret_cast<MockWddmResidentAllocationsContainer *>(gmockWddm.temporaryResources.get());
|
2019-01-16 22:09:33 +08:00
|
|
|
constexpr uint32_t numAllocations = 3u;
|
|
|
|
for (auto i = 0u; i < numAllocations; i++) {
|
2019-07-12 22:50:14 +08:00
|
|
|
mockTemporaryResources->resourceHandles.push_back(i);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-07-12 22:50:14 +08:00
|
|
|
EXPECT_CALL(gmockWddm, evict(::testing::_, ::testing::_, ::testing::_)).Times(1).WillOnce(::testing::Return(false));
|
|
|
|
gmockWddm.getTemporaryResourcesContainer()->evictAllResources();
|
2019-08-29 19:46:49 +08:00
|
|
|
EXPECT_EQ(MemoryOperationsStatus::FAILED, mockTemporaryResources->evictAllResourcesResult.operationSuccess);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, givenNoTemporaryResourcesWhenEvictingTemporaryResourceThenEvictionIsNotApplied) {
|
2019-07-12 22:50:14 +08:00
|
|
|
wddm->getTemporaryResourcesContainer()->evictResource(ALLOCATION_HANDLE);
|
2019-08-29 19:46:49 +08:00
|
|
|
EXPECT_EQ(MemoryOperationsStatus::MEMORY_NOT_FOUND, mockTemporaryResources->evictResourceResult.operationSuccess);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, whenEvictingTemporaryResourceThenAcquireTemporaryResourcesLock) {
|
2019-07-12 22:50:14 +08:00
|
|
|
wddm->getTemporaryResourcesContainer()->evictResource(ALLOCATION_HANDLE);
|
|
|
|
EXPECT_EQ(1u, mockTemporaryResources->acquireLockResult.called);
|
|
|
|
EXPECT_EQ(reinterpret_cast<uint64_t>(&mockTemporaryResources->resourcesLock), mockTemporaryResources->acquireLockResult.uint64ParamPassed);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, whenEvictingNonExistingTemporaryResourceThenEvictIsNotAppliedAndTemporaryResourcesAreRestored) {
|
2019-07-12 22:50:14 +08:00
|
|
|
mockTemporaryResources->resourceHandles.push_back(ALLOCATION_HANDLE);
|
|
|
|
EXPECT_FALSE(mockTemporaryResources->resourceHandles.empty());
|
|
|
|
wddm->getTemporaryResourcesContainer()->evictResource(ALLOCATION_HANDLE + 1);
|
|
|
|
EXPECT_FALSE(mockTemporaryResources->resourceHandles.empty());
|
2019-08-29 19:46:49 +08:00
|
|
|
EXPECT_EQ(MemoryOperationsStatus::MEMORY_NOT_FOUND, mockTemporaryResources->evictResourceResult.operationSuccess);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, whenEvictingTemporaryResourceAndEvictFailsThenReturnFail) {
|
2019-11-07 01:14:30 +08:00
|
|
|
GmockWddm gmockWddm(*executionEnvironment->rootDeviceEnvironments[0].get());
|
2019-07-12 22:50:14 +08:00
|
|
|
auto mockTemporaryResources = reinterpret_cast<MockWddmResidentAllocationsContainer *>(gmockWddm.temporaryResources.get());
|
|
|
|
mockTemporaryResources->resourceHandles.push_back(ALLOCATION_HANDLE);
|
2019-01-16 22:09:33 +08:00
|
|
|
EXPECT_CALL(gmockWddm, evict(::testing::_, ::testing::_, ::testing::_)).Times(1).WillOnce(::testing::Return(false));
|
2019-07-12 22:50:14 +08:00
|
|
|
gmockWddm.getTemporaryResourcesContainer()->evictResource(ALLOCATION_HANDLE);
|
|
|
|
EXPECT_TRUE(mockTemporaryResources->resourceHandles.empty());
|
2019-08-29 19:46:49 +08:00
|
|
|
EXPECT_EQ(MemoryOperationsStatus::FAILED, mockTemporaryResources->evictResourceResult.operationSuccess);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, whenEvictingTemporaryResourceAndEvictSucceedThenReturnSuccess) {
|
2019-11-07 01:14:30 +08:00
|
|
|
GmockWddm gmockWddm(*executionEnvironment->rootDeviceEnvironments[0].get());
|
2019-07-12 22:50:14 +08:00
|
|
|
auto mockTemporaryResources = reinterpret_cast<MockWddmResidentAllocationsContainer *>(gmockWddm.temporaryResources.get());
|
|
|
|
mockTemporaryResources->resourceHandles.push_back(ALLOCATION_HANDLE);
|
2019-01-16 22:09:33 +08:00
|
|
|
EXPECT_CALL(gmockWddm, evict(::testing::_, ::testing::_, ::testing::_)).Times(1).WillOnce(::testing::Return(true));
|
2019-07-12 22:50:14 +08:00
|
|
|
gmockWddm.getTemporaryResourcesContainer()->evictResource(ALLOCATION_HANDLE);
|
|
|
|
EXPECT_TRUE(mockTemporaryResources->resourceHandles.empty());
|
2019-08-29 19:46:49 +08:00
|
|
|
EXPECT_EQ(MemoryOperationsStatus::SUCCESS, mockTemporaryResources->evictResourceResult.operationSuccess);
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, whenEvictingTemporaryResourceThenOtherResourcesRemainOnTheList) {
|
2019-07-12 22:50:14 +08:00
|
|
|
mockTemporaryResources->resourceHandles.push_back(0x1);
|
|
|
|
mockTemporaryResources->resourceHandles.push_back(0x2);
|
|
|
|
mockTemporaryResources->resourceHandles.push_back(0x3);
|
2019-01-16 22:09:33 +08:00
|
|
|
|
2019-07-12 22:50:14 +08:00
|
|
|
wddm->getTemporaryResourcesContainer()->evictResource(0x2);
|
2019-01-16 22:09:33 +08:00
|
|
|
|
2019-07-12 22:50:14 +08:00
|
|
|
EXPECT_EQ(2u, mockTemporaryResources->resourceHandles.size());
|
|
|
|
EXPECT_EQ(0x1, mockTemporaryResources->resourceHandles.front());
|
|
|
|
EXPECT_EQ(0x3, mockTemporaryResources->resourceHandles.back());
|
2019-01-16 22:09:33 +08:00
|
|
|
}
|
2019-01-29 01:12:39 +08:00
|
|
|
|
2019-03-06 15:39:06 +08:00
|
|
|
TEST_F(WddmLockWithMakeResidentTests, whenAlllocationNeedsBlockingMakeResidentBeforeLockThenLockWithBlockingMakeResident) {
|
2019-03-22 00:45:00 +08:00
|
|
|
WddmMemoryManager memoryManager(*executionEnvironment);
|
2019-03-06 15:39:06 +08:00
|
|
|
MockWddmAllocation allocation;
|
|
|
|
allocation.needsMakeResidentBeforeLock = false;
|
|
|
|
memoryManager.lockResource(&allocation);
|
|
|
|
EXPECT_EQ(1u, wddm->lockResult.called);
|
|
|
|
EXPECT_EQ(0u, wddm->lockResult.uint64ParamPassed);
|
|
|
|
memoryManager.unlockResource(&allocation);
|
|
|
|
|
|
|
|
allocation.needsMakeResidentBeforeLock = true;
|
|
|
|
memoryManager.lockResource(&allocation);
|
|
|
|
EXPECT_EQ(2u, wddm->lockResult.called);
|
|
|
|
EXPECT_EQ(1u, wddm->lockResult.uint64ParamPassed);
|
|
|
|
memoryManager.unlockResource(&allocation);
|
|
|
|
}
|
2019-03-01 23:14:28 +08:00
|
|
|
using WddmGfxPartitionTest = Wddm20Tests;
|
|
|
|
|
|
|
|
TEST_F(WddmGfxPartitionTest, initGfxPartition) {
|
|
|
|
MockGfxPartition gfxPartition;
|
|
|
|
|
|
|
|
for (auto heap : MockGfxPartition::allHeapNames) {
|
|
|
|
ASSERT_FALSE(gfxPartition.heapInitialized(heap));
|
|
|
|
}
|
|
|
|
|
|
|
|
wddm->initGfxPartition(gfxPartition);
|
|
|
|
|
|
|
|
for (auto heap : MockGfxPartition::allHeapNames) {
|
|
|
|
if (!gfxPartition.heapInitialized(heap)) {
|
2020-01-08 19:36:09 +08:00
|
|
|
EXPECT_TRUE(heap == HeapIndex::HEAP_SVM || heap == HeapIndex::HEAP_EXTENDED);
|
2019-03-01 23:14:28 +08:00
|
|
|
} else {
|
|
|
|
EXPECT_TRUE(gfxPartition.heapInitialized(heap));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-09-13 18:14:06 +08:00
|
|
|
|
|
|
|
TEST_F(Wddm20Tests, givenWddmWhenOpenAdapterAndForceDeviceIdIsTheSameAsTheExistingDeviceThenReturnTrue) {
|
|
|
|
DebugManagerStateRestore stateRestore;
|
|
|
|
DebugManager.flags.ForceDeviceId.set("1234"); // Existing device Id
|
2019-11-07 01:14:30 +08:00
|
|
|
struct MockWddm : public Wddm {
|
2019-09-13 18:14:06 +08:00
|
|
|
using Wddm::openAdapter;
|
2019-11-07 01:14:30 +08:00
|
|
|
|
|
|
|
MockWddm(RootDeviceEnvironment &rootDeviceEnvironment) : Wddm(rootDeviceEnvironment) {}
|
2019-09-13 18:14:06 +08:00
|
|
|
};
|
2019-11-07 01:14:30 +08:00
|
|
|
|
|
|
|
MockWddm wddm(*executionEnvironment->rootDeviceEnvironments[0].get());
|
2019-09-13 18:14:06 +08:00
|
|
|
bool result = wddm.openAdapter();
|
|
|
|
EXPECT_TRUE(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(Wddm20Tests, givenWddmWhenOpenAdapterAndForceDeviceIdIsDifferentFromTheExistingDeviceThenReturnFalse) {
|
|
|
|
DebugManagerStateRestore stateRestore;
|
|
|
|
DebugManager.flags.ForceDeviceId.set("1111");
|
2019-11-07 01:14:30 +08:00
|
|
|
struct MockWddm : public Wddm {
|
2019-09-13 18:14:06 +08:00
|
|
|
using Wddm::openAdapter;
|
2019-11-07 01:14:30 +08:00
|
|
|
|
|
|
|
MockWddm(RootDeviceEnvironment &rootDeviceEnvironment) : Wddm(rootDeviceEnvironment) {}
|
2019-09-13 18:14:06 +08:00
|
|
|
};
|
2019-11-07 01:14:30 +08:00
|
|
|
|
|
|
|
MockWddm wddm(*executionEnvironment->rootDeviceEnvironments[0].get());
|
2019-09-13 18:14:06 +08:00
|
|
|
bool result = wddm.openAdapter();
|
|
|
|
EXPECT_FALSE(result);
|
|
|
|
}
|
2019-12-17 21:29:28 +08:00
|
|
|
|
|
|
|
TEST_F(WddmTest, WhenFeatureFlagHwQueueIsDisabledThenReturnWddm20Version) {
|
|
|
|
wddm->featureTable->ftrWddmHwQueues = 0;
|
|
|
|
EXPECT_EQ(WddmVersion::WDDM_2_0, wddm->getWddmVersion());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(WddmTest, WhenFeatureFlagHwQueueIsEnabledThenReturnWddm23Version) {
|
|
|
|
wddm->featureTable->ftrWddmHwQueues = 1;
|
|
|
|
EXPECT_EQ(WddmVersion::WDDM_2_3, wddm->getWddmVersion());
|
|
|
|
}
|
2019-12-17 22:26:00 +08:00
|
|
|
|
|
|
|
TEST_F(Wddm20WithMockGdiDllTests, GivenCreationSucceedWhenCreatingSeparateMonitorFenceThenReturnFilledStructure) {
|
|
|
|
MonitoredFence monitorFence = {0};
|
|
|
|
|
|
|
|
bool ret = wddmMockInterface->createMonitoredFence(monitorFence);
|
|
|
|
EXPECT_TRUE(ret);
|
|
|
|
|
|
|
|
EXPECT_EQ(4u, monitorFence.fenceHandle);
|
|
|
|
EXPECT_EQ(getMonitorFenceCpuFenceAddressFcn(), monitorFence.cpuAddress);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(Wddm20WithMockGdiDllTests, GivenCreationFailWhenCreatingSeparateMonitorFenceThenReturnNotFilledStructure) {
|
|
|
|
MonitoredFence monitorFence = {0};
|
|
|
|
|
|
|
|
*getCreateSynchronizationObject2FailCallFcn() = true;
|
|
|
|
bool ret = wddmMockInterface->createMonitoredFence(monitorFence);
|
|
|
|
EXPECT_FALSE(ret);
|
|
|
|
|
|
|
|
EXPECT_EQ(0u, monitorFence.fenceHandle);
|
|
|
|
void *retAddress = reinterpret_cast<void *>(0);
|
|
|
|
EXPECT_EQ(retAddress, monitorFence.cpuAddress);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(Wddm20WithMockGdiDllTests, WhenDestroyingSeparateMonitorFenceThenExpectGdiCalled) {
|
|
|
|
MonitoredFence monitorFence = {0};
|
|
|
|
monitorFence.fenceHandle = 10u;
|
|
|
|
|
|
|
|
wddmMockInterface->destroyMonitorFence(monitorFence);
|
|
|
|
|
|
|
|
EXPECT_EQ(monitorFence.fenceHandle, getDestroySynchronizationObjectDataFcn()->hSyncObject);
|
|
|
|
}
|
2019-12-23 21:28:33 +08:00
|
|
|
namespace NEO {
|
|
|
|
long __stdcall notifyAubCapture(void *csrHandle, uint64_t gfxAddress, size_t gfxSize, bool allocate);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(Wddm20WithMockGdiDllTests, whenSetDeviceInfoSucceedsThenDeviceCallbacksArePassedToGmmMemory) {
|
|
|
|
GMM_DEVICE_CALLBACKS_INT expectedDeviceCb{};
|
|
|
|
auto hwInfoMock = *platformDevices[0];
|
|
|
|
wddm->init(hwInfoMock);
|
|
|
|
auto gdi = wddm->getGdi();
|
|
|
|
auto gmmMemory = static_cast<MockGmmMemory *>(wddm->getGmmMemory());
|
|
|
|
|
|
|
|
expectedDeviceCb.Adapter.KmtHandle = wddm->getAdapter();
|
|
|
|
expectedDeviceCb.hDevice.KmtHandle = wddm->getDevice();
|
|
|
|
expectedDeviceCb.hCsr = nullptr;
|
|
|
|
expectedDeviceCb.PagingQueue = wddm->getPagingQueue();
|
|
|
|
expectedDeviceCb.PagingFence = wddm->getPagingQueueSyncObject();
|
|
|
|
|
|
|
|
expectedDeviceCb.DevCbPtrs.KmtCbPtrs.pfnAllocate = gdi->createAllocation;
|
|
|
|
expectedDeviceCb.DevCbPtrs.KmtCbPtrs.pfnDeallocate = gdi->destroyAllocation;
|
|
|
|
expectedDeviceCb.DevCbPtrs.KmtCbPtrs.pfnMapGPUVA = gdi->mapGpuVirtualAddress;
|
|
|
|
expectedDeviceCb.DevCbPtrs.KmtCbPtrs.pfnMakeResident = gdi->makeResident;
|
|
|
|
expectedDeviceCb.DevCbPtrs.KmtCbPtrs.pfnEvict = gdi->evict;
|
|
|
|
expectedDeviceCb.DevCbPtrs.KmtCbPtrs.pfnReserveGPUVA = gdi->reserveGpuVirtualAddress;
|
|
|
|
expectedDeviceCb.DevCbPtrs.KmtCbPtrs.pfnUpdateGPUVA = gdi->updateGpuVirtualAddress;
|
|
|
|
expectedDeviceCb.DevCbPtrs.KmtCbPtrs.pfnWaitFromCpu = gdi->waitForSynchronizationObjectFromCpu;
|
|
|
|
expectedDeviceCb.DevCbPtrs.KmtCbPtrs.pfnLock = gdi->lock2;
|
|
|
|
expectedDeviceCb.DevCbPtrs.KmtCbPtrs.pfnUnLock = gdi->unlock2;
|
|
|
|
expectedDeviceCb.DevCbPtrs.KmtCbPtrs.pfnEscape = gdi->escape;
|
|
|
|
expectedDeviceCb.DevCbPtrs.KmtCbPtrs.pfnFreeGPUVA = gdi->freeGpuVirtualAddress;
|
|
|
|
expectedDeviceCb.DevCbPtrs.KmtCbPtrs.pfnNotifyAubCapture = notifyAubCapture;
|
|
|
|
|
|
|
|
EXPECT_TRUE(memcmp(&expectedDeviceCb, &gmmMemory->deviceCallbacks, sizeof(GMM_DEVICE_CALLBACKS_INT)) == 0);
|
|
|
|
EXPECT_TRUE(memcmp(&expectedDeviceCb.Adapter, &gmmMemory->deviceCallbacks.Adapter, sizeof(GMM_HANDLE_EXT)) == 0);
|
|
|
|
EXPECT_TRUE(memcmp(&expectedDeviceCb.hDevice, &gmmMemory->deviceCallbacks.hDevice, sizeof(GMM_HANDLE_EXT)) == 0);
|
|
|
|
EXPECT_TRUE(memcmp(&expectedDeviceCb.DevCbPtrs.KmtCbPtrs, &gmmMemory->deviceCallbacks.DevCbPtrs.KmtCbPtrs, sizeof(GMM_DEVICE_CB_PTRS::KmtCbPtrs)) == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(Wddm20WithMockGdiDllTests, whenSetDeviceInfoFailsThenDeviceIsNotConfigured) {
|
|
|
|
|
2020-01-24 22:03:28 +08:00
|
|
|
auto gmockGmmMemory = new ::testing::NiceMock<GmockGmmMemory>(executionEnvironment->getGmmClientContext());
|
2019-12-23 21:28:33 +08:00
|
|
|
ON_CALL(*gmockGmmMemory, setDeviceInfo(::testing::_))
|
|
|
|
.WillByDefault(::testing::Return(false));
|
|
|
|
EXPECT_CALL(*gmockGmmMemory, configureDeviceAddressSpace(::testing::_,
|
|
|
|
::testing::_,
|
|
|
|
::testing::_,
|
|
|
|
::testing::_,
|
|
|
|
::testing::_))
|
|
|
|
.Times(0);
|
|
|
|
|
|
|
|
wddm->gmmMemory.reset(gmockGmmMemory);
|
|
|
|
|
|
|
|
auto hwInfoMock = *platformDevices[0];
|
|
|
|
wddm->init(hwInfoMock);
|
|
|
|
}
|
|
|
|
|
|
|
|
HWTEST_F(Wddm20WithMockGdiDllTests, givenNonGen12LPPlatformWhenConfigureDeviceAddressSpaceThenDontObtainMinAddress) {
|
|
|
|
if (platformDevices[0]->platform.eRenderCoreFamily == IGFX_GEN12LP_CORE) {
|
|
|
|
GTEST_SKIP();
|
|
|
|
}
|
2020-01-24 22:03:28 +08:00
|
|
|
auto gmmMemory = new ::testing::NiceMock<GmockGmmMemory>(executionEnvironment->getGmmClientContext());
|
2019-12-23 21:28:33 +08:00
|
|
|
wddm->gmmMemory.reset(gmmMemory);
|
|
|
|
ON_CALL(*gmmMemory, configureDeviceAddressSpace(::testing::_,
|
|
|
|
::testing::_,
|
|
|
|
::testing::_,
|
|
|
|
::testing::_,
|
|
|
|
::testing::_))
|
|
|
|
.WillByDefault(::testing::Return(true));
|
|
|
|
|
|
|
|
EXPECT_CALL(*gmmMemory,
|
|
|
|
getInternalGpuVaRangeLimit())
|
|
|
|
.Times(0);
|
|
|
|
|
|
|
|
auto hwInfoMock = *platformDevices[0];
|
|
|
|
wddm->init(hwInfoMock);
|
|
|
|
|
|
|
|
EXPECT_EQ(NEO::windowsMinAddress, wddm->getWddmMinAddress());
|
|
|
|
}
|