From 3c18744d10b9ce9505444fd35818f199803c33ac Mon Sep 17 00:00:00 2001 From: Mateusz Jablonski Date: Thu, 12 May 2022 15:56:50 +0000 Subject: [PATCH] Create a wrapper for drm_i915_gem_execbuffer2 Related-To: NEO-6852 Signed-off-by: Mateusz Jablonski --- .../device_command_stream_fixture_context.cpp | 12 ++-- .../linux/drm_buffer_object_tests.cpp | 14 ++--- .../linux/drm_command_stream_tests_1.cpp | 50 ++++++++-------- .../linux/drm_command_stream_tests_2.cpp | 2 +- ...and_stream_xehp_and_later_prelim_tests.cpp | 6 +- .../linux/drm_memory_manager_tests.cpp | 4 +- .../os_interface/linux/drm_buffer_object.cpp | 24 +++----- .../os_interface/linux/drm_buffer_object.h | 6 +- .../os_interface/linux/ioctl_helper.cpp | 59 ++++++++++++------ .../source/os_interface/linux/ioctl_helper.h | 14 +++-- .../linux/ioctl_helper_prelim.cpp | 9 +-- .../linux/ioctl_helper_upstream.cpp | 2 +- shared/test/common/libult/linux/drm_mock.cpp | 6 +- shared/test/common/libult/linux/drm_mock.h | 5 +- .../common/mocks/linux/mock_drm_wrappers.cpp | 60 +++++++++++++++---- .../common/mocks/linux/mock_drm_wrappers.h | 17 +++++- .../linux/device_command_stream_fixture.cpp | 4 +- .../linux/device_command_stream_fixture.h | 5 +- 18 files changed, 189 insertions(+), 110 deletions(-) diff --git a/opencl/test/unit_test/os_interface/linux/device_command_stream_fixture_context.cpp b/opencl/test/unit_test/os_interface/linux/device_command_stream_fixture_context.cpp index 97b31d5350..5fe4c8443d 100644 --- a/opencl/test/unit_test/os_interface/linux/device_command_stream_fixture_context.cpp +++ b/opencl/test/unit_test/os_interface/linux/device_command_stream_fixture_context.cpp @@ -7,6 +7,8 @@ #include "opencl/test/unit_test/os_interface/linux/device_command_stream_fixture_context.h" +#include "shared/test/common/mocks/linux/mock_drm_wrappers.h" + #include "third_party/uapi/prelim/drm/i915_drm.h" int DrmMockCustomPrelimContext::ioctlExtra(unsigned long request, void *arg) { @@ -45,13 +47,13 @@ int DrmMockCustomPrelimContext::ioctlExtra(unsigned long request, void *arg) { } void DrmMockCustomPrelimContext::execBufferExtensions(void *arg) { - const auto execbuf = reinterpret_cast(arg); - if ((execbuf->flags | I915_EXEC_USE_EXTENSIONS) && - (execbuf->cliprects_ptr != 0)) { - i915_user_extension *base = reinterpret_cast(execbuf->cliprects_ptr); + const auto execbuf = reinterpret_cast(arg); + if ((execbuf->hasUseExtensionsFlag()) && + (execbuf->getCliprectsPtr() != 0)) { + i915_user_extension *base = reinterpret_cast(execbuf->getCliprectsPtr()); if (base->name == PRELIM_DRM_I915_GEM_EXECBUFFER_EXT_USER_FENCE) { prelim_drm_i915_gem_execbuffer_ext_user_fence *userFenceExt = - reinterpret_cast(execbuf->cliprects_ptr); + reinterpret_cast(execbuf->getCliprectsPtr()); this->completionAddress = userFenceExt->addr; this->completionValue = userFenceExt->value; } 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 f2b431b818..07ffbb6a3f 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 @@ -29,7 +29,7 @@ TEST_F(DrmBufferObjectTest, WhenCallingExecThenReturnIsCorrect) { 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); + EXPECT_EQ(0u, mock->execBuffer.getFlags()); } TEST_F(DrmBufferObjectTest, GivenInvalidParamsWhenCallingExecThenEfaultIsReturned) { @@ -275,9 +275,9 @@ TEST(DrmBufferObjectSimpleTest, givenArrayOfBosWhenPinnedThenAllBosArePinned) { auto ret = bo->pin(array, 3, &osContext, 0, 1); EXPECT_EQ(mock->ioctl_res, ret); - EXPECT_LT(0u, mock->execBuffer.batch_len); - EXPECT_EQ(4u, mock->execBuffer.buffer_count); // 3 bos to pin plus 1 exec bo - EXPECT_EQ(reinterpret_cast(boToPin->execObjectPointerFilled), mock->execBuffer.buffers_ptr); + EXPECT_LT(0u, mock->execBuffer.getBatchLen()); + EXPECT_EQ(4u, mock->execBuffer.getBufferCount()); // 3 bos to pin plus 1 exec bo + EXPECT_EQ(reinterpret_cast(boToPin->execObjectPointerFilled), mock->execBuffer.getBuffersPtr()); EXPECT_NE(nullptr, boToPin2->execObjectPointerFilled); EXPECT_NE(nullptr, boToPin3->execObjectPointerFilled); @@ -309,9 +309,9 @@ TEST(DrmBufferObjectSimpleTest, givenArrayOfBosWhenValidatedThenAllBosArePinned) auto ret = bo->validateHostPtr(array, 3, &osContext, 0, 1); EXPECT_EQ(mock->ioctl_res, ret); - EXPECT_LT(0u, mock->execBuffer.batch_len); - EXPECT_EQ(4u, mock->execBuffer.buffer_count); // 3 bos to pin plus 1 exec bo - EXPECT_EQ(reinterpret_cast(boToPin->execObjectPointerFilled), mock->execBuffer.buffers_ptr); + EXPECT_LT(0u, mock->execBuffer.getBatchLen()); + EXPECT_EQ(4u, mock->execBuffer.getBufferCount()); // 3 bos to pin plus 1 exec bo + EXPECT_EQ(reinterpret_cast(boToPin->execObjectPointerFilled), mock->execBuffer.getBuffersPtr()); EXPECT_NE(nullptr, boToPin2->execObjectPointerFilled); EXPECT_NE(nullptr, boToPin3->execObjectPointerFilled); diff --git a/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests_1.cpp b/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests_1.cpp index 1c94937b9b..14db2a2f1f 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests_1.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests_1.cpp @@ -139,8 +139,8 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, WhenFlushingThenAvailableSpaceDoesNotCh EXPECT_EQ(1, mock->ioctlCount.gemUserptr); EXPECT_EQ(1, mock->ioctlCount.execbuffer2); - EXPECT_EQ(0u, mock->execBuffers.back().batch_start_offset); - EXPECT_EQ(expectedSize, mock->execBuffers.back().batch_len); + EXPECT_EQ(0u, mock->execBuffers.back().getBatchStartOffset()); + EXPECT_EQ(expectedSize, mock->execBuffers.back().getBatchLen()); } HWTEST_TEMPLATED_F(DrmCommandStreamTest, givenPrintIndicesEnabledWhenFlushThenPrintIndices) { @@ -194,11 +194,11 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, givenDrmContextIdWhenFlushingThenSetIdT EXPECT_EQ(1, mock->ioctlCount.contextCreate); EXPECT_EQ(1, mock->ioctlCount.execbuffer2); - EXPECT_EQ(numAllocations, mock->execBuffers.back().buffer_count); - EXPECT_EQ(expectedDrmContextId, mock->execBuffers.back().rsvd1); + EXPECT_EQ(numAllocations, mock->execBuffers.back().getBufferCount()); + EXPECT_EQ(expectedDrmContextId, mock->execBuffers.back().getReserved()); for (uint32_t i = 0; i < mock->receivedBos.size(); i++) { - EXPECT_EQ(expectedDrmContextId, mock->receivedBos[i].rsvd1); + EXPECT_EQ(expectedDrmContextId, mock->receivedBos[i].getReserved()); } } @@ -224,8 +224,8 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenLowPriorityContextWhenFlushingThen mock->ioctlTearDownExpected.gemClose = 1; mock->ioctlTearDownExpects = true; - EXPECT_EQ(0u, mock->execBuffers.back().batch_start_offset); - EXPECT_EQ(expectedSize, mock->execBuffers.back().batch_len); + EXPECT_EQ(0u, mock->execBuffers.back().getBatchStartOffset()); + EXPECT_EQ(expectedSize, mock->execBuffers.back().getBatchLen()); } HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenInvalidAddressWhenFlushingThenSucceeds) { @@ -268,8 +268,8 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenNotEmptyBbWhenFlushingThenSucceeds mock->ioctlTearDownExpected.gemClose = 1; mock->ioctlTearDownExpects = true; - EXPECT_EQ(0u, mock->execBuffers.back().batch_start_offset); - EXPECT_EQ(expectedSize, mock->execBuffers.back().batch_len); + EXPECT_EQ(0u, mock->execBuffers.back().getBatchStartOffset()); + EXPECT_EQ(expectedSize, mock->execBuffers.back().getBatchLen()); } HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenNotEmptyNotPaddedBbWhenFlushingThenSucceeds) { @@ -290,8 +290,8 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenNotEmptyNotPaddedBbWhenFlushingThe mock->ioctlTearDownExpected.gemClose = 1; mock->ioctlTearDownExpects = true; - EXPECT_EQ(0u, mock->execBuffers.back().batch_start_offset); - EXPECT_EQ(bbUsed + 4, mock->execBuffers.back().batch_len); + EXPECT_EQ(0u, mock->execBuffers.back().getBatchStartOffset()); + EXPECT_EQ(bbUsed + 4, mock->execBuffers.back().getBatchLen()); } HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenNotAlignedWhenFlushingThenSucceeds) { @@ -317,8 +317,8 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenNotAlignedWhenFlushingThenSucceeds mock->ioctlTearDownExpected.gemClose = 1; mock->ioctlTearDownExpects = true; - EXPECT_EQ(expectedBatchStartOffset, mock->execBuffers.back().batch_start_offset); - EXPECT_EQ(expectedSize, mock->execBuffers.back().batch_len); + EXPECT_EQ(expectedBatchStartOffset, mock->execBuffers.back().getBatchStartOffset()); + EXPECT_EQ(expectedSize, mock->execBuffers.back().getBatchLen()); } HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenCheckFlagsWhenFlushingThenSucceeds) { @@ -364,8 +364,8 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenCheckDrmFreeWhenFlushingThenSuccee mock->ioctlTearDownExpected.gemWait = 2; mock->ioctlTearDownExpects = true; - EXPECT_EQ(expectedBatchStartOffset, mock->execBuffers.back().batch_start_offset); - EXPECT_EQ(expectedSize, mock->execBuffers.back().batch_len); + EXPECT_EQ(expectedBatchStartOffset, mock->execBuffers.back().getBatchStartOffset()); + EXPECT_EQ(expectedSize, mock->execBuffers.back().getBatchLen()); } HWTEST_TEMPLATED_F(DrmCommandStreamTest, WhenGettingDrmThenNonNullPointerIsReturned) { @@ -406,8 +406,8 @@ HWTEST_TEMPLATED_F(DrmCommandStreamTest, GivenCheckDrmFreeCloseFailedWhenFlushin mock->ioctlTearDownExpected.gemWait = 2; mock->ioctlTearDownExpects = true; - EXPECT_EQ(expectedBatchStartOffset, mock->execBuffers.back().batch_start_offset); - EXPECT_EQ(expectedSize, mock->execBuffers.back().batch_len); + EXPECT_EQ(expectedBatchStartOffset, mock->execBuffers.back().getBatchStartOffset()); + EXPECT_EQ(expectedSize, mock->execBuffers.back().getBatchLen()); } class DrmCommandStreamBatchingTests : public DrmCommandStreamEnhancedTest { @@ -450,7 +450,7 @@ HWTEST_TEMPLATED_F(DrmCommandStreamBatchingTests, givenCsrWhenFlushIsCalledThenP EXPECT_EQ(ioctlExecCnt, this->mock->ioctl_cnt.execbuffer2); EXPECT_EQ(ioctlUserPtrCnt, this->mock->ioctl_cnt.gemUserptr); uint64_t flags = engineFlag | I915_EXEC_NO_RELOC; - EXPECT_EQ(flags, this->mock->execBuffer.flags); + EXPECT_EQ(flags, this->mock->execBuffer.getFlags()); mm->freeGraphicsMemory(dummyAllocation); mm->freeGraphicsMemory(commandBuffer); @@ -515,7 +515,7 @@ HWTEST_TEMPLATED_F(DrmCommandStreamBatchingTests, givenCsrWhenDispatchPolicyIsSe EXPECT_EQ(ioctlUserPtrCnt, this->mock->ioctl_cnt.total); EXPECT_EQ(ioctlUserPtrCnt, this->mock->ioctl_cnt.gemUserptr); - EXPECT_EQ(0u, this->mock->execBuffer.flags); + EXPECT_EQ(0u, this->mock->execBuffer.getFlags()); csr->flushBatchedSubmissions(); @@ -569,14 +569,14 @@ HWTEST_TEMPLATED_F(DrmCommandStreamBatchingTests, givenRecordedCommandBufferWhen csrSurfaceCount += testedCsr->clearColorAllocation ? 1 : 0; //validate that submited command buffer has what we want - EXPECT_EQ(3u + csrSurfaceCount, this->mock->execBuffer.buffer_count); - EXPECT_EQ(4u, this->mock->execBuffer.batch_start_offset); - EXPECT_EQ(submittedCommandBuffer.getUsed(), this->mock->execBuffer.batch_len); + EXPECT_EQ(3u + csrSurfaceCount, this->mock->execBuffer.getBufferCount()); + EXPECT_EQ(4u, this->mock->execBuffer.getBatchStartOffset()); + EXPECT_EQ(submittedCommandBuffer.getUsed(), this->mock->execBuffer.getBatchLen()); - drm_i915_gem_exec_object2 *exec_objects = (drm_i915_gem_exec_object2 *)this->mock->execBuffer.buffers_ptr; + auto *execObjects = reinterpret_cast(this->mock->execBuffer.getBuffersPtr()); - for (unsigned int i = 0; i < this->mock->execBuffer.buffer_count; i++) { - int handle = exec_objects[i].handle; + for (unsigned int i = 0; i < this->mock->execBuffer.getBufferCount(); i++) { + int handle = execObjects[i].getHandle(); auto handleFound = false; for (auto &graphicsAllocation : copyOfResidency) { 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 0401b179eb..0e555305e9 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 @@ -90,7 +90,7 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, givenTaskThatRequiresLargeResou BatchBuffer batchBuffer{cs.getGraphicsAllocation(), 0, 0, nullptr, false, false, QueueThrottle::MEDIUM, QueueSliceCount::defaultSliceCount, cs.getUsed(), &cs, nullptr, false}; csr->flush(batchBuffer, csr->getResidencyAllocations()); - EXPECT_EQ(11u, this->mock->execBuffer.buffer_count); + EXPECT_EQ(11u, this->mock->execBuffer.getBufferCount()); mm->freeGraphicsMemory(commandBuffer); for (auto graphicsAllocation : graphicsAllocations) { mm->freeGraphicsMemory(graphicsAllocation); diff --git a/opencl/test/unit_test/os_interface/linux/drm_command_stream_xehp_and_later_prelim_tests.cpp b/opencl/test/unit_test/os_interface/linux/drm_command_stream_xehp_and_later_prelim_tests.cpp index 435351457f..ba2f888c2e 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_command_stream_xehp_and_later_prelim_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_command_stream_xehp_and_later_prelim_tests.cpp @@ -475,11 +475,11 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, DrmImplicitScalingCommandStreamTest, givenTwoTilesW EXPECT_EQ(2, drm->ioctlCount.execbuffer2); - EXPECT_EQ(exec0Bos.size(), drm->execBuffers[0].buffer_count); - EXPECT_EQ(exec1Bos.size(), drm->execBuffers[1].buffer_count); + EXPECT_EQ(exec0Bos.size(), drm->execBuffers[0].getBufferCount()); + EXPECT_EQ(exec1Bos.size(), drm->execBuffers[1].getBufferCount()); for (size_t i = 0; i < execBos.size(); i++) { - EXPECT_EQ(static_cast(execBos[i]->peekHandle()), drm->receivedBos[i].handle); + EXPECT_EQ(static_cast(execBos[i]->peekHandle()), drm->receivedBos[i].getHandle()); } memoryManager->freeGraphicsMemory(tileInstancedAllocation); diff --git a/opencl/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp b/opencl/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp index f935a8e4ed..fa403d4ee2 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_memory_manager_tests.cpp @@ -507,7 +507,7 @@ TEST_F(DrmMemoryManagerTest, givenDrmContextIdWhenAllocationIsCreatedThenPinWith EXPECT_NE(0u, drmContextId); auto alloc = memoryManager->allocateGraphicsMemoryWithProperties(createAllocationProperties(rootDeviceIndex, memoryManager->pinThreshold, true)); - EXPECT_EQ(drmContextId, mock->execBuffer.rsvd1); + EXPECT_EQ(drmContextId, mock->execBuffer.getReserved()); memoryManager->freeGraphicsMemory(alloc); } @@ -1127,7 +1127,7 @@ TEST_F(DrmMemoryManagerWithExplicitExpectationsTest, givenEnabledHostMemoryValid auto allocation = memoryManager->allocateGraphicsMemoryForNonSvmHostPtr(allocationData); EXPECT_NE(nullptr, allocation); - EXPECT_EQ(allocation->getGpuAddress() - allocation->getAllocationOffset(), mock->execBufferBufferObjects.offset); + EXPECT_EQ(allocation->getGpuAddress() - allocation->getAllocationOffset(), mock->execBufferBufferObjects.getOffset()); mock->testIoctls(); mock->ioctl_res_ext = &mock->NONE; diff --git a/shared/source/os_interface/linux/drm_buffer_object.cpp b/shared/source/os_interface/linux/drm_buffer_object.cpp index 655897ee4c..79505667dc 100644 --- a/shared/source/os_interface/linux/drm_buffer_object.cpp +++ b/shared/source/os_interface/linux/drm_buffer_object.cpp @@ -128,14 +128,12 @@ int BufferObject::exec(uint32_t used, size_t startOffset, unsigned int flags, bo residency[i]->fillExecObject(execObjectsStorage[i], osContext, vmHandleId, drmContextId); } this->fillExecObject(execObjectsStorage[residencyCount], osContext, vmHandleId, drmContextId); + auto ioctlHelper = drm->getIoctlHelper(); - drm_i915_gem_execbuffer2 execbuf{}; - execbuf.buffers_ptr = reinterpret_cast(execObjectsStorage); - execbuf.buffer_count = static_cast(residencyCount + 1u); - execbuf.batch_start_offset = static_cast(startOffset); - execbuf.batch_len = alignUp(used, 8); - execbuf.flags = flags; - execbuf.rsvd1 = drmContextId; + ExecBuffer execbuf{}; + ioctlHelper->fillExecBuffer(execbuf, reinterpret_cast(execObjectsStorage), + static_cast(residencyCount + 1u), static_cast(startOffset), + alignUp(used, 8), flags, drmContextId); if (DebugManager.flags.PrintExecutionBuffer.get()) { PRINT_DEBUG_STRING(DebugManager.flags.PrintExecutionBuffer.get(), stdout, "Exec called with drmVmId = %u\n", @@ -144,7 +142,6 @@ int BufferObject::exec(uint32_t used, size_t startOffset, unsigned int flags, bo printExecutionBuffer(execbuf, residencyCount, execObjectsStorage, residency); } - auto ioctlHelper = drm->getIoctlHelper(); int ret = ioctlHelper->execBuffer(drm, &execbuf, completionGpuAddress, completionValue); if (ret != 0) { @@ -232,17 +229,10 @@ int BufferObject::unbind(OsContext *osContext, uint32_t vmHandleId) { return retVal; } -void BufferObject::printExecutionBuffer(drm_i915_gem_execbuffer2 &execbuf, const size_t &residencyCount, ExecObject *execObjectsStorage, BufferObject *const residency[]) { +void BufferObject::printExecutionBuffer(ExecBuffer &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) - << ", buffer_count: " + std::to_string(execbuf.buffer_count) - << ", batch_start_offset: " + std::to_string(execbuf.batch_start_offset) - << ", batch_len: " + std::to_string(execbuf.batch_len) - << ", flags: " + std::to_string(execbuf.flags) - << ", rsvd1: " + std::to_string(execbuf.rsvd1) - << " }\n"; + ioctlHelper->logExecBuffer(execbuf, logger); size_t i; for (i = 0; i < residencyCount; i++) { diff --git a/shared/source/os_interface/linux/drm_buffer_object.h b/shared/source/os_interface/linux/drm_buffer_object.h index 369a7a1ffe..82fdae2c15 100644 --- a/shared/source/os_interface/linux/drm_buffer_object.h +++ b/shared/source/os_interface/linux/drm_buffer_object.h @@ -19,11 +19,9 @@ #include #include -struct drm_i915_gem_relocation_entry; -struct drm_i915_gem_execbuffer2; - namespace NEO { +struct ExecBuffer; struct ExecObject; class DrmMemoryManager; class Drm; @@ -52,7 +50,7 @@ class BufferObject { 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, ExecObject *execObjectsStorage, BufferObject *const residency[]); + void printExecutionBuffer(ExecBuffer &execbuf, const size_t &residencyCount, ExecObject *execObjectsStorage, BufferObject *const residency[]); int wait(int64_t timeoutNs); bool close(); diff --git a/shared/source/os_interface/linux/ioctl_helper.cpp b/shared/source/os_interface/linux/ioctl_helper.cpp index 591dfadbae..3c5f424faf 100644 --- a/shared/source/os_interface/linux/ioctl_helper.cpp +++ b/shared/source/os_interface/linux/ioctl_helper.cpp @@ -26,35 +26,60 @@ 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; + 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; + drmExecObject.flags |= EXEC_OBJECT_ASYNC; } if (isMarkedForCapture) { - drmExecObject->flags |= EXEC_OBJECT_CAPTURE; + drmExecObject.flags |= EXEC_OBJECT_CAPTURE; } - drmExecObject->rsvd1 = drmContextId; - drmExecObject->rsvd2 = 0; + drmExecObject.rsvd1 = drmContextId; + drmExecObject.rsvd2 = 0; if (bindInfo) { - drmExecObject->handle = 0u; + 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 + 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"; } + +static_assert(sizeof(ExecBuffer) == sizeof(drm_i915_gem_execbuffer2)); + +void IoctlHelper::fillExecBuffer(ExecBuffer &execBuffer, uintptr_t buffersPtr, uint32_t bufferCount, uint32_t startOffset, uint32_t size, uint64_t flags, uint32_t drmContextId) { + auto &drmExecBuffer = *reinterpret_cast(execBuffer.data); + drmExecBuffer.buffers_ptr = buffersPtr; + drmExecBuffer.buffer_count = bufferCount; + drmExecBuffer.batch_start_offset = startOffset; + drmExecBuffer.batch_len = size; + drmExecBuffer.flags = flags; + drmExecBuffer.rsvd1 = drmContextId; +} + +void IoctlHelper::logExecBuffer(const ExecBuffer &execBuffer, std::stringstream &logger) { + auto &drmExecBuffer = *reinterpret_cast(execBuffer.data); + logger << "drm_i915_gem_execbuffer2 { " + << "buffer_ptr: " + std::to_string(drmExecBuffer.buffers_ptr) + << ", buffer_count: " + std::to_string(drmExecBuffer.buffer_count) + << ", batch_start_offset: " + std::to_string(drmExecBuffer.batch_start_offset) + << ", batch_len: " + std::to_string(drmExecBuffer.batch_len) + << ", flags: " + std::to_string(drmExecBuffer.flags) + << ", rsvd1: " + std::to_string(drmExecBuffer.rsvd1) + << " }\n"; +} + } // namespace NEO diff --git a/shared/source/os_interface/linux/ioctl_helper.h b/shared/source/os_interface/linux/ioctl_helper.h index 1cf0e25b02..bf16a88c2e 100644 --- a/shared/source/os_interface/linux/ioctl_helper.h +++ b/shared/source/os_interface/linux/ioctl_helper.h @@ -19,7 +19,6 @@ struct drm_i915_query_item; struct drm_i915_gem_context_create_ext; -struct drm_i915_gem_execbuffer2; namespace NEO { class Drm; @@ -84,6 +83,10 @@ struct ExecObject { uint8_t data[56]; }; +struct ExecBuffer { + uint8_t data[64]; +}; + class IoctlHelper { public: virtual ~IoctlHelper() {} @@ -114,7 +117,7 @@ class IoctlHelper { virtual uint32_t queryDistances(Drm *drm, std::vector &queryItems, std::vector &distanceInfos) = 0; virtual int32_t getComputeEngineClass() = 0; virtual uint16_t getWaitUserFenceSoftFlag() = 0; - virtual int execBuffer(Drm *drm, drm_i915_gem_execbuffer2 *execBuffer, uint64_t completionGpuAddress, uint32_t counterValue) = 0; + virtual int execBuffer(Drm *drm, ExecBuffer *execBuffer, uint64_t completionGpuAddress, uint32_t counterValue) = 0; virtual bool completionFenceExtensionSupported(const HardwareInfo &hwInfo, const bool isVmBindAvailable) = 0; virtual std::optional getHasPageFaultParamId() = 0; virtual std::unique_ptr createVmControlExtRegion(const std::optional ®ionInstanceClass) = 0; @@ -139,6 +142,9 @@ class IoctlHelper { 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); + + void fillExecBuffer(ExecBuffer &execBuffer, uintptr_t buffersPtr, uint32_t bufferCount, uint32_t startOffset, uint32_t size, uint64_t flags, uint32_t drmContextId); + void logExecBuffer(const ExecBuffer &execBuffer, std::stringstream &logger); }; class IoctlHelperUpstream : public IoctlHelper { @@ -168,7 +174,7 @@ class IoctlHelperUpstream : public IoctlHelper { uint32_t queryDistances(Drm *drm, std::vector &queryItems, std::vector &distanceInfos) override; int32_t getComputeEngineClass() override; uint16_t getWaitUserFenceSoftFlag() override; - int execBuffer(Drm *drm, drm_i915_gem_execbuffer2 *execBuffer, uint64_t completionGpuAddress, uint32_t counterValue) override; + int execBuffer(Drm *drm, ExecBuffer *execBuffer, uint64_t completionGpuAddress, uint32_t counterValue) override; bool completionFenceExtensionSupported(const HardwareInfo &hwInfo, const bool isVmBindAvailable) override; std::optional getHasPageFaultParamId() override; std::unique_ptr createVmControlExtRegion(const std::optional ®ionInstanceClass) override; @@ -232,7 +238,7 @@ class IoctlHelperPrelim20 : public IoctlHelper { uint32_t queryDistances(Drm *drm, std::vector &queryItems, std::vector &distanceInfos) override; int32_t getComputeEngineClass() override; uint16_t getWaitUserFenceSoftFlag() override; - int execBuffer(Drm *drm, drm_i915_gem_execbuffer2 *execBuffer, uint64_t completionGpuAddress, uint32_t counterValue) override; + int execBuffer(Drm *drm, ExecBuffer *execBuffer, uint64_t completionGpuAddress, uint32_t counterValue) override; bool completionFenceExtensionSupported(const HardwareInfo &hwInfo, const bool isVmBindAvailable) override; std::optional getHasPageFaultParamId() override; std::unique_ptr createVmControlExtRegion(const std::optional ®ionInstanceClass) override; diff --git a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp index 2a11d58585..4086815b8c 100644 --- a/shared/source/os_interface/linux/ioctl_helper_prelim.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_prelim.cpp @@ -235,16 +235,17 @@ uint16_t IoctlHelperPrelim20::getWaitUserFenceSoftFlag() { return PRELIM_I915_UFENCE_WAIT_SOFT; }; -int IoctlHelperPrelim20::execBuffer(Drm *drm, drm_i915_gem_execbuffer2 *execBuffer, uint64_t completionGpuAddress, uint32_t counterValue) { +int IoctlHelperPrelim20::execBuffer(Drm *drm, ExecBuffer *execBuffer, uint64_t completionGpuAddress, uint32_t counterValue) { prelim_drm_i915_gem_execbuffer_ext_user_fence fenceObject = {}; if (completionGpuAddress != 0) { fenceObject.base.name = PRELIM_DRM_I915_GEM_EXECBUFFER_EXT_USER_FENCE; fenceObject.addr = completionGpuAddress; fenceObject.value = counterValue; - execBuffer->flags |= I915_EXEC_USE_EXTENSIONS; - execBuffer->num_cliprects = 0; - execBuffer->cliprects_ptr = castToUint64(&fenceObject); + auto &drmExecBuffer = *reinterpret_cast(execBuffer->data); + drmExecBuffer.flags |= I915_EXEC_USE_EXTENSIONS; + drmExecBuffer.num_cliprects = 0; + drmExecBuffer.cliprects_ptr = castToUint64(&fenceObject); } return IoctlHelper::ioctl(drm, DRM_IOCTL_I915_GEM_EXECBUFFER2, execBuffer); diff --git a/shared/source/os_interface/linux/ioctl_helper_upstream.cpp b/shared/source/os_interface/linux/ioctl_helper_upstream.cpp index 4514f67298..ad67fba3df 100644 --- a/shared/source/os_interface/linux/ioctl_helper_upstream.cpp +++ b/shared/source/os_interface/linux/ioctl_helper_upstream.cpp @@ -159,7 +159,7 @@ uint16_t IoctlHelperUpstream::getWaitUserFenceSoftFlag() { return 0; } -int IoctlHelperUpstream::execBuffer(Drm *drm, drm_i915_gem_execbuffer2 *execBuffer, uint64_t completionGpuAddress, uint32_t counterValue) { +int IoctlHelperUpstream::execBuffer(Drm *drm, ExecBuffer *execBuffer, uint64_t completionGpuAddress, uint32_t counterValue) { return ioctl(drm, DRM_IOCTL_I915_GEM_EXECBUFFER2, execBuffer); } diff --git a/shared/test/common/libult/linux/drm_mock.cpp b/shared/test/common/libult/linux/drm_mock.cpp index 0582327537..2498a380ae 100644 --- a/shared/test/common/libult/linux/drm_mock.cpp +++ b/shared/test/common/libult/linux/drm_mock.cpp @@ -156,10 +156,10 @@ int DrmMock::ioctl(unsigned long request, void *arg) { if (request == DRM_IOCTL_I915_GEM_EXECBUFFER2) { ioctlCount.execbuffer2++; - auto execbuf = static_cast(arg); - auto execObjects = reinterpret_cast(execbuf->buffers_ptr); + auto execbuf = static_cast(arg); + auto execObjects = reinterpret_cast(execbuf->getBuffersPtr()); this->execBuffers.push_back(*execbuf); - for (uint32_t i = 0; i < execbuf->buffer_count; i++) { + for (uint32_t i = 0; i < execbuf->getBufferCount(); i++) { this->receivedBos.push_back(execObjects[i]); } return 0; diff --git a/shared/test/common/libult/linux/drm_mock.h b/shared/test/common/libult/linux/drm_mock.h index cb4852d1fc..3ba3338724 100644 --- a/shared/test/common/libult/linux/drm_mock.h +++ b/shared/test/common/libult/linux/drm_mock.h @@ -12,6 +12,7 @@ #include "shared/source/helpers/string.h" #include "shared/source/os_interface/linux/drm_neo.h" #include "shared/test/common/helpers/default_hw_info.h" +#include "shared/test/common/mocks/linux/mock_drm_wrappers.h" #include "shared/test/common/os_interface/linux/device_command_stream_fixture.h" #include "gtest/gtest.h" @@ -209,8 +210,8 @@ class DrmMock : public Drm { bool queryPageFaultSupportCalled = false; //DRM_IOCTL_I915_GEM_EXECBUFFER2 - std::vector execBuffers{}; - std::vector receivedBos{}; + std::vector execBuffers{}; + std::vector receivedBos{}; //DRM_IOCTL_I915_GEM_CREATE __u64 createParamsSize = 0; __u32 createParamsHandle = 0; diff --git a/shared/test/common/mocks/linux/mock_drm_wrappers.cpp b/shared/test/common/mocks/linux/mock_drm_wrappers.cpp index 365ceb0a22..983f5e940f 100644 --- a/shared/test/common/mocks/linux/mock_drm_wrappers.cpp +++ b/shared/test/common/mocks/linux/mock_drm_wrappers.cpp @@ -7,28 +7,68 @@ #include "shared/test/common/mocks/linux/mock_drm_wrappers.h" +#include "shared/source/helpers/bit_helpers.h" + #include "drm/i915_drm.h" namespace NEO { uint32_t MockExecObject::getHandle() const { - auto drmExecObject = reinterpret_cast(this->data); - return drmExecObject->handle; + auto &drmExecObject = *reinterpret_cast(this->data); + return drmExecObject.handle; } uint64_t MockExecObject::getOffset() const { - auto drmExecObject = reinterpret_cast(this->data); - return drmExecObject->offset; + auto &drmExecObject = *reinterpret_cast(this->data); + return drmExecObject.offset; +} +uint64_t MockExecObject::getReserved() const { + auto &drmExecObject = *reinterpret_cast(this->data); + return drmExecObject.rsvd1; } bool MockExecObject::has48BAddressSupportFlag() const { - auto drmExecObject = reinterpret_cast(this->data); - return drmExecObject->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS; + auto &drmExecObject = *reinterpret_cast(this->data); + return isValueSet(drmExecObject.flags, EXEC_OBJECT_SUPPORTS_48B_ADDRESS); } bool MockExecObject::hasCaptureFlag() const { - auto drmExecObject = reinterpret_cast(this->data); - return drmExecObject->flags & EXEC_OBJECT_CAPTURE; + auto &drmExecObject = *reinterpret_cast(this->data); + return isValueSet(drmExecObject.flags, EXEC_OBJECT_CAPTURE); } bool MockExecObject::hasAsyncFlag() const { - auto drmExecObject = reinterpret_cast(this->data); - return drmExecObject->flags & EXEC_OBJECT_ASYNC; + auto &drmExecObject = *reinterpret_cast(this->data); + return isValueSet(drmExecObject.flags, EXEC_OBJECT_ASYNC); } + +uint64_t MockExecBuffer::getBuffersPtr() const { + auto &drmExecBuffer = *reinterpret_cast(this->data); + return drmExecBuffer.buffers_ptr; +} +uint32_t MockExecBuffer::getBufferCount() const { + auto &drmExecBuffer = *reinterpret_cast(this->data); + return drmExecBuffer.buffer_count; +} +uint32_t MockExecBuffer::getBatchLen() const { + auto &drmExecBuffer = *reinterpret_cast(this->data); + return drmExecBuffer.batch_len; +} +uint32_t MockExecBuffer::getBatchStartOffset() const { + auto &drmExecBuffer = *reinterpret_cast(this->data); + return drmExecBuffer.batch_start_offset; +} +uint64_t MockExecBuffer::getFlags() const { + auto &drmExecBuffer = *reinterpret_cast(this->data); + return drmExecBuffer.flags; +} +uint64_t MockExecBuffer::getCliprectsPtr() const { + auto &drmExecBuffer = *reinterpret_cast(this->data); + return drmExecBuffer.cliprects_ptr; +} +uint64_t MockExecBuffer::getReserved() const { + auto &drmExecBuffer = *reinterpret_cast(this->data); + return drmExecBuffer.rsvd1; +} +bool MockExecBuffer::hasUseExtensionsFlag() const { + auto &drmExecBuffer = *reinterpret_cast(this->data); + return isValueSet(drmExecBuffer.flags, I915_EXEC_USE_EXTENSIONS); +} + } // namespace NEO diff --git a/shared/test/common/mocks/linux/mock_drm_wrappers.h b/shared/test/common/mocks/linux/mock_drm_wrappers.h index 7f9e39c013..36f4ea0506 100644 --- a/shared/test/common/mocks/linux/mock_drm_wrappers.h +++ b/shared/test/common/mocks/linux/mock_drm_wrappers.h @@ -13,10 +13,25 @@ namespace NEO { struct MockExecObject : ExecObject { uint32_t getHandle() const; uint64_t getOffset() const; + uint64_t getReserved() const; + bool has48BAddressSupportFlag() const; bool hasCaptureFlag() const; bool hasAsyncFlag() const; }; - static_assert(sizeof(MockExecObject) == sizeof(ExecObject)); + +struct MockExecBuffer : ExecBuffer { + uint64_t getBuffersPtr() const; + uint32_t getBufferCount() const; + uint32_t getBatchLen() const; + uint32_t getBatchStartOffset() const; + uint64_t getFlags() const; + uint64_t getCliprectsPtr() const; + uint64_t getReserved() const; + + bool hasUseExtensionsFlag() const; +}; +static_assert(sizeof(MockExecBuffer) == sizeof(ExecBuffer)); + } // namespace NEO diff --git a/shared/test/common/os_interface/linux/device_command_stream_fixture.cpp b/shared/test/common/os_interface/linux/device_command_stream_fixture.cpp index 6bd07d31f6..e5fdebd2d9 100644 --- a/shared/test/common/os_interface/linux/device_command_stream_fixture.cpp +++ b/shared/test/common/os_interface/linux/device_command_stream_fixture.cpp @@ -69,10 +69,10 @@ int DrmMockCustom::ioctl(unsigned long request, void *arg) { //store flags switch (request) { case DRM_IOCTL_I915_GEM_EXECBUFFER2: { - drm_i915_gem_execbuffer2 *execbuf = (drm_i915_gem_execbuffer2 *)arg; + auto execbuf = static_cast(arg); this->execBuffer = *execbuf; this->execBufferBufferObjects = - *reinterpret_cast(this->execBuffer.buffers_ptr); + *reinterpret_cast(this->execBuffer.getBuffersPtr()); ioctl_cnt.execbuffer2++; execBufferExtensions(execbuf); } break; diff --git a/shared/test/common/os_interface/linux/device_command_stream_fixture.h b/shared/test/common/os_interface/linux/device_command_stream_fixture.h index 720d0363e6..02c66f749b 100644 --- a/shared/test/common/os_interface/linux/device_command_stream_fixture.h +++ b/shared/test/common/os_interface/linux/device_command_stream_fixture.h @@ -11,6 +11,7 @@ #include "shared/source/os_interface/linux/drm_memory_manager.h" #include "shared/source/os_interface/linux/drm_neo.h" #include "shared/test/common/helpers/default_hw_info.h" +#include "shared/test/common/mocks/linux/mock_drm_wrappers.h" #include "engine_node.h" #include "gtest/gtest.h" @@ -161,10 +162,10 @@ class DrmMockCustom : public Drm { std::atomic ioctl_res_ext; //DRM_IOCTL_I915_GEM_EXECBUFFER2 - drm_i915_gem_execbuffer2 execBuffer = {0}; + NEO::MockExecBuffer execBuffer{}; //First exec object - drm_i915_gem_exec_object2 execBufferBufferObjects = {0}; + NEO::MockExecObject execBufferBufferObjects{}; //DRM_IOCTL_I915_GEM_CREATE __u64 createParamsSize = 0;