diff --git a/level_zero/api/driver_experimental/public/zex_context.cpp b/level_zero/api/driver_experimental/public/zex_context.cpp index 6991369c81..bafdc12d1f 100644 --- a/level_zero/api/driver_experimental/public/zex_context.cpp +++ b/level_zero/api/driver_experimental/public/zex_context.cpp @@ -7,13 +7,38 @@ #include "level_zero/api/driver_experimental/public/zex_context.h" +#include "shared/source/device/device.h" + +#include "level_zero/core/source/device/device.h" + namespace L0 { ZE_APIEXPORT ze_result_t ZE_APICALL zeIntelMediaCommunicationCreate(ze_context_handle_t hContext, ze_device_handle_t hDevice, ze_intel_media_communication_desc_t *desc, ze_intel_media_doorbell_handle_desc_t *phDoorbell) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + auto device = Device::fromHandle(hDevice); + + if (!device || !desc || !phDoorbell) { + return ZE_RESULT_ERROR_INVALID_ARGUMENT; + } + + if (device->getNEODevice()->getMemoryManager()->createMediaContext(device->getRootDeviceIndex(), desc->controlSharedMemoryBuffer, desc->controlSharedMemoryBufferSize, + desc->controlBatchBuffer, desc->controlBatchBufferSize, phDoorbell->doorbell)) { + return ZE_RESULT_SUCCESS; + } + + return ZE_RESULT_ERROR_UNKNOWN; } ZE_APIEXPORT ze_result_t ZE_APICALL zeIntelMediaCommunicationDestroy(ze_context_handle_t hContext, ze_device_handle_t hDevice, ze_intel_media_doorbell_handle_desc_t *phDoorbell) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + auto device = Device::fromHandle(hDevice); + + if (!device || !phDoorbell) { + return ZE_RESULT_ERROR_INVALID_ARGUMENT; + } + + if (device->getNEODevice()->getMemoryManager()->releaseMediaContext(device->getRootDeviceIndex(), phDoorbell->doorbell)) { + return ZE_RESULT_SUCCESS; + } + + return ZE_RESULT_ERROR_UNKNOWN; } } // namespace L0 diff --git a/shared/source/memory_manager/memory_manager.h b/shared/source/memory_manager/memory_manager.h index f96182f6a9..ff29fce9a0 100644 --- a/shared/source/memory_manager/memory_manager.h +++ b/shared/source/memory_manager/memory_manager.h @@ -303,6 +303,9 @@ class MemoryManager { virtual bool allocateInterrupt(uint32_t &outHandle, uint32_t rootDeviceIndex) { return false; } virtual bool releaseInterrupt(uint32_t outHandle, uint32_t rootDeviceIndex) { return false; } + virtual bool createMediaContext(uint32_t rootDeviceIndex, void *controlSharedMemoryBuffer, uint32_t controlSharedMemoryBufferSize, void *controlBatchBuffer, uint32_t controlBatchBufferSize, uint64_t &outDoorbell) { return false; } + virtual bool releaseMediaContext(uint32_t rootDeviceIndex, uint64_t doorbellHandle) { return false; } + protected: bool getAllocationData(AllocationData &allocationData, const AllocationProperties &properties, const void *hostPtr, const StorageInfo &storageInfo); static void overrideAllocationData(AllocationData &allocationData, const AllocationProperties &properties); diff --git a/shared/source/os_interface/linux/drm_memory_manager.cpp b/shared/source/os_interface/linux/drm_memory_manager.cpp index 1a00d22505..1584ccbc0f 100644 --- a/shared/source/os_interface/linux/drm_memory_manager.cpp +++ b/shared/source/os_interface/linux/drm_memory_manager.cpp @@ -2732,4 +2732,12 @@ bool DrmMemoryManager::releaseInterrupt(uint32_t outHandle, uint32_t rootDeviceI return getDrm(rootDeviceIndex).getIoctlHelper()->releaseInterrupt(outHandle); } +bool DrmMemoryManager::createMediaContext(uint32_t rootDeviceIndex, void *controlSharedMemoryBuffer, uint32_t controlSharedMemoryBufferSize, void *controlBatchBuffer, uint32_t controlBatchBufferSize, uint64_t &outDoorbell) { + return getDrm(rootDeviceIndex).getIoctlHelper()->createMediaContext(controlSharedMemoryBuffer, controlSharedMemoryBufferSize, controlBatchBuffer, controlBatchBufferSize, outDoorbell); +} + +bool DrmMemoryManager::releaseMediaContext(uint32_t rootDeviceIndex, uint64_t doorbellHandle) { + return getDrm(rootDeviceIndex).getIoctlHelper()->releaseMediaContext(doorbellHandle); +} + } // namespace NEO diff --git a/shared/source/os_interface/linux/drm_memory_manager.h b/shared/source/os_interface/linux/drm_memory_manager.h index 9a2d9e9ab4..eb8b70f1cd 100644 --- a/shared/source/os_interface/linux/drm_memory_manager.h +++ b/shared/source/os_interface/linux/drm_memory_manager.h @@ -101,6 +101,9 @@ class DrmMemoryManager : public MemoryManager { bool allocateInterrupt(uint32_t &outHandle, uint32_t rootDeviceIndex) override; bool releaseInterrupt(uint32_t outHandle, uint32_t rootDeviceIndex) override; + bool createMediaContext(uint32_t rootDeviceIndex, void *controlSharedMemoryBuffer, uint32_t controlSharedMemoryBufferSize, void *controlBatchBuffer, uint32_t controlBatchBufferSize, uint64_t &outDoorbell) override; + bool releaseMediaContext(uint32_t rootDeviceIndex, uint64_t doorbellHandle) override; + protected: void registerSharedBoHandleAllocation(DrmAllocation *drmAllocation); BufferObjectHandleWrapper tryToGetBoHandleWrapperWithSharedOwnership(int boHandle); diff --git a/shared/source/os_interface/linux/engine_info.cpp b/shared/source/os_interface/linux/engine_info.cpp index ecb6a5d4e1..6902b052ee 100644 --- a/shared/source/os_interface/linux/engine_info.cpp +++ b/shared/source/os_interface/linux/engine_info.cpp @@ -200,7 +200,7 @@ void EngineInfo::getListOfEnginesOnATile(uint32_t tile, std::vector EngineInfo::getEngineTileInfo() { +const std::multimap &EngineInfo::getEngineTileInfo() const { return tileToEngineMap; } diff --git a/shared/source/os_interface/linux/engine_info.h b/shared/source/os_interface/linux/engine_info.h index c0ed34a7cd..166e82d028 100644 --- a/shared/source/os_interface/linux/engine_info.h +++ b/shared/source/os_interface/linux/engine_info.h @@ -34,7 +34,7 @@ struct EngineInfo { const EngineClassInstance *getEngineInstance(uint32_t tile, aub_stream::EngineType engineType) const; uint32_t getEngineTileIndex(const EngineClassInstance &engine); void getListOfEnginesOnATile(uint32_t tile, std::vector &listOfEngines); - std::multimap getEngineTileInfo(); + const std::multimap &getEngineTileInfo() const; bool hasEngines(); const std::vector &getEngineInfos() const; diff --git a/shared/source/os_interface/linux/ioctl_helper.h b/shared/source/os_interface/linux/ioctl_helper.h index e7242bd3a2..8d13d7145a 100644 --- a/shared/source/os_interface/linux/ioctl_helper.h +++ b/shared/source/os_interface/linux/ioctl_helper.h @@ -155,6 +155,8 @@ class IoctlHelper { virtual bool checkIfIoctlReinvokeRequired(int error, DrmIoctl ioctlRequest) const; virtual int createDrmContext(Drm &drm, OsContextLinux &osContext, uint32_t drmVmId, uint32_t deviceIndex, bool allocateInterrupt) = 0; + virtual bool createMediaContext(void *controlSharedMemoryBuffer, uint32_t controlSharedMemoryBufferSize, void *controlBatchBuffer, uint32_t controlBatchBufferSize, uint64_t &outDoorbell) { return false; } + virtual bool releaseMediaContext(uint64_t doorbellHandle) { return false; } virtual void fillExecObject(ExecObject &execObject, uint32_t handle, uint64_t gpuAddress, uint32_t drmContextId, bool bindInfo, bool isMarkedForCapture) = 0; virtual void logExecObject(const ExecObject &execObject, std::stringstream &logger, size_t size) = 0; diff --git a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp index c2618e075b..2bc200cda7 100644 --- a/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp +++ b/shared/source/os_interface/linux/xe/ioctl_helper_xe.cpp @@ -994,7 +994,7 @@ int IoctlHelperXe::ioctl(DrmIoctl request, void *arg) { struct drm_xe_exec_queue_destroy destroy = {}; destroy.exec_queue_id = d->contextId; ret = IoctlHelper::ioctl(request, &destroy); - xeLog(" -> IoctlHelperXe::ioctl GemContextDestroryExt ctx=0x%x r=%d\n", + xeLog(" -> IoctlHelperXe::ioctl GemContextDestrory ctx=0x%x r=%d\n", d->contextId, ret); } break; case DrmIoctl::gemContextGetparam: { diff --git a/shared/test/common/mocks/linux/mock_ioctl_helper.h b/shared/test/common/mocks/linux/mock_ioctl_helper.h index ab71999313..8662025352 100644 --- a/shared/test/common/mocks/linux/mock_ioctl_helper.h +++ b/shared/test/common/mocks/linux/mock_ioctl_helper.h @@ -67,6 +67,15 @@ class MockIoctlHelper : public IoctlHelperPrelim20 { return IoctlHelperPrelim20::releaseInterrupt(handle); } + bool createMediaContext(void *controlSharedMemoryBuffer, uint32_t controlSharedMemoryBufferSize, void *controlBatchBuffer, uint32_t controlBatchBufferSize, uint64_t &outDoorbell) override { + createMediaContextCalled++; + return IoctlHelperPrelim20::createMediaContext(controlSharedMemoryBuffer, controlSharedMemoryBufferSize, controlBatchBuffer, controlBatchBufferSize, outDoorbell); + } + bool releaseMediaContext(uint64_t doorbellHandle) override { + releaseMediaContextCalled++; + return IoctlHelperPrelim20::releaseMediaContext(doorbellHandle); + } + std::unique_ptr createMemoryInfo() override { std::vector regionInfo(3); @@ -91,5 +100,7 @@ class MockIoctlHelper : public IoctlHelperPrelim20 { uint32_t allocateInterruptCalled = 0; uint32_t releaseInterruptCalled = 0; uint32_t latestReleaseInterruptHandle = InterruptId::notUsed; + uint32_t createMediaContextCalled = 0; + uint32_t releaseMediaContextCalled = 0; }; } // namespace NEO diff --git a/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp index d2a3de502a..288e664554 100644 --- a/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp +++ b/shared/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp @@ -1726,6 +1726,26 @@ TEST_F(DrmMemoryManagerTest, whenCallingAllocateAndReleaseInterruptThenCallIoctl EXPECT_EQ(123u, mockIoctlHelper->latestReleaseInterruptHandle); } +TEST_F(DrmMemoryManagerTest, whenCallingCreateAndReleaseMediaContextThenCallIoctlHelper) { + auto mockIoctlHelper = new MockIoctlHelper(*mock); + + auto &drm = static_cast(memoryManager->getDrm(rootDeviceIndex)); + drm.ioctlHelper.reset(mockIoctlHelper); + + uint64_t handle = 0; + + EXPECT_EQ(0u, mockIoctlHelper->createMediaContextCalled); + EXPECT_EQ(0u, mockIoctlHelper->releaseMediaContextCalled); + + memoryManager->createMediaContext(rootDeviceIndex, nullptr, 0, nullptr, 0, handle); + EXPECT_EQ(1u, mockIoctlHelper->createMediaContextCalled); + EXPECT_EQ(0u, mockIoctlHelper->releaseMediaContextCalled); + + memoryManager->releaseMediaContext(rootDeviceIndex, handle); + EXPECT_EQ(1u, mockIoctlHelper->createMediaContextCalled); + EXPECT_EQ(1u, mockIoctlHelper->releaseMediaContextCalled); +} + TEST_F(DrmMemoryManagerTest, GivenShareableEnabledWhenAskedToCreateGraphicsAllocationThenValidAllocationIsReturnedAndStandard64KBHeapIsUsed) { mock->ioctlHelper.reset(new MockIoctlHelper(*mock)); mock->queryMemoryInfo(); diff --git a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.h b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.h index 5a0a1fe06b..e55655823b 100644 --- a/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.h +++ b/shared/test/unit_test/os_interface/linux/xe/ioctl_helper_xe_tests.h @@ -302,6 +302,7 @@ class DrmMockXe : public DrmMockCustom { case DrmIoctl::gemContextCreateExt: { auto queueCreate = static_cast(arg); latestExecQueueCreate = *queueCreate; + latestQueueEngineClassInstance = reinterpret_cast(queueCreate->instances)[0]; auto extension = queueCreate->extensions; while (extension) { @@ -310,6 +311,7 @@ class DrmMockXe : public DrmMockCustom { auto setProperty = reinterpret_cast(ext); execQueueProperties.push_back(*setProperty); } + handleContextCreateExtensions(ext); extension = ext->next_extension; } queueCreate->exec_queue_id = mockExecQueueId; @@ -334,6 +336,7 @@ class DrmMockXe : public DrmMockCustom { } virtual void handleUserFenceWaitExtensions(drm_xe_wait_user_fence *userFenceWait) {} + virtual void handleContextCreateExtensions(drm_xe_user_extension *extension) {} void addMockedQueryTopologyData(uint16_t tileId, uint16_t maskType, uint32_t nBytes, const std::vector &mask) { @@ -382,6 +385,7 @@ class DrmMockXe : public DrmMockCustom { StackVec syncInputs; StackVec execQueueProperties; drm_xe_exec_queue_create latestExecQueueCreate = {}; + drm_xe_engine_class_instance latestQueueEngineClassInstance = {}; int waitUserFenceReturn = 0; int execQueueBanPropertyReturn = 0;