Skip to content

Commit c0c6a46

Browse files
Wddm 2.3 improvements
- Dont create synchronization object manually - take it from HW queue - Construct MonitoredFence from HwQueue object - D3DKMT_SUBMITCOMMANDTOHWQUEUE should get currentFenceValue instead of its handle - Dont pass MonitoredFenceVa/Value in cmd buffer header Change-Id: I4717119379cef2f0e641ce9f4ef614089491a85d Signed-off-by: Dunajski, Bartosz <[email protected]> Related-To: NEO-3728
1 parent 49e17d7 commit c0c6a46

File tree

7 files changed

+70
-36
lines changed

7 files changed

+70
-36
lines changed

runtime/os_interface/windows/os_context_win.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ OsContextWin::OsContextWin(Wddm &wddm, uint32_t contextId, DeviceBitfield device
3434
return;
3535
}
3636
}
37-
initialized = wddmInterface->createMonitoredFence(residencyController);
37+
initialized = wddmInterface->createMonitoredFence(*this);
3838
residencyController.registerCallback();
3939
};
4040

4141
OsContextWin::~OsContextWin() {
42-
wddm.getWddmInterface()->destroyHwQueue(hwQueueHandle);
42+
wddm.getWddmInterface()->destroyHwQueue(hardwareQueue.handle);
4343
wddm.destroyContext(wddmContextHandle);
4444
}
4545

runtime/os_interface/windows/os_context_win.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@
1212
namespace NEO {
1313

1414
class Wddm;
15+
16+
struct HardwareQueue {
17+
D3DKMT_HANDLE handle = 0;
18+
D3DKMT_HANDLE progressFenceHandle = 0;
19+
VOID *progressFenceCpuVA = nullptr;
20+
D3DGPU_VIRTUAL_ADDRESS progressFenceGpuVA = 0;
21+
};
22+
1523
class OsContextWin : public OsContext {
1624
public:
1725
OsContextWin() = delete;
@@ -22,16 +30,16 @@ class OsContextWin : public OsContext {
2230

2331
D3DKMT_HANDLE getWddmContextHandle() const { return wddmContextHandle; }
2432
void setWddmContextHandle(D3DKMT_HANDLE wddmContextHandle) { this->wddmContextHandle = wddmContextHandle; }
25-
D3DKMT_HANDLE getHwQueue() const { return hwQueueHandle; }
26-
void setHwQueue(D3DKMT_HANDLE hwQueue) { hwQueueHandle = hwQueue; }
33+
HardwareQueue getHwQueue() const { return hardwareQueue; }
34+
void setHwQueue(HardwareQueue hardwareQueue) { this->hardwareQueue = hardwareQueue; }
2735
bool isInitialized() const { return initialized; }
2836
Wddm *getWddm() const { return &wddm; }
29-
WddmResidencyController &getResidencyController() { return residencyController; }
37+
MOCKABLE_VIRTUAL WddmResidencyController &getResidencyController() { return residencyController; }
3038

3139
protected:
3240
bool initialized = false;
3341
D3DKMT_HANDLE wddmContextHandle = 0;
34-
D3DKMT_HANDLE hwQueueHandle = 0;
42+
HardwareQueue hardwareQueue;
3543
Wddm &wddm;
3644
WddmResidencyController residencyController;
3745
};

runtime/os_interface/windows/wddm/wddm_interface.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ bool WddmInterface20::createHwQueue(OsContextWin &osContext) {
1919
}
2020
void WddmInterface20::destroyHwQueue(D3DKMT_HANDLE hwQueue) {}
2121

22-
bool WddmInterface::createMonitoredFence(WddmResidencyController &residencyController) {
22+
bool WddmInterface20::createMonitoredFence(OsContextWin &osContext) {
23+
auto &residencyController = osContext.getResidencyController();
2324
NTSTATUS Status;
2425
D3DKMT_CREATESYNCHRONIZATIONOBJECT2 CreateSynchronizationObject = {0};
2526
CreateSynchronizationObject.hDevice = wddm.getDevice();
@@ -80,11 +81,21 @@ bool WddmInterface23::createHwQueue(OsContextWin &osContext) {
8081

8182
auto status = wddm.getGdi()->createHwQueue(&createHwQueue);
8283
UNRECOVERABLE_IF(status != STATUS_SUCCESS);
83-
osContext.setHwQueue(createHwQueue.hHwQueue);
84+
osContext.setHwQueue({createHwQueue.hHwQueue, createHwQueue.hHwQueueProgressFence, createHwQueue.HwQueueProgressFenceCPUVirtualAddress,
85+
createHwQueue.HwQueueProgressFenceGPUVirtualAddress});
8486

8587
return status == STATUS_SUCCESS;
8688
}
8789

90+
bool WddmInterface23::createMonitoredFence(OsContextWin &osContext) {
91+
auto &residencyController = osContext.getResidencyController();
92+
auto hwQueue = osContext.getHwQueue();
93+
residencyController.resetMonitoredFenceParams(hwQueue.progressFenceHandle,
94+
reinterpret_cast<uint64_t *>(hwQueue.progressFenceCpuVA),
95+
hwQueue.progressFenceGpuVA);
96+
return true;
97+
}
98+
8899
void WddmInterface23::destroyHwQueue(D3DKMT_HANDLE hwQueue) {
89100
if (hwQueue) {
90101
D3DKMT_DESTROYHWQUEUE destroyHwQueue = {};
@@ -103,15 +114,11 @@ bool WddmInterface23::submit(uint64_t commandBuffer, size_t size, void *commandH
103114
auto monitoredFence = osContext.getResidencyController().getMonitoredFence();
104115

105116
D3DKMT_SUBMITCOMMANDTOHWQUEUE submitCommand = {};
106-
submitCommand.hHwQueue = osContext.getHwQueue();
107-
submitCommand.HwQueueProgressFenceId = monitoredFence.fenceHandle;
117+
submitCommand.hHwQueue = osContext.getHwQueue().handle;
118+
submitCommand.HwQueueProgressFenceId = monitoredFence.currentFenceValue;
108119
submitCommand.CommandBuffer = commandBuffer;
109120
submitCommand.CommandLength = static_cast<UINT>(size);
110121

111-
COMMAND_BUFFER_HEADER *pHeader = reinterpret_cast<COMMAND_BUFFER_HEADER *>(commandHeader);
112-
pHeader->MonitorFenceVA = monitoredFence.gpuAddress;
113-
pHeader->MonitorFenceValue = monitoredFence.currentFenceValue;
114-
115122
submitCommand.pPrivateDriverData = commandHeader;
116123
submitCommand.PrivateDriverDataSize = MemoryConstants::pageSize;
117124

runtime/os_interface/windows/wddm/wddm_interface.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class WddmInterface {
2727
WddmInterface() = delete;
2828
virtual bool createHwQueue(OsContextWin &osContext) = 0;
2929
virtual void destroyHwQueue(D3DKMT_HANDLE hwQueue) = 0;
30-
bool createMonitoredFence(WddmResidencyController &residencyController);
30+
virtual bool createMonitoredFence(OsContextWin &osContext) = 0;
3131
virtual const bool hwQueuesSupported() = 0;
3232
virtual bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, OsContextWin &osContext) = 0;
3333
Wddm &wddm;
@@ -38,6 +38,7 @@ class WddmInterface20 : public WddmInterface {
3838
using WddmInterface::WddmInterface;
3939
bool createHwQueue(OsContextWin &osContext) override;
4040
void destroyHwQueue(D3DKMT_HANDLE hwQueue) override;
41+
bool createMonitoredFence(OsContextWin &osContext) override;
4142
const bool hwQueuesSupported() override;
4243
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, OsContextWin &osContext) override;
4344
};
@@ -47,6 +48,7 @@ class WddmInterface23 : public WddmInterface {
4748
using WddmInterface::WddmInterface;
4849
bool createHwQueue(OsContextWin &osContext) override;
4950
void destroyHwQueue(D3DKMT_HANDLE hwQueue) override;
51+
bool createMonitoredFence(OsContextWin &osContext) override;
5052
const bool hwQueuesSupported() override;
5153
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, OsContextWin &osContext) override;
5254
};

unit_tests/os_interface/windows/wddm20_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ TEST_F(Wddm20Tests, createMonitoredFenceIsInitializedWithFenceValueZeroAndCurren
649649

650650
gdi->getCreateSynchronizationObject2Arg().Info.MonitoredFence.InitialFenceValue = 300;
651651

652-
wddm->wddmInterface->createMonitoredFence(osContext->getResidencyController());
652+
wddm->wddmInterface->createMonitoredFence(*osContext);
653653

654654
EXPECT_EQ(0u, gdi->getCreateSynchronizationObject2Arg().Info.MonitoredFence.InitialFenceValue);
655655
EXPECT_EQ(1u, osContext->getResidencyController().getMonitoredFence().currentFenceValue);

unit_tests/os_interface/windows/wddm23_tests.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,19 +86,19 @@ TEST_F(Wddm23Tests, givenPreemptionModeWhenCreateHwQueueCalledThenSetGpuTimeoutI
8686

8787
TEST_F(Wddm23Tests, whenDestroyHwQueueCalledThenPassExistingHandle) {
8888
D3DKMT_HANDLE hwQueue = 123;
89-
osContext->setHwQueue(hwQueue);
90-
wddmMockInterface->destroyHwQueue(osContext->getHwQueue());
89+
osContext->setHwQueue({hwQueue, 0, nullptr, 0});
90+
wddmMockInterface->destroyHwQueue(osContext->getHwQueue().handle);
9191
EXPECT_EQ(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue);
9292

9393
hwQueue = 0;
94-
osContext->setHwQueue(hwQueue);
95-
wddmMockInterface->destroyHwQueue(osContext->getHwQueue());
94+
osContext->setHwQueue({hwQueue, 0, nullptr, 0});
95+
wddmMockInterface->destroyHwQueue(osContext->getHwQueue().handle);
9696
EXPECT_NE(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue); // gdi not called when 0
9797
}
9898

9999
TEST_F(Wddm23Tests, whenObjectIsDestructedThenDestroyHwQueue) {
100100
D3DKMT_HANDLE hwQueue = 123;
101-
osContext->setHwQueue(hwQueue);
101+
osContext->setHwQueue({hwQueue, 0, nullptr, 0});
102102
osContext.reset();
103103
EXPECT_EQ(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue);
104104
}
@@ -116,24 +116,25 @@ TEST_F(Wddm23Tests, givenCmdBufferWhenSubmitCalledThenSetAllRequiredFiledsAndUpd
116116

117117
EXPECT_EQ(cmdBufferAddress, getSubmitCommandToHwQueueDataFcn()->CommandBuffer);
118118
EXPECT_EQ(static_cast<UINT>(cmdSize), getSubmitCommandToHwQueueDataFcn()->CommandLength);
119-
EXPECT_EQ(hwQueue, getSubmitCommandToHwQueueDataFcn()->hHwQueue);
120-
EXPECT_EQ(osContext->getResidencyController().getMonitoredFence().fenceHandle, getSubmitCommandToHwQueueDataFcn()->HwQueueProgressFenceId);
119+
EXPECT_EQ(hwQueue.handle, getSubmitCommandToHwQueueDataFcn()->hHwQueue);
120+
EXPECT_EQ(osContext->getResidencyController().getMonitoredFence().lastSubmittedFence, getSubmitCommandToHwQueueDataFcn()->HwQueueProgressFenceId);
121121
EXPECT_EQ(&cmdBufferHeader, getSubmitCommandToHwQueueDataFcn()->pPrivateDriverData);
122122
EXPECT_EQ(static_cast<UINT>(MemoryConstants::pageSize), getSubmitCommandToHwQueueDataFcn()->PrivateDriverDataSize);
123123

124-
EXPECT_EQ(osContext->getResidencyController().getMonitoredFence().gpuAddress, cmdBufferHeader.MonitorFenceVA);
125-
EXPECT_EQ(osContext->getResidencyController().getMonitoredFence().lastSubmittedFence, cmdBufferHeader.MonitorFenceValue);
124+
EXPECT_EQ(0u, cmdBufferHeader.MonitorFenceVA);
125+
EXPECT_EQ(0u, cmdBufferHeader.MonitorFenceValue);
126126
EXPECT_EQ(2u, osContext->getResidencyController().getMonitoredFence().currentFenceValue);
127127
EXPECT_EQ(1u, osContext->getResidencyController().getMonitoredFence().lastSubmittedFence);
128128
}
129129

130130
TEST_F(Wddm23Tests, whenMonitoredFenceIsCreatedThenSetupAllRequiredFields) {
131-
wddm->wddmInterface->createMonitoredFence(osContext->getResidencyController());
131+
wddm->wddmInterface->createMonitoredFence(*osContext);
132+
auto hwQueue = osContext->getHwQueue();
132133

133-
EXPECT_NE(nullptr, osContext->getResidencyController().getMonitoredFence().cpuAddress);
134+
EXPECT_EQ(hwQueue.progressFenceCpuVA, osContext->getResidencyController().getMonitoredFence().cpuAddress);
134135
EXPECT_EQ(1u, osContext->getResidencyController().getMonitoredFence().currentFenceValue);
135-
EXPECT_NE(static_cast<D3DKMT_HANDLE>(0), osContext->getResidencyController().getMonitoredFence().fenceHandle);
136-
EXPECT_NE(static_cast<D3DGPU_VIRTUAL_ADDRESS>(0), osContext->getResidencyController().getMonitoredFence().gpuAddress);
136+
EXPECT_EQ(hwQueue.progressFenceHandle, osContext->getResidencyController().getMonitoredFence().fenceHandle);
137+
EXPECT_EQ(hwQueue.progressFenceGpuVA, osContext->getResidencyController().getMonitoredFence().gpuAddress);
137138
EXPECT_EQ(0u, osContext->getResidencyController().getMonitoredFence().lastSubmittedFence);
138139
}
139140

unit_tests/os_interface/windows/wddm_residency_controller_tests.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,33 @@ class MockWddmResidencyController : public WddmResidencyController {
4848
}
4949
};
5050

51+
class MockOsContextWin : public OsContextWin {
52+
public:
53+
MockOsContextWin(Wddm &wddm, uint32_t contextId, DeviceBitfield deviceBitfield,
54+
aub_stream::EngineType engineType, PreemptionMode preemptionMode, bool lowPriority)
55+
: OsContextWin(wddm, contextId, deviceBitfield, engineType, preemptionMode, lowPriority),
56+
mockResidencyController(wddm, contextId) {}
57+
58+
WddmResidencyController &getResidencyController() override { return mockResidencyController; };
59+
60+
MockWddmResidencyController mockResidencyController;
61+
};
62+
5163
struct WddmResidencyControllerTest : ::testing::Test {
5264
const uint32_t osContextId = 0u;
5365

5466
void SetUp() {
5567
wddm = std::unique_ptr<WddmMock>(static_cast<WddmMock *>(Wddm::createWddm()));
5668
auto hwInfo = *platformDevices[0];
5769
wddm->init(hwInfo);
58-
residencyController = std::make_unique<MockWddmResidencyController>(*wddm, osContextId);
59-
wddm->getWddmInterface()->createMonitoredFence(*residencyController);
70+
mockOsContextWin = std::make_unique<MockOsContextWin>(*wddm, osContextId, 0, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false);
71+
wddm->getWddmInterface()->createMonitoredFence(*mockOsContextWin);
72+
residencyController = &mockOsContextWin->mockResidencyController;
6073
}
6174

6275
std::unique_ptr<WddmMock> wddm;
63-
std::unique_ptr<MockWddmResidencyController> residencyController;
76+
std::unique_ptr<MockOsContextWin> mockOsContextWin;
77+
MockWddmResidencyController *residencyController = nullptr;
6478
};
6579

6680
struct WddmResidencyControllerWithGdiTest : ::testing::Test {
@@ -73,13 +87,15 @@ struct WddmResidencyControllerWithGdiTest : ::testing::Test {
7387
auto hwInfo = *platformDevices[0];
7488
wddm->init(hwInfo);
7589

76-
residencyController = std::make_unique<MockWddmResidencyController>(*wddm, osContextId);
77-
wddm->getWddmInterface()->createMonitoredFence(*residencyController);
90+
mockOsContextWin = std::make_unique<MockOsContextWin>(*wddm, osContextId, 0, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false);
91+
wddm->getWddmInterface()->createMonitoredFence(*mockOsContextWin);
92+
residencyController = &mockOsContextWin->mockResidencyController;
7893
residencyController->registerCallback();
7994
}
8095

8196
std::unique_ptr<WddmMock> wddm;
82-
std::unique_ptr<MockWddmResidencyController> residencyController;
97+
std::unique_ptr<MockOsContextWin> mockOsContextWin;
98+
MockWddmResidencyController *residencyController = nullptr;
8399
MockGdi *gdi;
84100
};
85101

@@ -212,7 +228,7 @@ TEST_F(WddmResidencyControllerWithGdiTest, givenWddmResidencyControllerWhenItIsD
212228
auto trimCallbackAddress = reinterpret_cast<PFND3DKMT_TRIMNOTIFICATIONCALLBACK>(WddmResidencyController::trimCallback);
213229

214230
std::memset(&gdi->getUnregisterTrimNotificationArg(), 0, sizeof(D3DKMT_UNREGISTERTRIMNOTIFICATION));
215-
residencyController.reset();
231+
mockOsContextWin.reset();
216232

217233
EXPECT_EQ(trimCallbackAddress, gdi->getUnregisterTrimNotificationArg().Callback);
218234
EXPECT_EQ(trimCallbackHandle, gdi->getUnregisterTrimNotificationArg().Handle);

0 commit comments

Comments
 (0)