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 <bartosz.dunajski@intel.com>
Related-To: NEO-3728
This commit is contained in:
Dunajski, Bartosz
2019-09-13 08:13:02 +02:00
committed by sys_ocldev
parent 49e17d734e
commit c0c6a46ece
7 changed files with 70 additions and 36 deletions

View File

@ -34,12 +34,12 @@ OsContextWin::OsContextWin(Wddm &wddm, uint32_t contextId, DeviceBitfield device
return; return;
} }
} }
initialized = wddmInterface->createMonitoredFence(residencyController); initialized = wddmInterface->createMonitoredFence(*this);
residencyController.registerCallback(); residencyController.registerCallback();
}; };
OsContextWin::~OsContextWin() { OsContextWin::~OsContextWin() {
wddm.getWddmInterface()->destroyHwQueue(hwQueueHandle); wddm.getWddmInterface()->destroyHwQueue(hardwareQueue.handle);
wddm.destroyContext(wddmContextHandle); wddm.destroyContext(wddmContextHandle);
} }

View File

@ -12,6 +12,14 @@
namespace NEO { namespace NEO {
class Wddm; class Wddm;
struct HardwareQueue {
D3DKMT_HANDLE handle = 0;
D3DKMT_HANDLE progressFenceHandle = 0;
VOID *progressFenceCpuVA = nullptr;
D3DGPU_VIRTUAL_ADDRESS progressFenceGpuVA = 0;
};
class OsContextWin : public OsContext { class OsContextWin : public OsContext {
public: public:
OsContextWin() = delete; OsContextWin() = delete;
@ -22,16 +30,16 @@ class OsContextWin : public OsContext {
D3DKMT_HANDLE getWddmContextHandle() const { return wddmContextHandle; } D3DKMT_HANDLE getWddmContextHandle() const { return wddmContextHandle; }
void setWddmContextHandle(D3DKMT_HANDLE wddmContextHandle) { this->wddmContextHandle = wddmContextHandle; } void setWddmContextHandle(D3DKMT_HANDLE wddmContextHandle) { this->wddmContextHandle = wddmContextHandle; }
D3DKMT_HANDLE getHwQueue() const { return hwQueueHandle; } HardwareQueue getHwQueue() const { return hardwareQueue; }
void setHwQueue(D3DKMT_HANDLE hwQueue) { hwQueueHandle = hwQueue; } void setHwQueue(HardwareQueue hardwareQueue) { this->hardwareQueue = hardwareQueue; }
bool isInitialized() const { return initialized; } bool isInitialized() const { return initialized; }
Wddm *getWddm() const { return &wddm; } Wddm *getWddm() const { return &wddm; }
WddmResidencyController &getResidencyController() { return residencyController; } MOCKABLE_VIRTUAL WddmResidencyController &getResidencyController() { return residencyController; }
protected: protected:
bool initialized = false; bool initialized = false;
D3DKMT_HANDLE wddmContextHandle = 0; D3DKMT_HANDLE wddmContextHandle = 0;
D3DKMT_HANDLE hwQueueHandle = 0; HardwareQueue hardwareQueue;
Wddm &wddm; Wddm &wddm;
WddmResidencyController residencyController; WddmResidencyController residencyController;
}; };

View File

@ -19,7 +19,8 @@ bool WddmInterface20::createHwQueue(OsContextWin &osContext) {
} }
void WddmInterface20::destroyHwQueue(D3DKMT_HANDLE hwQueue) {} void WddmInterface20::destroyHwQueue(D3DKMT_HANDLE hwQueue) {}
bool WddmInterface::createMonitoredFence(WddmResidencyController &residencyController) { bool WddmInterface20::createMonitoredFence(OsContextWin &osContext) {
auto &residencyController = osContext.getResidencyController();
NTSTATUS Status; NTSTATUS Status;
D3DKMT_CREATESYNCHRONIZATIONOBJECT2 CreateSynchronizationObject = {0}; D3DKMT_CREATESYNCHRONIZATIONOBJECT2 CreateSynchronizationObject = {0};
CreateSynchronizationObject.hDevice = wddm.getDevice(); CreateSynchronizationObject.hDevice = wddm.getDevice();
@ -80,11 +81,21 @@ bool WddmInterface23::createHwQueue(OsContextWin &osContext) {
auto status = wddm.getGdi()->createHwQueue(&createHwQueue); auto status = wddm.getGdi()->createHwQueue(&createHwQueue);
UNRECOVERABLE_IF(status != STATUS_SUCCESS); UNRECOVERABLE_IF(status != STATUS_SUCCESS);
osContext.setHwQueue(createHwQueue.hHwQueue); osContext.setHwQueue({createHwQueue.hHwQueue, createHwQueue.hHwQueueProgressFence, createHwQueue.HwQueueProgressFenceCPUVirtualAddress,
createHwQueue.HwQueueProgressFenceGPUVirtualAddress});
return status == STATUS_SUCCESS; return status == STATUS_SUCCESS;
} }
bool WddmInterface23::createMonitoredFence(OsContextWin &osContext) {
auto &residencyController = osContext.getResidencyController();
auto hwQueue = osContext.getHwQueue();
residencyController.resetMonitoredFenceParams(hwQueue.progressFenceHandle,
reinterpret_cast<uint64_t *>(hwQueue.progressFenceCpuVA),
hwQueue.progressFenceGpuVA);
return true;
}
void WddmInterface23::destroyHwQueue(D3DKMT_HANDLE hwQueue) { void WddmInterface23::destroyHwQueue(D3DKMT_HANDLE hwQueue) {
if (hwQueue) { if (hwQueue) {
D3DKMT_DESTROYHWQUEUE destroyHwQueue = {}; D3DKMT_DESTROYHWQUEUE destroyHwQueue = {};
@ -103,15 +114,11 @@ bool WddmInterface23::submit(uint64_t commandBuffer, size_t size, void *commandH
auto monitoredFence = osContext.getResidencyController().getMonitoredFence(); auto monitoredFence = osContext.getResidencyController().getMonitoredFence();
D3DKMT_SUBMITCOMMANDTOHWQUEUE submitCommand = {}; D3DKMT_SUBMITCOMMANDTOHWQUEUE submitCommand = {};
submitCommand.hHwQueue = osContext.getHwQueue(); submitCommand.hHwQueue = osContext.getHwQueue().handle;
submitCommand.HwQueueProgressFenceId = monitoredFence.fenceHandle; submitCommand.HwQueueProgressFenceId = monitoredFence.currentFenceValue;
submitCommand.CommandBuffer = commandBuffer; submitCommand.CommandBuffer = commandBuffer;
submitCommand.CommandLength = static_cast<UINT>(size); submitCommand.CommandLength = static_cast<UINT>(size);
COMMAND_BUFFER_HEADER *pHeader = reinterpret_cast<COMMAND_BUFFER_HEADER *>(commandHeader);
pHeader->MonitorFenceVA = monitoredFence.gpuAddress;
pHeader->MonitorFenceValue = monitoredFence.currentFenceValue;
submitCommand.pPrivateDriverData = commandHeader; submitCommand.pPrivateDriverData = commandHeader;
submitCommand.PrivateDriverDataSize = MemoryConstants::pageSize; submitCommand.PrivateDriverDataSize = MemoryConstants::pageSize;

View File

@ -27,7 +27,7 @@ class WddmInterface {
WddmInterface() = delete; WddmInterface() = delete;
virtual bool createHwQueue(OsContextWin &osContext) = 0; virtual bool createHwQueue(OsContextWin &osContext) = 0;
virtual void destroyHwQueue(D3DKMT_HANDLE hwQueue) = 0; virtual void destroyHwQueue(D3DKMT_HANDLE hwQueue) = 0;
bool createMonitoredFence(WddmResidencyController &residencyController); virtual bool createMonitoredFence(OsContextWin &osContext) = 0;
virtual const bool hwQueuesSupported() = 0; virtual const bool hwQueuesSupported() = 0;
virtual bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, OsContextWin &osContext) = 0; virtual bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, OsContextWin &osContext) = 0;
Wddm &wddm; Wddm &wddm;
@ -38,6 +38,7 @@ class WddmInterface20 : public WddmInterface {
using WddmInterface::WddmInterface; using WddmInterface::WddmInterface;
bool createHwQueue(OsContextWin &osContext) override; bool createHwQueue(OsContextWin &osContext) override;
void destroyHwQueue(D3DKMT_HANDLE hwQueue) override; void destroyHwQueue(D3DKMT_HANDLE hwQueue) override;
bool createMonitoredFence(OsContextWin &osContext) override;
const bool hwQueuesSupported() override; const bool hwQueuesSupported() override;
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, OsContextWin &osContext) override; bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, OsContextWin &osContext) override;
}; };
@ -47,6 +48,7 @@ class WddmInterface23 : public WddmInterface {
using WddmInterface::WddmInterface; using WddmInterface::WddmInterface;
bool createHwQueue(OsContextWin &osContext) override; bool createHwQueue(OsContextWin &osContext) override;
void destroyHwQueue(D3DKMT_HANDLE hwQueue) override; void destroyHwQueue(D3DKMT_HANDLE hwQueue) override;
bool createMonitoredFence(OsContextWin &osContext) override;
const bool hwQueuesSupported() override; const bool hwQueuesSupported() override;
bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, OsContextWin &osContext) override; bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, OsContextWin &osContext) override;
}; };

View File

@ -649,7 +649,7 @@ TEST_F(Wddm20Tests, createMonitoredFenceIsInitializedWithFenceValueZeroAndCurren
gdi->getCreateSynchronizationObject2Arg().Info.MonitoredFence.InitialFenceValue = 300; gdi->getCreateSynchronizationObject2Arg().Info.MonitoredFence.InitialFenceValue = 300;
wddm->wddmInterface->createMonitoredFence(osContext->getResidencyController()); wddm->wddmInterface->createMonitoredFence(*osContext);
EXPECT_EQ(0u, gdi->getCreateSynchronizationObject2Arg().Info.MonitoredFence.InitialFenceValue); EXPECT_EQ(0u, gdi->getCreateSynchronizationObject2Arg().Info.MonitoredFence.InitialFenceValue);
EXPECT_EQ(1u, osContext->getResidencyController().getMonitoredFence().currentFenceValue); EXPECT_EQ(1u, osContext->getResidencyController().getMonitoredFence().currentFenceValue);

View File

@ -86,19 +86,19 @@ TEST_F(Wddm23Tests, givenPreemptionModeWhenCreateHwQueueCalledThenSetGpuTimeoutI
TEST_F(Wddm23Tests, whenDestroyHwQueueCalledThenPassExistingHandle) { TEST_F(Wddm23Tests, whenDestroyHwQueueCalledThenPassExistingHandle) {
D3DKMT_HANDLE hwQueue = 123; D3DKMT_HANDLE hwQueue = 123;
osContext->setHwQueue(hwQueue); osContext->setHwQueue({hwQueue, 0, nullptr, 0});
wddmMockInterface->destroyHwQueue(osContext->getHwQueue()); wddmMockInterface->destroyHwQueue(osContext->getHwQueue().handle);
EXPECT_EQ(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue); EXPECT_EQ(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue);
hwQueue = 0; hwQueue = 0;
osContext->setHwQueue(hwQueue); osContext->setHwQueue({hwQueue, 0, nullptr, 0});
wddmMockInterface->destroyHwQueue(osContext->getHwQueue()); wddmMockInterface->destroyHwQueue(osContext->getHwQueue().handle);
EXPECT_NE(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue); // gdi not called when 0 EXPECT_NE(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue); // gdi not called when 0
} }
TEST_F(Wddm23Tests, whenObjectIsDestructedThenDestroyHwQueue) { TEST_F(Wddm23Tests, whenObjectIsDestructedThenDestroyHwQueue) {
D3DKMT_HANDLE hwQueue = 123; D3DKMT_HANDLE hwQueue = 123;
osContext->setHwQueue(hwQueue); osContext->setHwQueue({hwQueue, 0, nullptr, 0});
osContext.reset(); osContext.reset();
EXPECT_EQ(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue); EXPECT_EQ(hwQueue, getDestroyHwQueueDataFcn()->hHwQueue);
} }
@ -116,24 +116,25 @@ TEST_F(Wddm23Tests, givenCmdBufferWhenSubmitCalledThenSetAllRequiredFiledsAndUpd
EXPECT_EQ(cmdBufferAddress, getSubmitCommandToHwQueueDataFcn()->CommandBuffer); EXPECT_EQ(cmdBufferAddress, getSubmitCommandToHwQueueDataFcn()->CommandBuffer);
EXPECT_EQ(static_cast<UINT>(cmdSize), getSubmitCommandToHwQueueDataFcn()->CommandLength); EXPECT_EQ(static_cast<UINT>(cmdSize), getSubmitCommandToHwQueueDataFcn()->CommandLength);
EXPECT_EQ(hwQueue, getSubmitCommandToHwQueueDataFcn()->hHwQueue); EXPECT_EQ(hwQueue.handle, getSubmitCommandToHwQueueDataFcn()->hHwQueue);
EXPECT_EQ(osContext->getResidencyController().getMonitoredFence().fenceHandle, getSubmitCommandToHwQueueDataFcn()->HwQueueProgressFenceId); EXPECT_EQ(osContext->getResidencyController().getMonitoredFence().lastSubmittedFence, getSubmitCommandToHwQueueDataFcn()->HwQueueProgressFenceId);
EXPECT_EQ(&cmdBufferHeader, getSubmitCommandToHwQueueDataFcn()->pPrivateDriverData); EXPECT_EQ(&cmdBufferHeader, getSubmitCommandToHwQueueDataFcn()->pPrivateDriverData);
EXPECT_EQ(static_cast<UINT>(MemoryConstants::pageSize), getSubmitCommandToHwQueueDataFcn()->PrivateDriverDataSize); EXPECT_EQ(static_cast<UINT>(MemoryConstants::pageSize), getSubmitCommandToHwQueueDataFcn()->PrivateDriverDataSize);
EXPECT_EQ(osContext->getResidencyController().getMonitoredFence().gpuAddress, cmdBufferHeader.MonitorFenceVA); EXPECT_EQ(0u, cmdBufferHeader.MonitorFenceVA);
EXPECT_EQ(osContext->getResidencyController().getMonitoredFence().lastSubmittedFence, cmdBufferHeader.MonitorFenceValue); EXPECT_EQ(0u, cmdBufferHeader.MonitorFenceValue);
EXPECT_EQ(2u, osContext->getResidencyController().getMonitoredFence().currentFenceValue); EXPECT_EQ(2u, osContext->getResidencyController().getMonitoredFence().currentFenceValue);
EXPECT_EQ(1u, osContext->getResidencyController().getMonitoredFence().lastSubmittedFence); EXPECT_EQ(1u, osContext->getResidencyController().getMonitoredFence().lastSubmittedFence);
} }
TEST_F(Wddm23Tests, whenMonitoredFenceIsCreatedThenSetupAllRequiredFields) { TEST_F(Wddm23Tests, whenMonitoredFenceIsCreatedThenSetupAllRequiredFields) {
wddm->wddmInterface->createMonitoredFence(osContext->getResidencyController()); wddm->wddmInterface->createMonitoredFence(*osContext);
auto hwQueue = osContext->getHwQueue();
EXPECT_NE(nullptr, osContext->getResidencyController().getMonitoredFence().cpuAddress); EXPECT_EQ(hwQueue.progressFenceCpuVA, osContext->getResidencyController().getMonitoredFence().cpuAddress);
EXPECT_EQ(1u, osContext->getResidencyController().getMonitoredFence().currentFenceValue); EXPECT_EQ(1u, osContext->getResidencyController().getMonitoredFence().currentFenceValue);
EXPECT_NE(static_cast<D3DKMT_HANDLE>(0), osContext->getResidencyController().getMonitoredFence().fenceHandle); EXPECT_EQ(hwQueue.progressFenceHandle, osContext->getResidencyController().getMonitoredFence().fenceHandle);
EXPECT_NE(static_cast<D3DGPU_VIRTUAL_ADDRESS>(0), osContext->getResidencyController().getMonitoredFence().gpuAddress); EXPECT_EQ(hwQueue.progressFenceGpuVA, osContext->getResidencyController().getMonitoredFence().gpuAddress);
EXPECT_EQ(0u, osContext->getResidencyController().getMonitoredFence().lastSubmittedFence); EXPECT_EQ(0u, osContext->getResidencyController().getMonitoredFence().lastSubmittedFence);
} }

View File

@ -48,6 +48,18 @@ class MockWddmResidencyController : public WddmResidencyController {
} }
}; };
class MockOsContextWin : public OsContextWin {
public:
MockOsContextWin(Wddm &wddm, uint32_t contextId, DeviceBitfield deviceBitfield,
aub_stream::EngineType engineType, PreemptionMode preemptionMode, bool lowPriority)
: OsContextWin(wddm, contextId, deviceBitfield, engineType, preemptionMode, lowPriority),
mockResidencyController(wddm, contextId) {}
WddmResidencyController &getResidencyController() override { return mockResidencyController; };
MockWddmResidencyController mockResidencyController;
};
struct WddmResidencyControllerTest : ::testing::Test { struct WddmResidencyControllerTest : ::testing::Test {
const uint32_t osContextId = 0u; const uint32_t osContextId = 0u;
@ -55,12 +67,14 @@ struct WddmResidencyControllerTest : ::testing::Test {
wddm = std::unique_ptr<WddmMock>(static_cast<WddmMock *>(Wddm::createWddm())); wddm = std::unique_ptr<WddmMock>(static_cast<WddmMock *>(Wddm::createWddm()));
auto hwInfo = *platformDevices[0]; auto hwInfo = *platformDevices[0];
wddm->init(hwInfo); wddm->init(hwInfo);
residencyController = std::make_unique<MockWddmResidencyController>(*wddm, osContextId); mockOsContextWin = std::make_unique<MockOsContextWin>(*wddm, osContextId, 0, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false);
wddm->getWddmInterface()->createMonitoredFence(*residencyController); wddm->getWddmInterface()->createMonitoredFence(*mockOsContextWin);
residencyController = &mockOsContextWin->mockResidencyController;
} }
std::unique_ptr<WddmMock> wddm; std::unique_ptr<WddmMock> wddm;
std::unique_ptr<MockWddmResidencyController> residencyController; std::unique_ptr<MockOsContextWin> mockOsContextWin;
MockWddmResidencyController *residencyController = nullptr;
}; };
struct WddmResidencyControllerWithGdiTest : ::testing::Test { struct WddmResidencyControllerWithGdiTest : ::testing::Test {
@ -73,13 +87,15 @@ struct WddmResidencyControllerWithGdiTest : ::testing::Test {
auto hwInfo = *platformDevices[0]; auto hwInfo = *platformDevices[0];
wddm->init(hwInfo); wddm->init(hwInfo);
residencyController = std::make_unique<MockWddmResidencyController>(*wddm, osContextId); mockOsContextWin = std::make_unique<MockOsContextWin>(*wddm, osContextId, 0, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false);
wddm->getWddmInterface()->createMonitoredFence(*residencyController); wddm->getWddmInterface()->createMonitoredFence(*mockOsContextWin);
residencyController = &mockOsContextWin->mockResidencyController;
residencyController->registerCallback(); residencyController->registerCallback();
} }
std::unique_ptr<WddmMock> wddm; std::unique_ptr<WddmMock> wddm;
std::unique_ptr<MockWddmResidencyController> residencyController; std::unique_ptr<MockOsContextWin> mockOsContextWin;
MockWddmResidencyController *residencyController = nullptr;
MockGdi *gdi; MockGdi *gdi;
}; };
@ -212,7 +228,7 @@ TEST_F(WddmResidencyControllerWithGdiTest, givenWddmResidencyControllerWhenItIsD
auto trimCallbackAddress = reinterpret_cast<PFND3DKMT_TRIMNOTIFICATIONCALLBACK>(WddmResidencyController::trimCallback); auto trimCallbackAddress = reinterpret_cast<PFND3DKMT_TRIMNOTIFICATIONCALLBACK>(WddmResidencyController::trimCallback);
std::memset(&gdi->getUnregisterTrimNotificationArg(), 0, sizeof(D3DKMT_UNREGISTERTRIMNOTIFICATION)); std::memset(&gdi->getUnregisterTrimNotificationArg(), 0, sizeof(D3DKMT_UNREGISTERTRIMNOTIFICATION));
residencyController.reset(); mockOsContextWin.reset();
EXPECT_EQ(trimCallbackAddress, gdi->getUnregisterTrimNotificationArg().Callback); EXPECT_EQ(trimCallbackAddress, gdi->getUnregisterTrimNotificationArg().Callback);
EXPECT_EQ(trimCallbackHandle, gdi->getUnregisterTrimNotificationArg().Handle); EXPECT_EQ(trimCallbackHandle, gdi->getUnregisterTrimNotificationArg().Handle);