66 */
77
88#include " shared/source/os_interface/linux/drm_buffer_object.h"
9+ #include " shared/source/os_interface/linux/drm_memory_operations_handler_default.h"
10+ #include " shared/source/os_interface/linux/os_context_linux.h"
11+ #include " shared/source/os_interface/linux/os_interface.h"
912#include " shared/test/unit_test/helpers/debug_manager_state_restore.h"
13+ #include " shared/test/unit_test/mocks/mock_device.h"
1014
15+ #include " opencl/test/unit_test/mocks/linux/mock_drm_allocation.h"
1116#include " opencl/test/unit_test/os_interface/linux/device_command_stream_fixture.h"
17+ #include " opencl/test/unit_test/os_interface/linux/drm_mock.h"
1218#include " test.h"
1319
1420#include " drm/i915_drm.h"
@@ -26,8 +32,8 @@ class TestedBufferObject : public BufferObject {
2632 this ->tiling_mode = mode;
2733 }
2834
29- void fillExecObject (drm_i915_gem_exec_object2 &execObject, uint32_t vmHandleId, uint32_t drmContextId) override {
30- BufferObject::fillExecObject (execObject, vmHandleId, drmContextId);
35+ void fillExecObject (drm_i915_gem_exec_object2 &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) override {
36+ BufferObject::fillExecObject (execObject, osContext, vmHandleId, drmContextId);
3137 execObjectPointerFilled = &execObject;
3238 }
3339
@@ -43,10 +49,13 @@ class DrmBufferObjectFixture {
4349 std::unique_ptr<DrmMockCustom> mock;
4450 TestedBufferObject *bo;
4551 drm_i915_gem_exec_object2 execObjectsStorage[256 ];
52+ std::unique_ptr<OsContextLinux> osContext;
4653
4754 void SetUp () {
4855 this ->mock = std::make_unique<DrmMockCustom>();
4956 ASSERT_NE (nullptr , this ->mock );
57+ osContext.reset (new OsContextLinux (*this ->mock , 0u , 1 , aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false , false , false ));
58+ this ->mock ->reset ();
5059 bo = new TestedBufferObject (this ->mock .get ());
5160 ASSERT_NE (nullptr , bo);
5261 }
@@ -56,6 +65,9 @@ class DrmBufferObjectFixture {
5665 if (this ->mock ->ioctl_expected .total >= 0 ) {
5766 EXPECT_EQ (this ->mock ->ioctl_expected .total , this ->mock ->ioctl_cnt .total );
5867 }
68+ mock->reset ();
69+ osContext.reset (nullptr );
70+ mock.reset (nullptr );
5971 }
6072};
6173
@@ -66,7 +78,7 @@ TEST_F(DrmBufferObjectTest, exec) {
6678 mock->ioctl_res = 0 ;
6779
6880 drm_i915_gem_exec_object2 execObjectsStorage = {};
69- auto ret = bo->exec (0 , 0 , 0 , false , 0 , 1 , nullptr , 0u , &execObjectsStorage);
81+ auto ret = bo->exec (0 , 0 , 0 , false , osContext. get (), 0 , 1 , nullptr , 0u , &execObjectsStorage);
7082 EXPECT_EQ (mock->ioctl_res , ret);
7183 EXPECT_EQ (0u , mock->execBuffer .flags );
7284}
@@ -76,7 +88,7 @@ TEST_F(DrmBufferObjectTest, exec_ioctlFailed) {
7688 mock->ioctl_res = -1 ;
7789 mock->errnoValue = EFAULT;
7890 drm_i915_gem_exec_object2 execObjectsStorage = {};
79- EXPECT_EQ (EFAULT, bo->exec (0 , 0 , 0 , false , 0 , 1 , nullptr , 0u , &execObjectsStorage));
91+ EXPECT_EQ (EFAULT, bo->exec (0 , 0 , 0 , false , osContext. get (), 0 , 1 , nullptr , 0u , &execObjectsStorage));
8092}
8193
8294TEST_F (DrmBufferObjectTest, setTiling_success) {
@@ -105,7 +117,7 @@ TEST_F(DrmBufferObjectTest, givenAddressThatWhenSizeIsAddedCrosses32BitBoundaryW
105117 memset (&execObject, 0 , sizeof (execObject));
106118 bo->setAddress (((uint64_t )1u << 32 ) - 0x1000u );
107119 bo->setSize (0x1000 );
108- bo->fillExecObject (execObject, 0 , 1 );
120+ bo->fillExecObject (execObject, osContext. get (), 0 , 1 );
109121 // base address + size > size of 32bit address space
110122 EXPECT_TRUE (execObject.flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS);
111123}
@@ -116,7 +128,7 @@ TEST_F(DrmBufferObjectTest, givenAddressThatWhenSizeIsAddedWithin32BitBoundaryWh
116128 memset (&execObject, 0 , sizeof (execObject));
117129 bo->setAddress (((uint64_t )1u << 32 ) - 0x1000u );
118130 bo->setSize (0xFFF );
119- bo->fillExecObject (execObject, 0 , 1 );
131+ bo->fillExecObject (execObject, osContext. get (), 0 , 1 );
120132 // base address + size < size of 32bit address space
121133 EXPECT_TRUE (execObject.flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS);
122134}
@@ -133,7 +145,7 @@ TEST_F(DrmBufferObjectTest, onPinIoctlFailed) {
133145
134146 bo->setAddress (reinterpret_cast <uint64_t >(buff.get ()));
135147 BufferObject *boArray[1 ] = {boToPin.get ()};
136- auto ret = bo->pin (boArray, 1 , 0 , 1 );
148+ auto ret = bo->pin (boArray, 1 , osContext. get (), 0 , 1 );
137149 EXPECT_EQ (EINVAL, ret);
138150}
139151
@@ -144,7 +156,7 @@ TEST_F(DrmBufferObjectTest, whenPrintExecutionBufferIsSetToTrueThenMessageFoundI
144156 drm_i915_gem_exec_object2 execObjectsStorage = {};
145157
146158 testing::internal::CaptureStdout ();
147- auto ret = bo->exec (0 , 0 , 0 , false , 0 , 1 , nullptr , 0u , &execObjectsStorage);
159+ auto ret = bo->exec (0 , 0 , 0 , false , osContext. get (), 0 , 1 , nullptr , 0u , &execObjectsStorage);
148160 EXPECT_EQ (0 , ret);
149161
150162 std::string output = testing::internal::GetCapturedStdout ();
@@ -170,7 +182,7 @@ TEST(DrmBufferObjectSimpleTest, givenInvalidBoWhenPinIsCalledThenErrorIsReturned
170182 mock->errnoValue = EFAULT;
171183
172184 BufferObject *boArray[1 ] = {boToPin.get ()};
173- auto ret = bo->pin (boArray, 1 , 0 , 1 );
185+ auto ret = bo->pin (boArray, 1 , nullptr , 0 , 1 );
174186 EXPECT_EQ (EFAULT, ret);
175187}
176188
@@ -185,6 +197,8 @@ TEST(DrmBufferObjectSimpleTest, givenArrayOfBosWhenPinnedThenAllBosArePinned) {
185197 std::unique_ptr<uint32_t []> buff (new uint32_t [256 ]);
186198 std::unique_ptr<DrmMockCustom> mock (new DrmMockCustom);
187199 ASSERT_NE (nullptr , mock.get ());
200+ OsContextLinux osContext (*mock, 0u , 1 , aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false , false , false );
201+
188202 std::unique_ptr<TestedBufferObject> bo (new TestedBufferObject (mock.get ()));
189203 ASSERT_NE (nullptr , bo.get ());
190204 mock->ioctl_res = 0 ;
@@ -200,7 +214,7 @@ TEST(DrmBufferObjectSimpleTest, givenArrayOfBosWhenPinnedThenAllBosArePinned) {
200214 BufferObject *array[3 ] = {boToPin.get (), boToPin2.get (), boToPin3.get ()};
201215
202216 bo->setAddress (reinterpret_cast <uint64_t >(buff.get ()));
203- auto ret = bo->pin (array, 3 , 0 , 1 );
217+ auto ret = bo->pin (array, 3 , &osContext, 0 , 1 );
204218 EXPECT_EQ (mock->ioctl_res , ret);
205219
206220 EXPECT_LT (0u , mock->execBuffer .batch_len );
@@ -224,3 +238,51 @@ TEST_F(DrmBufferObjectTest, givenDeleterWhenBufferObjectIsCreatedAndDeletedThenC
224238 mock->ioctl_cnt .reset ();
225239 mock->ioctl_expected .reset ();
226240}
241+
242+ TEST (DrmBufferObject, givenPerContextVmRequiredWhenBoCreatedThenBindInfoIsInitializedToOsContextCount) {
243+ auto device = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr ));
244+ device->getRootDeviceEnvironment ().executionEnvironment .setPerContextMemorySpace ();
245+
246+ DrmMock drm (*(device->getExecutionEnvironment ()->rootDeviceEnvironments [0 ].get ()));
247+ EXPECT_TRUE (drm.isPerContextVMRequired ());
248+ MockBufferObject bo (&drm);
249+
250+ auto osContextCount = device->getExecutionEnvironment ()->memoryManager ->getRegisteredEnginesCount ();
251+ EXPECT_EQ (osContextCount, bo.bindInfo .size ());
252+
253+ for (auto &iter : bo.bindInfo ) {
254+ for (uint32_t i = 0 ; i < EngineLimits::maxHandleCount; i++) {
255+ EXPECT_FALSE (iter[i]);
256+ }
257+ }
258+ }
259+
260+ TEST (DrmBufferObject, givenPerContextVmRequiredWhenBoBoundAndUnboundThenCorrectBindInfoIsUpdated) {
261+ auto executionEnvironment = new ExecutionEnvironment;
262+ executionEnvironment->setPerContextMemorySpace ();
263+ executionEnvironment->prepareRootDeviceEnvironments (1 );
264+ executionEnvironment->rootDeviceEnvironments [0 ]->setHwInfo (defaultHwInfo.get ());
265+ executionEnvironment->rootDeviceEnvironments [0 ]->osInterface = std::make_unique<OSInterface>();
266+ executionEnvironment->rootDeviceEnvironments [0 ]->memoryOperationsInterface = DrmMemoryOperationsHandler::create ();
267+
268+ DrmMockNonFailing *drm = new DrmMockNonFailing (*executionEnvironment->rootDeviceEnvironments [0 ]);
269+ EXPECT_TRUE (drm->isPerContextVMRequired ());
270+
271+ executionEnvironment->rootDeviceEnvironments [0 ]->osInterface ->get ()->setDrm (drm);
272+
273+ std::unique_ptr<Device> device (MockDevice::createWithExecutionEnvironment<MockDevice>(defaultHwInfo.get (), executionEnvironment, 0 ));
274+
275+ MockBufferObject bo (drm);
276+
277+ auto osContextCount = device->getExecutionEnvironment ()->memoryManager ->getRegisteredEnginesCount ();
278+ EXPECT_EQ (osContextCount, bo.bindInfo .size ());
279+
280+ auto contextId = device->getExecutionEnvironment ()->memoryManager ->getRegisteredEnginesCount () / 2 ;
281+ auto osContext = device->getExecutionEnvironment ()->memoryManager ->getRegisteredEngines ()[contextId].osContext ;
282+
283+ bo.bind (osContext, 0 );
284+ EXPECT_TRUE (bo.bindInfo [contextId][0 ]);
285+
286+ bo.unbind (osContext, 0 );
287+ EXPECT_FALSE (bo.bindInfo [contextId][0 ]);
288+ }
0 commit comments