diff --git a/opencl/test/unit_test/os_interface/linux/drm_buffer_object_tests.cpp b/opencl/test/unit_test/os_interface/linux/drm_buffer_object_tests.cpp index a61ae5841a..f2b431b818 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_buffer_object_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_buffer_object_tests.cpp @@ -9,6 +9,7 @@ #include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/libult/linux/drm_mock.h" #include "shared/test/common/mocks/linux/mock_drm_allocation.h" +#include "shared/test/common/mocks/linux/mock_drm_wrappers.h" #include "shared/test/common/mocks/mock_device.h" #include "shared/test/common/mocks/mock_gmm_helper.h" #include "shared/test/common/os_interface/linux/device_command_stream_fixture.h" @@ -25,7 +26,7 @@ TEST_F(DrmBufferObjectTest, WhenCallingExecThenReturnIsCorrect) { mock->ioctl_expected.total = 1; mock->ioctl_res = 0; - drm_i915_gem_exec_object2 execObjectsStorage = {}; + ExecObject execObjectsStorage = {}; auto ret = bo->exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage, 0, 0); EXPECT_EQ(mock->ioctl_res, ret); EXPECT_EQ(0u, mock->execBuffer.flags); @@ -35,7 +36,7 @@ TEST_F(DrmBufferObjectTest, GivenInvalidParamsWhenCallingExecThenEfaultIsReturne mock->ioctl_expected.total = 3; mock->ioctl_res = -1; mock->errnoValue = EFAULT; - drm_i915_gem_exec_object2 execObjectsStorage = {}; + ExecObject execObjectsStorage = {}; EXPECT_EQ(EFAULT, bo->exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage, 0, 0)); } @@ -46,7 +47,7 @@ TEST_F(DrmBufferObjectTest, GivenDetectedGpuHangDuringEvictUnusedAllocationsWhen bo->callBaseEvictUnusedAllocations = false; - drm_i915_gem_exec_object2 execObjectsStorage = {}; + ExecObject execObjectsStorage = {}; const auto result = bo->exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage, 0, 0); EXPECT_EQ(BufferObject::gpuHangDetected, result); @@ -80,25 +81,25 @@ TEST_F(DrmBufferObjectTest, givenBindAvailableWhenCallWaitThenNoIoctlIsCalled) { } TEST_F(DrmBufferObjectTest, givenAddressThatWhenSizeIsAddedCrosses32BitBoundaryWhenExecIsCalledThen48BitFlagIsSet) { - drm_i915_gem_exec_object2 execObject; + MockExecObject execObject{}; memset(&execObject, 0, sizeof(execObject)); bo->setAddress(((uint64_t)1u << 32) - 0x1000u); bo->setSize(0x1000); bo->fillExecObject(execObject, osContext.get(), 0, 1); //base address + size > size of 32bit address space - EXPECT_TRUE(execObject.flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS); + EXPECT_TRUE(execObject.has48BAddressSupportFlag()); } TEST_F(DrmBufferObjectTest, givenAddressThatWhenSizeIsAddedWithin32BitBoundaryWhenExecIsCalledThen48BitFlagSet) { - drm_i915_gem_exec_object2 execObject; + MockExecObject execObject{}; memset(&execObject, 0, sizeof(execObject)); bo->setAddress(((uint64_t)1u << 32) - 0x1000u); bo->setSize(0xFFF); bo->fillExecObject(execObject, osContext.get(), 0, 1); //base address + size < size of 32bit address space - EXPECT_TRUE(execObject.flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS); + EXPECT_TRUE(execObject.has48BAddressSupportFlag()); } TEST_F(DrmBufferObjectTest, whenExecFailsThenPinFails) { @@ -179,7 +180,7 @@ TEST_F(DrmBufferObjectTest, whenPrintExecutionBufferIsSetToTrueThenMessageFoundI mock->ioctl_expected.total = 1; DebugManagerStateRestore restore; DebugManager.flags.PrintExecutionBuffer.set(true); - drm_i915_gem_exec_object2 execObjectsStorage = {}; + ExecObject execObjectsStorage = {}; testing::internal::CaptureStdout(); auto ret = bo->exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage, 0, 0); @@ -369,7 +370,7 @@ TEST(DrmBufferObject, givenDrmIoctlReturnsErrorNotSupportedThenBufferObjectRetur std::unique_ptr osContext; osContext.reset(new OsContextLinux(*drm, 0u, EngineDescriptorHelper::getDefaultDescriptor())); - drm_i915_gem_exec_object2 execObjectsStorage = {}; + ExecObject execObjectsStorage = {}; auto ret = bo.exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage, 0, 0); EXPECT_NE(0, ret); } @@ -538,7 +539,7 @@ TEST(DrmBufferObject, whenMarkForCapturedCalledThenIsMarkedForCaptureReturnsTrue } TEST_F(DrmBufferObjectTest, givenBoMarkedForCaptureWhenFillingExecObjectThenCaptureFlagIsSet) { - drm_i915_gem_exec_object2 execObject; + MockExecObject execObject{}; memset(&execObject, 0, sizeof(execObject)); bo->markForCapture(); @@ -546,11 +547,11 @@ TEST_F(DrmBufferObjectTest, givenBoMarkedForCaptureWhenFillingExecObjectThenCapt bo->setSize(0x1000); bo->fillExecObject(execObject, osContext.get(), 0, 1); - EXPECT_TRUE(execObject.flags & EXEC_OBJECT_CAPTURE); + EXPECT_TRUE(execObject.hasCaptureFlag()); } TEST_F(DrmBufferObjectTest, givenAsyncDebugFlagWhenFillingExecObjectThenFlagIsSet) { - drm_i915_gem_exec_object2 execObject; + MockExecObject execObject{}; DebugManagerStateRestore restorer; DebugManager.flags.UseAsyncDrmExec.set(1); @@ -559,7 +560,7 @@ TEST_F(DrmBufferObjectTest, givenAsyncDebugFlagWhenFillingExecObjectThenFlagIsSe bo->setSize(0x1000); bo->fillExecObject(execObject, osContext.get(), 0, 1); - EXPECT_TRUE(execObject.flags & EXEC_OBJECT_ASYNC); + EXPECT_TRUE(execObject.hasAsyncFlag()); } TEST_F(DrmBufferObjectTest, given47bitAddressWhenSetThenIsAddressNotCanonized) { diff --git a/opencl/test/unit_test/os_interface/linux/drm_buffer_object_tests_prelim.cpp b/opencl/test/unit_test/os_interface/linux/drm_buffer_object_tests_prelim.cpp index b1c4b5651f..de9166e36e 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_buffer_object_tests_prelim.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_buffer_object_tests_prelim.cpp @@ -25,7 +25,7 @@ TEST_F(DrmBufferObjectPrelimTest, GivenCompletionAddressWhenCallingExecThenRetur constexpr uint32_t completionValue = 33; constexpr uint64_t expectedCompletionValue = completionValue; - drm_i915_gem_exec_object2 execObjectsStorage = {}; + ExecObject execObjectsStorage = {}; auto ret = bo->exec(0, 0, 0, false, osContext.get(), 0, 1, nullptr, 0u, &execObjectsStorage, completionAddress, completionValue); EXPECT_EQ(0, ret); EXPECT_EQ(completionAddress, mock->context.completionAddress); diff --git a/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests_2.cpp b/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests_2.cpp index bb362b636c..0401b179eb 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests_2.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests_2.cpp @@ -25,6 +25,7 @@ #include "shared/test/common/helpers/dispatch_flags_helper.h" #include "shared/test/common/helpers/execution_environment_helper.h" #include "shared/test/common/mocks/linux/mock_drm_command_stream_receiver.h" +#include "shared/test/common/mocks/linux/mock_drm_wrappers.h" #include "shared/test/common/mocks/mock_allocation_properties.h" #include "shared/test/common/mocks/mock_gmm.h" #include "shared/test/common/mocks/mock_gmm_page_table_mngr.h" @@ -72,7 +73,7 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenCommandStreamWhenItIsFlush HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenTaskThatRequiresLargeResourceCountWhenItIsFlushedThenExecStorageIsResized) { std::vector graphicsAllocations; - auto &execStorage = static_cast *>(csr)->getExecStorage(); + auto &execStorage = static_cast *>(csr)->execObjectsStorage; execStorage.resize(0); for (auto id = 0; id < 10; id++) { @@ -1585,18 +1586,19 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenAllocInMemoryOperationsInt csr->flush(batchBuffer, csr->getResidencyAllocations()); - const auto boRequirments = [&allocation](const auto &bo) { - return (static_cast(bo.handle) == static_cast(allocation)->getBO()->peekHandle() && - bo.offset == static_cast(allocation)->getBO()->peekAddress()); + const auto execObjectRequirements = [&allocation](const auto &execObject) { + auto mockExecObject = static_cast(execObject); + return (static_cast(mockExecObject.getHandle()) == static_cast(allocation)->getBO()->peekHandle() && + mockExecObject.getOffset() == static_cast(allocation)->getBO()->peekAddress()); }; - auto &residency = static_cast *>(csr)->getExecStorage(); - EXPECT_TRUE(std::find_if(residency.begin(), residency.end(), boRequirments) != residency.end()); + auto &residency = static_cast *>(csr)->execObjectsStorage; + EXPECT_TRUE(std::find_if(residency.begin(), residency.end(), execObjectRequirements) != residency.end()); EXPECT_EQ(residency.size(), 2u); residency.clear(); csr->flush(batchBuffer, csr->getResidencyAllocations()); - EXPECT_TRUE(std::find_if(residency.begin(), residency.end(), boRequirments) != residency.end()); + EXPECT_TRUE(std::find_if(residency.begin(), residency.end(), execObjectRequirements) != residency.end()); EXPECT_EQ(residency.size(), 2u); residency.clear(); @@ -1605,7 +1607,7 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenAllocInMemoryOperationsInt csr->flush(batchBuffer, csr->getResidencyAllocations()); - EXPECT_FALSE(std::find_if(residency.begin(), residency.end(), boRequirments) != residency.end()); + EXPECT_FALSE(std::find_if(residency.begin(), residency.end(), execObjectRequirements) != residency.end()); EXPECT_EQ(residency.size(), 1u); mm->freeGraphicsMemory(allocation); diff --git a/opencl/test/unit_test/os_interface/linux/drm_memory_manager_localmem_prelim_tests.cpp b/opencl/test/unit_test/os_interface/linux/drm_memory_manager_localmem_prelim_tests.cpp index 7443cf8362..7e25a20fc2 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_memory_manager_localmem_prelim_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_memory_manager_localmem_prelim_tests.cpp @@ -15,6 +15,7 @@ #include "shared/test/common/libult/linux/drm_mock_helper.h" #include "shared/test/common/libult/linux/drm_mock_prelim_context.h" #include "shared/test/common/libult/linux/drm_query_mock.h" +#include "shared/test/common/mocks/linux/mock_drm_wrappers.h" #include "shared/test/common/mocks/mock_allocation_properties.h" #include "shared/test/common/mocks/mock_gfx_partition.h" #include "shared/test/common/mocks/mock_gmm.h" @@ -2086,13 +2087,14 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedPrelimTest, givenUseVmBindSetWhenFlus csr->flush(batchBuffer, csr->getResidencyAllocations()); - const auto boRequirments = [&allocation](const auto &bo) { - return (static_cast(bo.handle) == 0u && - bo.offset == static_cast(allocation)->getBO()->peekAddress()); + const auto execObjectRequirements = [&allocation](const auto &execObject) { + auto mockExecObject = static_cast(execObject); + return (mockExecObject.getHandle() == 0 && + mockExecObject.getOffset() == static_cast(allocation)->getBO()->peekAddress()); }; - auto &residency = static_cast *>(csr)->getExecStorage(); - EXPECT_TRUE(std::find_if(residency.begin(), residency.end(), boRequirments) == residency.end()); + auto &residency = static_cast *>(csr)->execObjectsStorage; + EXPECT_TRUE(std::find_if(residency.begin(), residency.end(), execObjectRequirements) == residency.end()); EXPECT_EQ(residency.size(), 1u); residency.clear(); @@ -2115,13 +2117,14 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedPrelimTest, givenUseVmBindAndPassBoun csr->flush(batchBuffer, csr->getResidencyAllocations()); - const auto boRequirments = [&allocation](const auto &bo) { - return (static_cast(bo.handle) == 0 && - bo.offset == static_cast(allocation)->getBO()->peekAddress()); + const auto execObjectRequirements = [&allocation](const auto &execObject) { + auto mockExecObject = static_cast(execObject); + return (mockExecObject.getHandle() == 0 && + mockExecObject.getOffset() == static_cast(allocation)->getBO()->peekAddress()); }; - auto &residency = static_cast *>(csr)->getExecStorage(); - EXPECT_FALSE(std::find_if(residency.begin(), residency.end(), boRequirments) != residency.end()); + auto &residency = static_cast *>(csr)->execObjectsStorage; + EXPECT_FALSE(std::find_if(residency.begin(), residency.end(), execObjectRequirements) != residency.end()); EXPECT_EQ(residency.size(), 1u); residency.clear(); @@ -2144,13 +2147,14 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedPrelimTest, givenUseVmBindAndPassBoun csr->flush(batchBuffer, csr->getResidencyAllocations()); - const auto boRequirments = [&allocation](const auto &bo) { - return (static_cast(bo.handle) == 0 && - bo.offset == static_cast(allocation)->getBO()->peekAddress()); + const auto execObjectRequirements = [&allocation](const auto &execObject) { + auto mockExecObject = static_cast(execObject); + return (mockExecObject.getHandle() == 0 && + mockExecObject.getOffset() == static_cast(allocation)->getBO()->peekAddress()); }; - auto &residency = static_cast *>(csr)->getExecStorage(); - EXPECT_TRUE(std::find_if(residency.begin(), residency.end(), boRequirments) != residency.end()); + auto &residency = static_cast *>(csr)->execObjectsStorage; + EXPECT_TRUE(std::find_if(residency.begin(), residency.end(), execObjectRequirements) != residency.end()); EXPECT_EQ(residency.size(), 2u); residency.clear(); diff --git a/shared/source/direct_submission/linux/drm_direct_submission.inl b/shared/source/direct_submission/linux/drm_direct_submission.inl index fe4e5ba37d..94c682dff8 100644 --- a/shared/source/direct_submission/linux/drm_direct_submission.inl +++ b/shared/source/direct_submission/linux/drm_direct_submission.inl @@ -83,7 +83,7 @@ bool DrmDirectSubmission::submit(uint64_t gpuAddress, siz auto execFlags = osContextLinux->getEngineFlag() | I915_EXEC_NO_RELOC; auto &drmContextIds = osContextLinux->getDrmContextIds(); - drm_i915_gem_exec_object2 execObject{}; + ExecObject execObject{}; this->handleResidency(); diff --git a/shared/source/os_interface/linux/drm_buffer_object.cpp b/shared/source/os_interface/linux/drm_buffer_object.cpp index 0abe69c619..655897ee4c 100644 --- a/shared/source/os_interface/linux/drm_buffer_object.cpp +++ b/shared/source/os_interface/linux/drm_buffer_object.cpp @@ -115,32 +115,15 @@ uint32_t BufferObject::getOsContextId(OsContext *osContext) { return perContextVmsUsed ? osContext->getContextId() : 0u; } -void BufferObject::fillExecObject(drm_i915_gem_exec_object2 &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) { - execObject.handle = this->handle; - execObject.relocation_count = 0; //No relocations, we are SoftPinning - execObject.relocs_ptr = 0ul; - execObject.alignment = 0; - execObject.offset = this->gpuAddress; - execObject.flags = EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS; - - if (DebugManager.flags.UseAsyncDrmExec.get() == 1) { - execObject.flags |= EXEC_OBJECT_ASYNC; - } - - if (this->isMarkedForCapture()) { - execObject.flags |= EXEC_OBJECT_CAPTURE; - } - execObject.rsvd1 = drmContextId; - execObject.rsvd2 = 0; - +void BufferObject::fillExecObject(ExecObject &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) { const auto osContextId = drm->isPerContextVMRequired() ? osContext->getContextId() : 0; - if (this->bindInfo[osContextId][vmHandleId]) { - execObject.handle = 0u; - } + + auto ioctlHelper = drm->getIoctlHelper(); + ioctlHelper->fillExecObject(execObject, this->handle, this->gpuAddress, drmContextId, this->bindInfo[osContextId][vmHandleId], this->isMarkedForCapture()); } int BufferObject::exec(uint32_t used, size_t startOffset, unsigned int flags, bool requiresCoherency, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId, - BufferObject *const residency[], size_t residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage, uint64_t completionGpuAddress, uint32_t completionValue) { + BufferObject *const residency[], size_t residencyCount, ExecObject *execObjectsStorage, uint64_t completionGpuAddress, uint32_t completionValue) { for (size_t i = 0; i < residencyCount; i++) { residency[i]->fillExecObject(execObjectsStorage[i], osContext, vmHandleId, drmContextId); } @@ -249,7 +232,8 @@ int BufferObject::unbind(OsContext *osContext, uint32_t vmHandleId) { return retVal; } -void BufferObject::printExecutionBuffer(drm_i915_gem_execbuffer2 &execbuf, const size_t &residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage, BufferObject *const residency[]) { +void BufferObject::printExecutionBuffer(drm_i915_gem_execbuffer2 &execbuf, const size_t &residencyCount, ExecObject *execObjectsStorage, BufferObject *const residency[]) { + auto ioctlHelper = drm->getIoctlHelper(); std::stringstream logger; logger << "drm_i915_gem_execbuffer2 { " << "buffer_ptr: " + std::to_string(execbuf.buffers_ptr) @@ -262,17 +246,10 @@ void BufferObject::printExecutionBuffer(drm_i915_gem_execbuffer2 &execbuf, const size_t i; for (i = 0; i < residencyCount; i++) { - logger << "Buffer Object = { handle: BO-" << execObjectsStorage[i].handle - << ", address range: 0x" << (void *)execObjectsStorage[i].offset - << " - 0x" << (void *)ptrOffset(execObjectsStorage[i].offset, residency[i]->peekSize()) - << ", flags: " << std::hex << execObjectsStorage[i].flags << std::dec - << ", size: " << residency[i]->peekSize() << " }\n"; + ioctlHelper->logExecObject(execObjectsStorage[i], logger, residency[i]->peekSize()); } - logger << "Command Buffer Object = { handle: BO-" << execObjectsStorage[i].handle - << ", address range: 0x" << (void *)execObjectsStorage[i].offset - << " - 0x" << (void *)ptrOffset(execObjectsStorage[i].offset, this->peekSize()) - << ", flags: " << std::hex << execObjectsStorage[i].flags << std::dec - << ", size: " << this->peekSize() << " }\n"; + logger << "Command "; + ioctlHelper->logExecObject(execObjectsStorage[i], logger, this->peekSize()); printf("%s\n", logger.str().c_str()); } @@ -297,7 +274,7 @@ int BufferObject::pin(BufferObject *const boToPin[], size_t numberOfBos, OsConte if (this->drm->isVmBindAvailable()) { retVal = bindBOsWithinContext(boToPin, numberOfBos, osContext, vmHandleId); } else { - StackVec execObject(numberOfBos + 1); + StackVec execObject(numberOfBos + 1); retVal = this->exec(4u, 0u, 0u, false, osContext, vmHandleId, drmContextId, boToPin, numberOfBos, &execObject[0], 0, 0); } @@ -315,7 +292,7 @@ int BufferObject::validateHostPtr(BufferObject *const boToPin[], size_t numberOf } } } else { - StackVec execObject(numberOfBos + 1); + StackVec execObject(numberOfBos + 1); retVal = this->exec(4u, 0u, 0u, false, osContext, vmHandleId, drmContextId, boToPin, numberOfBos, &execObject[0], 0, 0); } diff --git a/shared/source/os_interface/linux/drm_buffer_object.h b/shared/source/os_interface/linux/drm_buffer_object.h index 0494d72061..369a7a1ffe 100644 --- a/shared/source/os_interface/linux/drm_buffer_object.h +++ b/shared/source/os_interface/linux/drm_buffer_object.h @@ -19,12 +19,12 @@ #include #include -struct drm_i915_gem_exec_object2; struct drm_i915_gem_relocation_entry; struct drm_i915_gem_execbuffer2; namespace NEO { +struct ExecObject; class DrmMemoryManager; class Drm; class OsContext; @@ -47,12 +47,12 @@ class BufferObject { MOCKABLE_VIRTUAL int validateHostPtr(BufferObject *const boToPin[], size_t numberOfBos, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId); MOCKABLE_VIRTUAL int exec(uint32_t used, size_t startOffset, unsigned int flags, bool requiresCoherency, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId, - BufferObject *const residency[], size_t residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage, uint64_t completionGpuAddress, uint32_t completionValue); + BufferObject *const residency[], size_t residencyCount, ExecObject *execObjectsStorage, uint64_t completionGpuAddress, uint32_t completionValue); int bind(OsContext *osContext, uint32_t vmHandleId); int unbind(OsContext *osContext, uint32_t vmHandleId); - void printExecutionBuffer(drm_i915_gem_execbuffer2 &execbuf, const size_t &residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage, BufferObject *const residency[]); + void printExecutionBuffer(drm_i915_gem_execbuffer2 &execbuf, const size_t &residencyCount, ExecObject *execObjectsStorage, BufferObject *const residency[]); int wait(int64_t timeoutNs); bool close(); @@ -159,7 +159,7 @@ class BufferObject { bool requiresExplicitResidency = false; uint32_t getOsContextId(OsContext *osContext); - MOCKABLE_VIRTUAL void fillExecObject(drm_i915_gem_exec_object2 &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId); + MOCKABLE_VIRTUAL void fillExecObject(ExecObject &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId); void printBOBindingResult(OsContext *osContext, uint32_t vmHandleId, bool bind, int retVal); void *lockedAddress; // CPU side virtual address diff --git a/shared/source/os_interface/linux/drm_command_stream.h b/shared/source/os_interface/linux/drm_command_stream.h index 3eb581f5de..e76da69d2a 100644 --- a/shared/source/os_interface/linux/drm_command_stream.h +++ b/shared/source/os_interface/linux/drm_command_stream.h @@ -8,8 +8,7 @@ #pragma once #include "shared/source/command_stream/device_command_stream.h" #include "shared/source/os_interface/linux/drm_gem_close_worker.h" - -#include "drm/i915_drm.h" +#include "shared/source/os_interface/linux/ioctl_helper.h" #include @@ -74,7 +73,7 @@ class DrmCommandStreamReceiver : public DeviceCommandStreamReceiver { bool isUserFenceWaitActive(); std::vector residency; - std::vector execObjectsStorage; + std::vector execObjectsStorage; Drm *drm; gemCloseWorkerMode gemCloseWorkerOperationMode; diff --git a/shared/source/os_interface/linux/drm_neo.h b/shared/source/os_interface/linux/drm_neo.h index 5534773df6..34386fb41d 100644 --- a/shared/source/os_interface/linux/drm_neo.h +++ b/shared/source/os_interface/linux/drm_neo.h @@ -20,7 +20,6 @@ #include "shared/source/utilities/api_intercept.h" #include "shared/source/utilities/stackvec.h" -#include "drm/i915_drm.h" #include "engine_node.h" #include "igfxfmid.h" diff --git a/shared/source/os_interface/linux/ioctl_helper.cpp b/shared/source/os_interface/linux/ioctl_helper.cpp index dcc2acd7a0..40902e22d5 100644 --- a/shared/source/os_interface/linux/ioctl_helper.cpp +++ b/shared/source/os_interface/linux/ioctl_helper.cpp @@ -7,12 +7,50 @@ #include "shared/source/os_interface/linux/ioctl_helper.h" +#include "shared/source/helpers/ptr_math.h" #include "shared/source/os_interface/linux/drm_neo.h" +#include "drm/i915_drm.h" + namespace NEO { uint32_t IoctlHelper::ioctl(Drm *drm, unsigned long request, void *arg) { return drm->ioctl(request, arg); } +static_assert(sizeof(ExecObject) == sizeof(drm_i915_gem_exec_object2)); + +void IoctlHelper::fillExecObject(ExecObject &execObject, uint32_t handle, uint64_t gpuAddress, uint32_t drmContextId, bool bindInfo, bool isMarkedForCapture) { + + auto drmExecObject = reinterpret_cast(execObject.data); + drmExecObject->handle = handle; + drmExecObject->relocation_count = 0; //No relocations, we are SoftPinning + drmExecObject->relocs_ptr = 0ul; + drmExecObject->alignment = 0; + drmExecObject->offset = gpuAddress; + drmExecObject->flags = EXEC_OBJECT_PINNED | EXEC_OBJECT_SUPPORTS_48B_ADDRESS; + + if (DebugManager.flags.UseAsyncDrmExec.get() == 1) { + drmExecObject->flags |= EXEC_OBJECT_ASYNC; + } + + if (isMarkedForCapture) { + drmExecObject->flags |= EXEC_OBJECT_CAPTURE; + } + drmExecObject->rsvd1 = drmContextId; + drmExecObject->rsvd2 = 0; + + if (bindInfo) { + drmExecObject->handle = 0u; + } +} + +void IoctlHelper::logExecObject(const ExecObject &execObject, std::stringstream &logger, size_t size) { + auto drmExecObject = reinterpret_cast(execObject.data); + logger << "Buffer Object = { handle: BO-" << drmExecObject->handle + << ", address range: 0x" << reinterpret_cast(drmExecObject->offset) + << " - 0x" << reinterpret_cast(ptrOffset(drmExecObject->offset, size)) + << ", flags: " << std::hex << drmExecObject->flags << std::dec + << ", size: " << size << " }\n"; +} } // namespace NEO diff --git a/shared/source/os_interface/linux/ioctl_helper.h b/shared/source/os_interface/linux/ioctl_helper.h index 5e7a4f5470..4d2170ce8e 100644 --- a/shared/source/os_interface/linux/ioctl_helper.h +++ b/shared/source/os_interface/linux/ioctl_helper.h @@ -75,6 +75,10 @@ using MemRegionsVec = StackVec; using VmBindExtSetPatT = uint8_t[40]; using VmBindExtUserFenceT = uint8_t[56]; +struct ExecObject { + uint8_t data[56]; +}; + class IoctlHelper { public: virtual ~IoctlHelper() {} @@ -127,6 +131,9 @@ class IoctlHelper { virtual bool isContextDebugSupported(Drm *drm) = 0; virtual int setContextDebugFlag(Drm *drm, uint32_t drmContextId) = 0; virtual bool isDebugAttachAvailable() = 0; + + void fillExecObject(ExecObject &execObject, uint32_t handle, uint64_t gpuAddress, uint32_t drmContextId, bool bindInfo, bool isMarkedForCapture); + void logExecObject(const ExecObject &execObject, std::stringstream &logger, size_t size); }; class IoctlHelperUpstream : public IoctlHelper { diff --git a/shared/test/common/mocks/CMakeLists.txt b/shared/test/common/mocks/CMakeLists.txt index 283f1ea4f2..964636d64c 100644 --- a/shared/test/common/mocks/CMakeLists.txt +++ b/shared/test/common/mocks/CMakeLists.txt @@ -107,6 +107,8 @@ else() ${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_allocation.h ${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_command_stream_receiver.h ${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_memory_manager.h + ${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_wrappers.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_drm_wrappers.h ${CMAKE_CURRENT_SOURCE_DIR}/linux/mock_os_context_linux.h ) endif() diff --git a/shared/test/common/mocks/linux/mock_drm_allocation.h b/shared/test/common/mocks/linux/mock_drm_allocation.h index b7966f7c88..3359a48490 100644 --- a/shared/test/common/mocks/linux/mock_drm_allocation.h +++ b/shared/test/common/mocks/linux/mock_drm_allocation.h @@ -27,7 +27,7 @@ class MockBufferObject : public BufferObject { MockBufferObject(Drm *drm) : BufferObject(drm, CommonConstants::unsupportedPatIndex, 0, 0, 1) { } int exec(uint32_t used, size_t startOffset, unsigned int flags, bool requiresCoherency, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId, - BufferObject *const residency[], size_t residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage, uint64_t completionGpuAddress, uint32_t completionValue) override { + BufferObject *const residency[], size_t residencyCount, ExecObject *execObjectsStorage, uint64_t completionGpuAddress, uint32_t completionValue) override { passedExecParams.push_back({completionGpuAddress, completionValue}); return BufferObject::exec(used, startOffset, flags, requiresCoherency, osContext, vmHandleId, drmContextId, residency, residencyCount, execObjectsStorage, completionGpuAddress, completionValue); diff --git a/shared/test/common/mocks/linux/mock_drm_command_stream_receiver.h b/shared/test/common/mocks/linux/mock_drm_command_stream_receiver.h index 5c8d001358..65eb10c5d7 100644 --- a/shared/test/common/mocks/linux/mock_drm_command_stream_receiver.h +++ b/shared/test/common/mocks/linux/mock_drm_command_stream_receiver.h @@ -35,6 +35,7 @@ class TestedDrmCommandStreamReceiver : public DrmCommandStreamReceiver::residency; using DrmCommandStreamReceiver::useContextForUserFenceWait; using DrmCommandStreamReceiver::useUserFenceWait; + using DrmCommandStreamReceiver::execObjectsStorage; using CommandStreamReceiverHw::directSubmission; using CommandStreamReceiverHw::blitterDirectSubmission; using CommandStreamReceiverHw::CommandStreamReceiver::lastSentSliceCount; @@ -75,10 +76,6 @@ class TestedDrmCommandStreamReceiver : public DrmCommandStreamReceiversubmissionAggregator.reset(newSubmissionsAggregator); } - std::vector &getExecStorage() { - return this->execObjectsStorage; - } - bool createPreemptionAllocation() override { if (ultHwConfig.csrBaseCallCreatePreemption) { return CommandStreamReceiver::createPreemptionAllocation(); diff --git a/shared/test/common/mocks/linux/mock_drm_wrappers.cpp b/shared/test/common/mocks/linux/mock_drm_wrappers.cpp new file mode 100644 index 0000000000..365ceb0a22 --- /dev/null +++ b/shared/test/common/mocks/linux/mock_drm_wrappers.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/test/common/mocks/linux/mock_drm_wrappers.h" + +#include "drm/i915_drm.h" + +namespace NEO { + +uint32_t MockExecObject::getHandle() const { + auto drmExecObject = reinterpret_cast(this->data); + return drmExecObject->handle; +} +uint64_t MockExecObject::getOffset() const { + auto drmExecObject = reinterpret_cast(this->data); + return drmExecObject->offset; +} +bool MockExecObject::has48BAddressSupportFlag() const { + auto drmExecObject = reinterpret_cast(this->data); + return drmExecObject->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS; +} +bool MockExecObject::hasCaptureFlag() const { + auto drmExecObject = reinterpret_cast(this->data); + return drmExecObject->flags & EXEC_OBJECT_CAPTURE; +} +bool MockExecObject::hasAsyncFlag() const { + auto drmExecObject = reinterpret_cast(this->data); + return drmExecObject->flags & EXEC_OBJECT_ASYNC; +} +} // namespace NEO diff --git a/shared/test/common/mocks/linux/mock_drm_wrappers.h b/shared/test/common/mocks/linux/mock_drm_wrappers.h new file mode 100644 index 0000000000..7f9e39c013 --- /dev/null +++ b/shared/test/common/mocks/linux/mock_drm_wrappers.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/os_interface/linux/ioctl_helper.h" + +namespace NEO { + +struct MockExecObject : ExecObject { + uint32_t getHandle() const; + uint64_t getOffset() const; + bool has48BAddressSupportFlag() const; + bool hasCaptureFlag() const; + bool hasAsyncFlag() const; +}; + +static_assert(sizeof(MockExecObject) == sizeof(ExecObject)); +} // namespace NEO diff --git a/shared/test/common/os_interface/linux/drm_buffer_object_fixture.h b/shared/test/common/os_interface/linux/drm_buffer_object_fixture.h index ef5895bd40..ac25780ac8 100644 --- a/shared/test/common/os_interface/linux/drm_buffer_object_fixture.h +++ b/shared/test/common/os_interface/linux/drm_buffer_object_fixture.h @@ -12,8 +12,6 @@ #include "shared/test/common/helpers/engine_descriptor_helper.h" #include "shared/test/common/mocks/mock_execution_environment.h" -#include "drm/i915_drm.h" - #include class TestedBufferObject : public BufferObject { @@ -29,7 +27,7 @@ class TestedBufferObject : public BufferObject { this->tilingMode = mode; } - void fillExecObject(drm_i915_gem_exec_object2 &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) override { + void fillExecObject(ExecObject &execObject, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId) override { BufferObject::fillExecObject(execObject, osContext, vmHandleId, drmContextId); execObjectPointerFilled = &execObject; } @@ -39,7 +37,7 @@ class TestedBufferObject : public BufferObject { } int exec(uint32_t used, size_t startOffset, unsigned int flags, bool requiresCoherency, OsContext *osContext, uint32_t vmHandleId, uint32_t drmContextId, - BufferObject *const residency[], size_t residencyCount, drm_i915_gem_exec_object2 *execObjectsStorage, uint64_t completionGpuAddress, uint32_t completionValue) override { + BufferObject *const residency[], size_t residencyCount, ExecObject *execObjectsStorage, uint64_t completionGpuAddress, uint32_t completionValue) override { this->receivedCompletionGpuAddress = completionGpuAddress; this->receivedCompletionValue = completionValue; this->execCalled++; @@ -59,7 +57,7 @@ class TestedBufferObject : public BufferObject { } uint64_t receivedCompletionGpuAddress = 0; - drm_i915_gem_exec_object2 *execObjectPointerFilled = nullptr; + ExecObject *execObjectPointerFilled = nullptr; uint32_t receivedCompletionValue = 0; uint32_t execCalled = 0; bool callBaseEvictUnusedAllocations{true}; @@ -70,7 +68,7 @@ class DrmBufferObjectFixture { public: std::unique_ptr mock; TestedBufferObject *bo; - drm_i915_gem_exec_object2 execObjectsStorage[256]; + ExecObject execObjectsStorage[256]; std::unique_ptr osContext; void SetUp() { // NOLINT(readability-identifier-naming)