66 */
77
88#include " shared/source/execution_environment/root_device_environment.h"
9- #include " shared/source/os_interface/external_semaphore.h"
109#include " shared/source/os_interface/os_interface.h"
10+ #include " shared/source/os_interface/windows/external_semaphore_windows.h"
1111#include " shared/test/common/mocks/mock_builtins.h"
1212#include " shared/test/common/mocks/mock_device.h"
1313#include " shared/test/common/os_interface/windows/wddm_fixture.h"
@@ -19,18 +19,18 @@ namespace NEO {
1919
2020using WddmExternalSemaphoreTest = WddmFixture;
2121
22- TEST_F (WddmExternalSemaphoreTest, givenOpaqueFdSemaphoreWhenCreateExternalSemaphoreIsCalledThenNullptrIsReturned) {
23- auto externalSemaphore = ExternalSemaphore::create (osInterface, ExternalSemaphore::Type::OpaqueFd, nullptr , 0u , nullptr );
24- EXPECT_EQ (externalSemaphore, nullptr );
25- }
26-
2722TEST_F (WddmExternalSemaphoreTest, givenNullOsInterfaceWhenCreateExternalSemaphoreIsCalledThenNullptrIsReturned) {
2823 HANDLE extSemaphoreHandle = 0 ;
2924
3025 auto externalSemaphore = ExternalSemaphore::create (nullptr , ExternalSemaphore::Type::D3d12Fence, extSemaphoreHandle, 0u , nullptr );
3126 EXPECT_EQ (externalSemaphore, nullptr );
3227}
3328
29+ TEST_F (WddmExternalSemaphoreTest, givenOpaqueFdSemaphoreWhenCreateExternalSemaphoreIsCalledThenNullptrIsReturned) {
30+ auto externalSemaphore = ExternalSemaphore::create (osInterface, ExternalSemaphore::Type::OpaqueFd, nullptr , 0u , nullptr );
31+ EXPECT_EQ (externalSemaphore, nullptr );
32+ }
33+
3434TEST_F (WddmExternalSemaphoreTest, givenValidD3d12FenceSemaphoreWhenCreateExternalSemaphoreIsCalledThenSemaphoreIsSuccessfullyReturned) {
3535 HANDLE extSemaphoreHandle = 0 ;
3636
@@ -53,24 +53,147 @@ TEST_F(WddmExternalSemaphoreTest, givenValidTimelineSemaphoreWin32WhenCreateExte
5353 EXPECT_NE (externalSemaphore, nullptr );
5454}
5555
56- class MockFailGdi : public MockGdi {
56+ class MockWindowsExternalSemaphore : public ExternalSemaphoreWindows {
5757 public:
58- MockFailGdi () : MockGdi() {
59- openSyncObjectNtHandleFromName = mockD3DKMTOpenSyncObjectNtHandleFromName;
60- openSyncObjectFromNtHandle2 = mockD3DKMTOpenSyncObjectFromNtHandle2;
58+ using ExternalSemaphoreWindows::enqueueSignal;
59+ using ExternalSemaphoreWindows::enqueueWait;
60+
61+ MockWindowsExternalSemaphore (OSInterface *osInterface, ExternalSemaphore::Type type, uint64_t *signalVal) {
62+ this ->osInterface = osInterface;
63+ this ->type = type;
64+ this ->state = ExternalSemaphore::SemaphoreState::Initial;
65+ this ->syncHandle = 1 ;
66+ this ->pCpuAddress = nullptr ;
67+ this ->pLastSignaledValue = signalVal;
6168 }
6269
63- static NTSTATUS __stdcall mockD3DKMTOpenSyncObjectNtHandleFromName (IN OUT D3DKMT_OPENSYNCOBJECTNTHANDLEFROMNAME *) {
64- return STATUS_UNSUCCESSFUL ;
70+ uint64_t lastSignaledValue () const {
71+ return pLastSignaledValue ? *pLastSignaledValue : 0u ;
6572 }
73+ };
6674
67- static NTSTATUS __stdcall mockD3DKMTOpenSyncObjectFromNtHandle2 (IN OUT D3DKMT_OPENSYNCOBJECTFROMNTHANDLE2 *) {
68- return STATUS_UNSUCCESSFUL;
75+ class MockSyncGdi : public MockGdi {
76+ public:
77+ MockSyncGdi () : MockGdi() {
78+ openSyncObjectNtHandleFromName = mockOpenSyncObjectNtHandleFromName;
79+ openSyncObjectFromNtHandle2 = mockOpenSyncObjectFromNtHandle2;
80+ waitForSynchronizationObjectFromCpu = mockWaitForSynchronizationObjectFromCpu;
81+ signalSynchronizationObjectFromCpu = mockSignalSynchronizationObjectFromCpu;
82+ }
83+
84+ static NTSTATUS __stdcall mockOpenSyncObjectNtHandleFromName (IN OUT D3DKMT_OPENSYNCOBJECTNTHANDLEFROMNAME *) {
85+ return (failOpenSyncObjectNtHandleName ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS);
86+ }
87+
88+ static NTSTATUS __stdcall mockOpenSyncObjectFromNtHandle2 (IN OUT D3DKMT_OPENSYNCOBJECTFROMNTHANDLE2 *) {
89+ return (failOpenSyncObjectFromNtHandle ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS);
6990 }
91+
92+ static NTSTATUS __stdcall mockWaitForSynchronizationObjectFromCpu (IN CONST D3DKMT_WAITFORSYNCHRONIZATIONOBJECTFROMCPU *) {
93+ return (failWaitForSynchObjectFromCpu ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS);
94+ }
95+
96+ static NTSTATUS __stdcall mockSignalSynchronizationObjectFromCpu (IN CONST D3DKMT_SIGNALSYNCHRONIZATIONOBJECTFROMCPU *) {
97+ return (failSignalSynchObjectFromCpu ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS);
98+ }
99+
100+ static bool failOpenSyncObjectNtHandleName;
101+ static bool failOpenSyncObjectFromNtHandle;
102+ static bool failWaitForSynchObjectFromCpu;
103+ static bool failSignalSynchObjectFromCpu;
70104};
71105
106+ bool MockSyncGdi::failOpenSyncObjectNtHandleName = true ;
107+ bool MockSyncGdi::failOpenSyncObjectFromNtHandle = true ;
108+ bool MockSyncGdi::failWaitForSynchObjectFromCpu = false ;
109+ bool MockSyncGdi::failSignalSynchObjectFromCpu = false ;
110+
111+ TEST_F (WddmExternalSemaphoreTest, givenGdiWaitForSyncObjFailsWhenEnqueueSignalIsCalledWithOpaqueWin32ThenFalseIsReturnedAndSignalValueIsNotUpdated) {
112+ auto mockGdi = new MockSyncGdi ();
113+ static_cast <OsEnvironmentWin *>(executionEnvironment->osEnvironment .get ())->gdi .reset (mockGdi);
114+
115+ uint64_t signalVal = 0u ;
116+ auto extSem = new MockWindowsExternalSemaphore{osInterface, ExternalSemaphore::Type::OpaqueWin32, &signalVal};
117+ EXPECT_NE (extSem, nullptr );
118+ EXPECT_EQ (extSem->getState (), ExternalSemaphore::SemaphoreState::Initial);
119+ EXPECT_EQ (extSem->lastSignaledValue (), 0u );
120+ EXPECT_EQ (signalVal, 0u );
121+
122+ MockSyncGdi::failSignalSynchObjectFromCpu = true ;
123+ auto result = extSem->enqueueSignal (&signalVal);
124+ MockSyncGdi::failSignalSynchObjectFromCpu = false ;
125+ EXPECT_EQ (result, false );
126+ EXPECT_EQ (extSem->getState (), ExternalSemaphore::SemaphoreState::Initial);
127+ EXPECT_EQ (extSem->lastSignaledValue (), signalVal);
128+ EXPECT_EQ (signalVal, 0ull );
129+
130+ delete extSem;
131+ }
132+
133+ TEST_F (WddmExternalSemaphoreTest, givenGdiWaitForSyncObjFailsWhenEnqueueWaitIsCalledWithOpaqueWin32ThenFalseIsReturned) {
134+ auto mockGdi = new MockSyncGdi ();
135+ static_cast <OsEnvironmentWin *>(executionEnvironment->osEnvironment .get ())->gdi .reset (mockGdi);
136+
137+ uint64_t signalVal = 0u ;
138+ auto extSem = new MockWindowsExternalSemaphore{osInterface, ExternalSemaphore::Type::OpaqueWin32, &signalVal};
139+ EXPECT_NE (extSem, nullptr );
140+ EXPECT_EQ (extSem->getState (), ExternalSemaphore::SemaphoreState::Initial);
141+ EXPECT_EQ (extSem->lastSignaledValue (), 0u );
142+ EXPECT_EQ (signalVal, 0ull );
143+
144+ MockSyncGdi::failWaitForSynchObjectFromCpu = true ;
145+ auto result = extSem->enqueueWait (&signalVal);
146+ MockSyncGdi::failWaitForSynchObjectFromCpu = false ;
147+ EXPECT_EQ (result, false );
148+ EXPECT_EQ (extSem->getState (), ExternalSemaphore::SemaphoreState::Initial);
149+ EXPECT_EQ (extSem->lastSignaledValue (), signalVal);
150+ EXPECT_EQ (signalVal, 0ull );
151+
152+ delete extSem;
153+ }
154+
155+ TEST_F (WddmExternalSemaphoreTest, givenGdiWaitForSyncObjSucceedsWhenEnqueueSignalIsCalledWithOpaqueWin32ThenTrueIsReturnedAndSignalValueIsUpdated) {
156+ auto mockGdi = new MockSyncGdi ();
157+ static_cast <OsEnvironmentWin *>(executionEnvironment->osEnvironment .get ())->gdi .reset (mockGdi);
158+
159+ uint64_t signalVal = 0u ;
160+ auto extSem = new MockWindowsExternalSemaphore{osInterface, ExternalSemaphore::Type::OpaqueWin32, &signalVal};
161+ EXPECT_NE (extSem, nullptr );
162+ EXPECT_EQ (extSem->getState (), ExternalSemaphore::SemaphoreState::Initial);
163+ EXPECT_EQ (extSem->lastSignaledValue (), 0u );
164+ EXPECT_EQ (signalVal, 0ull );
165+
166+ auto result = extSem->enqueueSignal (&signalVal);
167+ EXPECT_EQ (result, true );
168+ EXPECT_EQ (extSem->getState (), ExternalSemaphore::SemaphoreState::Signaled);
169+ EXPECT_EQ (extSem->lastSignaledValue (), signalVal);
170+ EXPECT_EQ (signalVal, 2ull );
171+
172+ delete extSem;
173+ }
174+
175+ TEST_F (WddmExternalSemaphoreTest, givenGdiWaitForSyncObjSucceedsWhenEnqueueWaitIsCalledWithOpaqueWin32ThenTrueIsReturned) {
176+ auto mockGdi = new MockSyncGdi ();
177+ static_cast <OsEnvironmentWin *>(executionEnvironment->osEnvironment .get ())->gdi .reset (mockGdi);
178+
179+ uint64_t signalVal = 0u ;
180+ auto extSem = new MockWindowsExternalSemaphore{osInterface, ExternalSemaphore::Type::OpaqueWin32, &signalVal};
181+ EXPECT_NE (extSem, nullptr );
182+ EXPECT_EQ (extSem->getState (), ExternalSemaphore::SemaphoreState::Initial);
183+ EXPECT_EQ (extSem->lastSignaledValue (), 0u );
184+ EXPECT_EQ (signalVal, 0ull );
185+
186+ auto result = extSem->enqueueWait (&signalVal);
187+ EXPECT_EQ (result, true );
188+ EXPECT_EQ (extSem->getState (), ExternalSemaphore::SemaphoreState::Signaled);
189+ EXPECT_EQ (extSem->lastSignaledValue (), signalVal);
190+ EXPECT_EQ (signalVal, 0ull );
191+
192+ delete extSem;
193+ }
194+
72195TEST_F (WddmExternalSemaphoreTest, givenTimelineSemaphoreWin32FailsToOpenSyncObjectFromNameThenNullptrIsReturned) {
73- auto mockGdi = new MockFailGdi ();
196+ auto mockGdi = new MockSyncGdi ();
74197 static_cast <OsEnvironmentWin *>(executionEnvironment->osEnvironment .get ())->gdi .reset (mockGdi);
75198 HANDLE extSemaphoreHandle = 0 ;
76199 const char *extSemName = " timeline_semaphore_name" ;
@@ -80,7 +203,7 @@ TEST_F(WddmExternalSemaphoreTest, givenTimelineSemaphoreWin32FailsToOpenSyncObje
80203}
81204
82205TEST_F (WddmExternalSemaphoreTest, givenTimelineSemaphoreWin32FailsToOpenSyncObjectFromNtHandleThenNullptrIsReturned) {
83- auto mockGdi = new MockFailGdi ();
206+ auto mockGdi = new MockSyncGdi ();
84207 static_cast <OsEnvironmentWin *>(executionEnvironment->osEnvironment .get ())->gdi .reset (mockGdi);
85208 HANDLE extSemaphoreHandle = 0 ;
86209
0 commit comments