From 21e16ff2c526eb0af434926b163bc575e148508b Mon Sep 17 00:00:00 2001 From: Lukasz Jobczyk Date: Fri, 17 Jul 2020 11:28:59 +0200 Subject: [PATCH] Add initial implementation of Linux direct submission Change-Id: I9ee0434897bc3e980b240a8373190f0803e6c102 Signed-off-by: Lukasz Jobczyk --- .../os_interface/linux/drm_command_stream.inl | 5 ++ .../windows/wddm_device_command_stream.h | 2 - .../windows/wddm_device_command_stream.inl | 39 ------------ .../linux/drm_command_stream_tests.cpp | 35 +++++++++++ .../command_stream_receiver_hw.h | 2 + .../command_stream_receiver_hw_base.inl | 37 +++++++++++ .../direct_submission/direct_submission_hw.h | 8 ++- .../direct_submission_hw.inl | 33 +++++++++- .../linux/drm_direct_submission.h | 6 +- .../linux/drm_direct_submission.inl | 52 +++++++++++++-- .../windows/wddm_direct_submission.h | 4 +- .../windows/wddm_direct_submission.inl | 29 +++------ .../direct_submission_tests.cpp | 2 + .../linux/drm_direct_submission_tests.cpp | 63 +++++++++++++------ .../windows/wddm_direct_submission_tests.cpp | 55 +++------------- .../mocks/mock_direct_submission_hw.h | 16 ++--- .../windows/mock_wddm_direct_submission.h | 1 + 17 files changed, 237 insertions(+), 152 deletions(-) diff --git a/opencl/source/os_interface/linux/drm_command_stream.inl b/opencl/source/os_interface/linux/drm_command_stream.inl index 631efacbca..8e6dcb8d58 100644 --- a/opencl/source/os_interface/linux/drm_command_stream.inl +++ b/opencl/source/os_interface/linux/drm_command_stream.inl @@ -6,6 +6,7 @@ */ #include "shared/source/command_stream/linear_stream.h" +#include "shared/source/direct_submission/linux/drm_direct_submission.h" #include "shared/source/execution_environment/execution_environment.h" #include "shared/source/gmm_helper/gmm_helper.h" #include "shared/source/gmm_helper/page_table_mngr.h" @@ -72,6 +73,10 @@ bool DrmCommandStreamReceiver::flush(BatchBuffer &batchBuffer, Reside auto lock = memoryOperationsInterface->lockHandlerForExecWA(); memoryOperationsInterface->mergeWithResidencyContainer(this->osContext, allocationsForResidency); + if (this->directSubmission.get()) { + return this->directSubmission->dispatchCommandBuffer(batchBuffer, *this->flushStamp.get()); + } + this->flushStamp->setStamp(bb->peekHandle()); this->flushInternal(batchBuffer, allocationsForResidency); diff --git a/opencl/source/os_interface/windows/wddm_device_command_stream.h b/opencl/source/os_interface/windows/wddm_device_command_stream.h index f9210aebb7..d1e4da9818 100644 --- a/opencl/source/os_interface/windows/wddm_device_command_stream.h +++ b/opencl/source/os_interface/windows/wddm_device_command_stream.h @@ -35,8 +35,6 @@ class WddmCommandStreamReceiver : public DeviceCommandStreamReceiver } GmmPageTableMngr *createPageTableManager() override; - bool initDirectSubmission(Device &device, OsContext &osContext) override; - protected: void kmDafLockAllocations(ResidencyContainer &allocationsForResidency); diff --git a/opencl/source/os_interface/windows/wddm_device_command_stream.inl b/opencl/source/os_interface/windows/wddm_device_command_stream.inl index c7193f17bb..1a2ccb7adc 100644 --- a/opencl/source/os_interface/windows/wddm_device_command_stream.inl +++ b/opencl/source/os_interface/windows/wddm_device_command_stream.inl @@ -155,43 +155,4 @@ void WddmCommandStreamReceiver::kmDafLockAllocations(ResidencyContain } } -template -bool WddmCommandStreamReceiver::initDirectSubmission(Device &device, OsContext &osContext) { - bool ret = true; - - if (DebugManager.flags.EnableDirectSubmission.get() == 1) { - auto contextEngineType = osContext.getEngineType(); - const DirectSubmissionProperties &directSubmissionProperty = - device.getHardwareInfo().capabilityTable.directSubmissionEngines.data[contextEngineType]; - - bool startDirect = true; - if (!osContext.isDefaultContext()) { - startDirect = directSubmissionProperty.useNonDefault; - } - if (osContext.isLowPriority()) { - startDirect = directSubmissionProperty.useLowPriority; - } - if (osContext.isInternalEngine()) { - startDirect = directSubmissionProperty.useInternal; - } - if (osContext.isRootDevice()) { - startDirect = directSubmissionProperty.useRootDevice; - } - - if (directSubmissionProperty.engineSupported && startDirect) { - if (contextEngineType == aub_stream::ENGINE_BCS) { - blitterDirectSubmission = std::make_unique< - WddmDirectSubmission>>(device, osContext); - ret = blitterDirectSubmission->initialize(directSubmissionProperty.submitOnInit); - } else { - directSubmission = std::make_unique< - WddmDirectSubmission>>(device, osContext); - ret = directSubmission->initialize(directSubmissionProperty.submitOnInit); - this->dispatchMode = DispatchMode::ImmediateDispatch; - } - } - } - return ret; -} - } // namespace NEO diff --git a/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests.cpp b/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests.cpp index 66e2671c7a..5a0cd6eb55 100644 --- a/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests.cpp +++ b/opencl/test/unit_test/os_interface/linux/drm_command_stream_tests.cpp @@ -1287,6 +1287,41 @@ HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, FlushNotAligned) { csr->flush(batchBuffer, csr->getResidencyAllocations()); } +struct DrmCommandStreamDirectSubmissionTest : public DrmCommandStreamEnhancedTest { + + template + void SetUpT() { + DebugManager.flags.EnableDirectSubmission.set(1u); + DrmCommandStreamEnhancedTest::SetUpT(); + auto hwInfo = device->getRootDeviceEnvironment().getMutableHardwareInfo(); + auto engineType = device->getDefaultEngine().osContext->getEngineType(); + hwInfo->capabilityTable.directSubmissionEngines.data[engineType].engineSupported = true; + csr->initDirectSubmission(*device.get(), *device->getDefaultEngine().osContext); + } + + template + void TearDownT() { + this->dbgState.reset(); + DrmCommandStreamEnhancedTest::TearDownT(); + } + + DebugManagerStateRestore restorer; +}; + +HWTEST_TEMPLATED_F(DrmCommandStreamDirectSubmissionTest, givenEnabledDirectSubmissionWhenFlushThenFlushStampIsNotUpdated) { + auto &cs = csr->getCS(); + CommandStreamReceiverHw::addBatchBufferEnd(cs, nullptr); + CommandStreamReceiverHw::alignToCacheLine(cs); + BatchBuffer batchBuffer{cs.getGraphicsAllocation(), 4, 0, nullptr, false, false, QueueThrottle::MEDIUM, QueueSliceCount::defaultSliceCount, cs.getUsed(), &cs, nullptr}; + uint8_t bbStart[64]; + batchBuffer.endCmdPtr = &bbStart[0]; + + auto flushStamp = csr->obtainCurrentFlushStamp(); + csr->flush(batchBuffer, csr->getResidencyAllocations()); + + EXPECT_EQ(csr->obtainCurrentFlushStamp(), flushStamp); +} + HWTEST_TEMPLATED_F(DrmCommandStreamEnhancedTest, CheckDrmFree) { auto &cs = csr->getCS(); auto commandBuffer = static_cast(cs.getGraphicsAllocation()); diff --git a/shared/source/command_stream/command_stream_receiver_hw.h b/shared/source/command_stream/command_stream_receiver_hw.h index 5428f5c8b4..7aaa1a2740 100644 --- a/shared/source/command_stream/command_stream_receiver_hw.h +++ b/shared/source/command_stream/command_stream_receiver_hw.h @@ -97,6 +97,8 @@ class CommandStreamReceiverHw : public CommandStreamReceiver { return blitterDirectSubmission.get() != nullptr; } + bool initDirectSubmission(Device &device, OsContext &osContext) override; + protected: void programPreemption(LinearStream &csr, DispatchFlags &dispatchFlags); void programL3(LinearStream &csr, DispatchFlags &dispatchFlags, uint32_t &newL3Config); diff --git a/shared/source/command_stream/command_stream_receiver_hw_base.inl b/shared/source/command_stream/command_stream_receiver_hw_base.inl index 2df6614b4b..ce2f4797f8 100644 --- a/shared/source/command_stream/command_stream_receiver_hw_base.inl +++ b/shared/source/command_stream/command_stream_receiver_hw_base.inl @@ -1029,4 +1029,41 @@ inline size_t CommandStreamReceiverHw::getCmdSizeForPrologue() const return 0u; } +template +inline bool CommandStreamReceiverHw::initDirectSubmission(Device &device, OsContext &osContext) { + bool ret = true; + + if (DebugManager.flags.EnableDirectSubmission.get() == 1) { + auto contextEngineType = osContext.getEngineType(); + const DirectSubmissionProperties &directSubmissionProperty = + device.getHardwareInfo().capabilityTable.directSubmissionEngines.data[contextEngineType]; + + bool startDirect = true; + if (!osContext.isDefaultContext()) { + startDirect = directSubmissionProperty.useNonDefault; + } + if (osContext.isLowPriority()) { + startDirect = directSubmissionProperty.useLowPriority; + } + if (osContext.isInternalEngine()) { + startDirect = directSubmissionProperty.useInternal; + } + if (osContext.isRootDevice()) { + startDirect = directSubmissionProperty.useRootDevice; + } + + if (directSubmissionProperty.engineSupported && startDirect) { + if (contextEngineType == aub_stream::ENGINE_BCS) { + blitterDirectSubmission = DirectSubmissionHw>::create(device, osContext); + ret = blitterDirectSubmission->initialize(directSubmissionProperty.submitOnInit); + } else { + directSubmission = DirectSubmissionHw>::create(device, osContext); + ret = directSubmission->initialize(directSubmissionProperty.submitOnInit); + this->dispatchMode = DispatchMode::ImmediateDispatch; + } + } + } + return ret; +} + } // namespace NEO diff --git a/shared/source/direct_submission/direct_submission_hw.h b/shared/source/direct_submission/direct_submission_hw.h index e6b8423054..d796b03704 100644 --- a/shared/source/direct_submission/direct_submission_hw.h +++ b/shared/source/direct_submission/direct_submission_hw.h @@ -59,15 +59,19 @@ class DirectSubmissionHw { bool dispatchCommandBuffer(BatchBuffer &batchBuffer, FlushStampTracker &flushStamp); + static std::unique_ptr> create(Device &device, OsContext &osContext); + protected: static constexpr size_t prefetchSize = 8 * MemoryConstants::cacheLineSize; static constexpr size_t prefetchNoops = prefetchSize / sizeof(uint32_t); bool allocateResources(); void deallocateResources(); - virtual bool allocateOsResources(DirectSubmissionAllocations &allocations) = 0; + MOCKABLE_VIRTUAL bool makeResourcesResident(DirectSubmissionAllocations &allocations); + virtual bool allocateOsResources() = 0; virtual bool submit(uint64_t gpuAddress, size_t size) = 0; virtual bool handleResidency() = 0; - virtual uint64_t switchRingBuffers() = 0; + virtual uint64_t switchRingBuffers(); + virtual void handleSwitchRingBuffers() = 0; GraphicsAllocation *switchRingBuffersAllocations(); virtual uint64_t updateTagValue() = 0; virtual void getTagAddressValue(TagData &tagData) = 0; diff --git a/shared/source/direct_submission/direct_submission_hw.inl b/shared/source/direct_submission/direct_submission_hw.inl index 201482052a..f26fe659c7 100644 --- a/shared/source/direct_submission/direct_submission_hw.inl +++ b/shared/source/direct_submission/direct_submission_hw.inl @@ -16,6 +16,7 @@ #include "shared/source/memory_manager/allocation_properties.h" #include "shared/source/memory_manager/graphics_allocation.h" #include "shared/source/memory_manager/memory_manager.h" +#include "shared/source/memory_manager/memory_operations_handler.h" #include "shared/source/os_interface/os_context.h" #include "shared/source/utilities/cpu_info.h" #include "shared/source/utilities/cpuintrinsics.h" @@ -87,7 +88,18 @@ bool DirectSubmissionHw::allocateResources() { cpuCachelineFlush(semaphorePtr, MemoryConstants::cacheLineSize); workloadModeOneStoreAddress = static_cast(&semaphoreData->Reserved1Uint32); *static_cast(workloadModeOneStoreAddress) = 0u; - return allocateOsResources(allocations); + + auto ret = makeResourcesResident(allocations); + + return ret && allocateOsResources(); +} + +template +bool DirectSubmissionHw::makeResourcesResident(DirectSubmissionAllocations &allocations) { + auto memoryInterface = this->device.getRootDeviceEnvironment().memoryOperationsInterface.get(); + auto ret = memoryInterface->makeResident(&device, ArrayRef(allocations)) == MemoryOperationsStatus::SUCCESS; + + return ret; } template @@ -337,6 +349,25 @@ inline void DirectSubmissionHw::setReturnAddress(void *re *returnBBStart = cmd; } +template +inline uint64_t DirectSubmissionHw::switchRingBuffers() { + GraphicsAllocation *nextRingBuffer = switchRingBuffersAllocations(); + void *flushPtr = ringCommandStream.getSpace(0); + uint64_t currentBufferGpuVa = getCommandBufferPositionGpuAddress(flushPtr); + + if (ringStart) { + dispatchSwitchRingBufferSection(nextRingBuffer->getGpuAddress()); + cpuCachelineFlush(flushPtr, getSizeSwitchRingBufferSection()); + } + + ringCommandStream.replaceBuffer(nextRingBuffer->getUnderlyingBuffer(), ringCommandStream.getMaxAvailableSpace()); + ringCommandStream.replaceGraphicsAllocation(nextRingBuffer); + + handleSwitchRingBuffers(); + + return currentBufferGpuVa; +} + template inline GraphicsAllocation *DirectSubmissionHw::switchRingBuffersAllocations() { GraphicsAllocation *nextAllocation = nullptr; diff --git a/shared/source/direct_submission/linux/drm_direct_submission.h b/shared/source/direct_submission/linux/drm_direct_submission.h index 6a4f8021a4..137d938001 100644 --- a/shared/source/direct_submission/linux/drm_direct_submission.h +++ b/shared/source/direct_submission/linux/drm_direct_submission.h @@ -19,12 +19,14 @@ class DrmDirectSubmission : public DirectSubmissionHw { DrmDirectSubmission(Device &device, OsContext &osContext); + ~DrmDirectSubmission(); + protected: - bool allocateOsResources(DirectSubmissionAllocations &allocations) override; + bool allocateOsResources() override; bool submit(uint64_t gpuAddress, size_t size) override; bool handleResidency() override; - uint64_t switchRingBuffers() override; + void handleSwitchRingBuffers() override; uint64_t updateTagValue() override; void getTagAddressValue(TagData &tagData) override; }; diff --git a/shared/source/direct_submission/linux/drm_direct_submission.inl b/shared/source/direct_submission/linux/drm_direct_submission.inl index 94a2f7bd07..edf41908a3 100644 --- a/shared/source/direct_submission/linux/drm_direct_submission.inl +++ b/shared/source/direct_submission/linux/drm_direct_submission.inl @@ -8,33 +8,73 @@ #include "shared/source/command_stream/linear_stream.h" #include "shared/source/direct_submission/linux/drm_direct_submission.h" #include "shared/source/os_interface/linux/drm_allocation.h" +#include "shared/source/os_interface/linux/drm_buffer_object.h" +#include "shared/source/os_interface/linux/drm_neo.h" +#include "shared/source/os_interface/linux/os_context_linux.h" + +#include namespace NEO { +template +inline std::unique_ptr> DirectSubmissionHw::create(Device &device, OsContext &osContext) { + return std::make_unique>(device, osContext); +} + template DrmDirectSubmission::DrmDirectSubmission(Device &device, OsContext &osContext) : DirectSubmissionHw(device, osContext) { + this->disableMonitorFence = true; } template -bool DrmDirectSubmission::allocateOsResources(DirectSubmissionAllocations &allocations) { - return false; +inline DrmDirectSubmission::~DrmDirectSubmission() { + if (this->ringStart) { + this->stopRingBuffer(); + auto bb = static_cast(this->ringCommandStream.getGraphicsAllocation())->getBO(); + bb->wait(-1); + } + this->deallocateResources(); +} + +template +bool DrmDirectSubmission::allocateOsResources() { + return true; } template bool DrmDirectSubmission::submit(uint64_t gpuAddress, size_t size) { - return false; + auto bb = static_cast(this->ringCommandStream.getGraphicsAllocation())->getBO(); + + auto osContextLinux = static_cast(&this->osContext); + auto execFlags = osContextLinux->getEngineFlag() | I915_EXEC_NO_RELOC; + auto &drmContextIds = osContextLinux->getDrmContextIds(); + + drm_i915_gem_exec_object2 execObject{}; + + bool ret = false; + for (const auto &drmContextId : drmContextIds) { + ret |= bb->exec(static_cast(size), + 0, + execFlags, + false, + drmContextId, + nullptr, + 0, + &execObject); + } + + return !ret; } template bool DrmDirectSubmission::handleResidency() { - return false; + return true; } template -uint64_t DrmDirectSubmission::switchRingBuffers() { - return 0ull; +void DrmDirectSubmission::handleSwitchRingBuffers() { } template diff --git a/shared/source/direct_submission/windows/wddm_direct_submission.h b/shared/source/direct_submission/windows/wddm_direct_submission.h index fa9ebcd6e2..5117b90230 100644 --- a/shared/source/direct_submission/windows/wddm_direct_submission.h +++ b/shared/source/direct_submission/windows/wddm_direct_submission.h @@ -25,12 +25,12 @@ class WddmDirectSubmission : public DirectSubmissionHw { ~WddmDirectSubmission(); protected: - bool allocateOsResources(DirectSubmissionAllocations &allocations) override; + bool allocateOsResources() override; bool submit(uint64_t gpuAddress, size_t size) override; bool handleResidency() override; void handleCompletionRingBuffer(uint64_t completionValue, MonitoredFence &fence); - uint64_t switchRingBuffers() override; + void handleSwitchRingBuffers() override; uint64_t updateTagValue() override; void getTagAddressValue(TagData &tagData) override; diff --git a/shared/source/direct_submission/windows/wddm_direct_submission.inl b/shared/source/direct_submission/windows/wddm_direct_submission.inl index abbcae1e9b..d46fc25d46 100644 --- a/shared/source/direct_submission/windows/wddm_direct_submission.inl +++ b/shared/source/direct_submission/windows/wddm_direct_submission.inl @@ -21,6 +21,11 @@ namespace NEO { // Initialize COMMAND_BUFFER_HEADER Type PatchList Streamer Perf Tag DECLARE_COMMAND_BUFFER(CommandBufferHeader, UMD_OCL, FALSE, FALSE, PERFTAG_OCL); +template +inline std::unique_ptr> DirectSubmissionHw::create(Device &device, OsContext &osContext) { + return std::make_unique>(device, osContext); +} + template WddmDirectSubmission::WddmDirectSubmission(Device &device, OsContext &osContext) @@ -49,18 +54,12 @@ WddmDirectSubmission::~WddmDirectSubmission() { } template -bool WddmDirectSubmission::allocateOsResources(DirectSubmissionAllocations &allocations) { +bool WddmDirectSubmission::allocateOsResources() { //for now only WDDM2.0 UNRECOVERABLE_IF(wddm->getWddmVersion() != WddmVersion::WDDM_2_0); - WddmMemoryOperationsHandler *memoryInterface = - static_cast(device.getRootDeviceEnvironment().memoryOperationsInterface.get()); - bool ret = wddm->getWddmInterface()->createMonitoredFence(ringFence); ringFence.currentFenceValue = 1; - if (ret) { - ret = memoryInterface->makeResident(&device, ArrayRef(allocations)) == MemoryOperationsStatus::SUCCESS; - } perfLogResidencyVariadicLog(wddm->getResidencyLogger(), "ULLS resource allocation finished with: %d\n", ret); return ret; } @@ -93,27 +92,13 @@ bool WddmDirectSubmission::handleResidency() { } template -uint64_t WddmDirectSubmission::switchRingBuffers() { - GraphicsAllocation *nextRingBuffer = switchRingBuffersAllocations(); - void *flushPtr = ringCommandStream.getSpace(0); - uint64_t currentBufferGpuVa = getCommandBufferPositionGpuAddress(flushPtr); - - if (ringStart) { - dispatchSwitchRingBufferSection(nextRingBuffer->getGpuAddress()); - cpuCachelineFlush(flushPtr, getSizeSwitchRingBufferSection()); - } - - ringCommandStream.replaceBuffer(nextRingBuffer->getUnderlyingBuffer(), ringCommandStream.getMaxAvailableSpace()); - ringCommandStream.replaceGraphicsAllocation(nextRingBuffer); - +void WddmDirectSubmission::handleSwitchRingBuffers() { if (ringStart) { if (completionRingBuffers[currentRingBuffer] != 0) { MonitoredFence ¤tFence = osContextWin->getResidencyController().getMonitoredFence(); handleCompletionRingBuffer(completionRingBuffers[currentRingBuffer], currentFence); } } - - return currentBufferGpuVa; } template diff --git a/shared/test/unit_test/direct_submission/direct_submission_tests.cpp b/shared/test/unit_test/direct_submission/direct_submission_tests.cpp index c3ca92b280..600d910148 100644 --- a/shared/test/unit_test/direct_submission/direct_submission_tests.cpp +++ b/shared/test/unit_test/direct_submission/direct_submission_tests.cpp @@ -9,6 +9,7 @@ #include "shared/source/debug_settings/debug_settings_manager.h" #include "shared/source/direct_submission/dispatchers/render_dispatcher.h" #include "shared/source/helpers/flush_stamp.h" +#include "shared/source/os_interface/device_factory.h" #include "shared/source/os_interface/os_context.h" #include "shared/test/unit_test/cmd_parse/hw_parse.h" #include "shared/test/unit_test/fixtures/device_fixture.h" @@ -33,6 +34,7 @@ extern std::atomic lastClFlushedPtr; struct DirectSubmissionFixture : public DeviceFixture { void SetUp() { DeviceFixture::SetUp(); + DeviceFactory::prepareDeviceEnvironments(*pDevice->getExecutionEnvironment()); osContext.reset(OsContext::create(nullptr, 0u, pDevice->getDeviceBitfield(), aub_stream::ENGINE_RCS, PreemptionMode::ThreadGroup, false, false, false)); diff --git a/shared/test/unit_test/direct_submission/linux/drm_direct_submission_tests.cpp b/shared/test/unit_test/direct_submission/linux/drm_direct_submission_tests.cpp index 42bb9dcb5b..6f3fb62cb7 100644 --- a/shared/test/unit_test/direct_submission/linux/drm_direct_submission_tests.cpp +++ b/shared/test/unit_test/direct_submission/linux/drm_direct_submission_tests.cpp @@ -8,33 +8,44 @@ #include "shared/source/direct_submission/dispatchers/render_dispatcher.h" #include "shared/source/direct_submission/linux/drm_direct_submission.h" #include "shared/source/os_interface/linux/os_context_linux.h" -#include "shared/test/unit_test/fixtures/device_fixture.h" +#include "shared/test/unit_test/helpers/ult_hw_config.h" +#include "shared/test/unit_test/helpers/variable_backup.h" +#include "shared/test/unit_test/mocks/mock_device.h" +#include "opencl/test/unit_test/os_interface/linux/drm_memory_manager_tests.h" #include "opencl/test/unit_test/os_interface/linux/drm_mock.h" #include "test.h" #include -struct DrmDirectSubmissionFixture : public DeviceFixture { - void SetUp() { - DeviceFixture::SetUp(); +struct DrmDirectSubmissionTest : public DrmMemoryManagerBasic { + void SetUp() override { + backupUlt = std::make_unique>(&ultHwConfig); - osContext = std::make_unique(drmMock, 0u, 0u, aub_stream::ENGINE_RCS, - PreemptionMode::ThreadGroup, false, false, false); + DrmMemoryManagerBasic::SetUp(); + executionEnvironment.incRefInternal(); + + ultHwConfig.forceOsAgnosticMemoryManager = false; + device.reset(MockDevice::create(&executionEnvironment, 0u)); + osContext = std::make_unique(*executionEnvironment.rootDeviceEnvironments[0]->osInterface->get()->getDrm(), + 0u, device->getDeviceBitfield(), aub_stream::ENGINE_RCS, PreemptionMode::ThreadGroup, + false, false, false); } - void TearDown() { - DeviceFixture::TearDown(); + void TearDown() override { + DrmMemoryManagerBasic::TearDown(); } std::unique_ptr osContext; - DrmMock drmMock; + std::unique_ptr device; + + std::unique_ptr> backupUlt; }; template struct MockDrmDirectSubmission : public DrmDirectSubmission { using BaseClass = DrmDirectSubmission; - using BaseClass::allocateOsResources; + using BaseClass::allocateResources; using BaseClass::DrmDirectSubmission; using BaseClass::getTagAddressValue; using BaseClass::handleResidency; @@ -43,24 +54,21 @@ struct MockDrmDirectSubmission : public DrmDirectSubmission; - using namespace NEO; -HWTEST_F(DrmDirectSubmissionTest, givenDrmDirectSubmissionWhenCallingLinuxImplementationThenExpectAllFailAsNotImplemented) { - MockDrmDirectSubmission> drmDirectSubmission(*pDevice, +HWTEST_F(DrmDirectSubmissionTest, givenDrmDirectSubmissionWhenCallingLinuxImplementationThenExpectInitialImplementationValues) { + MockDrmDirectSubmission> drmDirectSubmission(*device.get(), *osContext.get()); - DirectSubmissionAllocations allocations; - EXPECT_FALSE(drmDirectSubmission.allocateOsResources(allocations)); + EXPECT_TRUE(drmDirectSubmission.allocateResources()); uint64_t gpuAddress = 0x1000; size_t size = 0x1000; - EXPECT_FALSE(drmDirectSubmission.submit(gpuAddress, size)); + EXPECT_TRUE(drmDirectSubmission.submit(gpuAddress, size)); - EXPECT_FALSE(drmDirectSubmission.handleResidency()); + EXPECT_TRUE(drmDirectSubmission.handleResidency()); - EXPECT_EQ(0ull, drmDirectSubmission.switchRingBuffers()); + EXPECT_NE(0ull, drmDirectSubmission.switchRingBuffers()); EXPECT_EQ(0ull, drmDirectSubmission.updateTagValue()); @@ -69,3 +77,20 @@ HWTEST_F(DrmDirectSubmissionTest, givenDrmDirectSubmissionWhenCallingLinuxImplem EXPECT_EQ(0ull, tagData.tagAddress); EXPECT_EQ(0ull, tagData.tagValue); } + +HWTEST_F(DrmDirectSubmissionTest, whenCreateDirectSubmissionThenValidObjectIsReturned) { + auto directSubmission = DirectSubmissionHw>::create(*device.get(), + *osContext.get()); + EXPECT_NE(directSubmission.get(), nullptr); +} + +HWTEST_F(DrmDirectSubmissionTest, givenDrmDirectSubmissionWhenDestructObjectThenIoctlIsCalled) { + auto drmDirectSubmission = std::make_unique>>(*device.get(), + *osContext.get()); + auto drm = static_cast(executionEnvironment.rootDeviceEnvironments[0]->osInterface->get()->getDrm()); + drm->ioctlCallsCount = 0u; + drmDirectSubmission->initialize(true); + drmDirectSubmission.reset(); + + EXPECT_EQ(drm->ioctlCallsCount, 11u); +} \ No newline at end of file diff --git a/shared/test/unit_test/direct_submission/windows/wddm_direct_submission_tests.cpp b/shared/test/unit_test/direct_submission/windows/wddm_direct_submission_tests.cpp index 543a0e1961..32d9234839 100644 --- a/shared/test/unit_test/direct_submission/windows/wddm_direct_submission_tests.cpp +++ b/shared/test/unit_test/direct_submission/windows/wddm_direct_submission_tests.cpp @@ -126,28 +126,15 @@ HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenSubmitingCmdBufferThenExpectPass } HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenAllocateOsResourcesThenExpectRingMonitorFenceCreatedAndAllocationsResident) { - MemoryManager *memoryManager = device->getExecutionEnvironment()->memoryManager.get(); - const auto allocationSize = MemoryConstants::pageSize; - const AllocationProperties commandStreamAllocationProperties{device->getRootDeviceIndex(), - allocationSize, - GraphicsAllocation::AllocationType::RING_BUFFER, device->getDeviceBitfield()}; - GraphicsAllocation *ringBuffer = memoryManager->allocateGraphicsMemoryWithProperties(commandStreamAllocationProperties); - ASSERT_NE(nullptr, ringBuffer); - MockWddmDirectSubmission> wddmDirectSubmission(*device.get(), *osContext.get()); - DirectSubmissionAllocations allocations; - allocations.push_back(ringBuffer); - - bool ret = wddmDirectSubmission.allocateOsResources(allocations); + bool ret = wddmDirectSubmission.allocateResources(); EXPECT_TRUE(ret); EXPECT_EQ(1u, wddmMockInterface->createMonitoredFenceCalled); EXPECT_EQ(1u, wddm->makeResidentResult.called); - EXPECT_EQ(1u, wddm->makeResidentResult.handleCount); - - memoryManager->freeGraphicsMemory(ringBuffer); + EXPECT_EQ(3u, wddm->makeResidentResult.handleCount); } HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenAllocateOsResourcesFenceCreationFailsThenExpectRingMonitorFenceNotCreatedAndAllocationsNotResident) { @@ -166,7 +153,7 @@ HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenAllocateOsResourcesFenceCreation wddmMockInterface->createMonitoredFenceCalledFail = true; - bool ret = wddmDirectSubmission.allocateOsResources(allocations); + bool ret = wddmDirectSubmission.allocateOsResources(); EXPECT_FALSE(ret); EXPECT_EQ(1u, wddmMockInterface->createMonitoredFenceCalled); @@ -177,32 +164,19 @@ HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenAllocateOsResourcesFenceCreation } HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenAllocateOsResourcesResidencyFailsThenExpectRingMonitorFenceCreatedAndAllocationsNotResident) { - MemoryManager *memoryManager = device->getExecutionEnvironment()->memoryManager.get(); - const auto allocationSize = MemoryConstants::pageSize; - const AllocationProperties commandStreamAllocationProperties{device->getRootDeviceIndex(), - allocationSize, - GraphicsAllocation::AllocationType::RING_BUFFER, device->getDeviceBitfield()}; - GraphicsAllocation *ringBuffer = memoryManager->allocateGraphicsMemoryWithProperties(commandStreamAllocationProperties); - ASSERT_NE(nullptr, ringBuffer); - MockWddmDirectSubmission> wddmDirectSubmission(*device.get(), *osContext.get()); - DirectSubmissionAllocations allocations; - allocations.push_back(ringBuffer); - wddm->callBaseMakeResident = false; wddm->makeResidentStatus = false; - bool ret = wddmDirectSubmission.allocateOsResources(allocations); + bool ret = wddmDirectSubmission.allocateResources(); EXPECT_FALSE(ret); - EXPECT_EQ(1u, wddmMockInterface->createMonitoredFenceCalled); + EXPECT_EQ(0u, wddmMockInterface->createMonitoredFenceCalled); //expect 2 makeResident calls, due to fail on 1st and then retry (which also fails) EXPECT_EQ(2u, wddm->makeResidentResult.called); - EXPECT_EQ(1u, wddm->makeResidentResult.handleCount); - - memoryManager->freeGraphicsMemory(ringBuffer); + EXPECT_EQ(3u, wddm->makeResidentResult.handleCount); } HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenGettingTagDataThenExpectContextMonitorFence) { @@ -406,24 +380,11 @@ HWTEST_F(WddmDirectSubmissionTest, givenWddmResidencyEnabledWhenAllocatingResour EXPECT_EQ(1u, NEO::IoFunctions::mockVfptrinfCalled); EXPECT_EQ(0u, NEO::IoFunctions::mockFcloseCalled); - MemoryManager *memoryManager = device->getExecutionEnvironment()->memoryManager.get(); - const auto allocationSize = MemoryConstants::pageSize; - const AllocationProperties commandStreamAllocationProperties{device->getRootDeviceIndex(), - allocationSize, - GraphicsAllocation::AllocationType::RING_BUFFER, device->getDeviceBitfield()}; - GraphicsAllocation *ringBuffer = memoryManager->allocateGraphicsMemoryWithProperties(commandStreamAllocationProperties); - ASSERT_NE(nullptr, ringBuffer); - - DirectSubmissionAllocations allocations; - allocations.push_back(ringBuffer); - - bool ret = wddmDirectSubmission.allocateOsResources(allocations); + bool ret = wddmDirectSubmission.allocateResources(); EXPECT_TRUE(ret); - memoryManager->freeGraphicsMemory(ringBuffer); - EXPECT_EQ(1u, NEO::IoFunctions::mockFopenCalled); - EXPECT_EQ(6u, NEO::IoFunctions::mockVfptrinfCalled); + EXPECT_EQ(10u, NEO::IoFunctions::mockVfptrinfCalled); EXPECT_EQ(0u, NEO::IoFunctions::mockFcloseCalled); } diff --git a/shared/test/unit_test/mocks/mock_direct_submission_hw.h b/shared/test/unit_test/mocks/mock_direct_submission_hw.h index 583bc6f31a..1cf49d7e5e 100644 --- a/shared/test/unit_test/mocks/mock_direct_submission_hw.h +++ b/shared/test/unit_test/mocks/mock_direct_submission_hw.h @@ -66,10 +66,14 @@ struct MockDirectSubmissionHw : public DirectSubmissionHw deallocateResources(); } - bool allocateOsResources(DirectSubmissionAllocations &allocations) override { + bool allocateOsResources() override { return allocateOsResourcesReturn; } + bool makeResourcesResident(DirectSubmissionAllocations &allocations) override { + return true; + } + bool submit(uint64_t gpuAddress, size_t size) override { submitGpuAddress = gpuAddress; submitSize = size; @@ -82,15 +86,7 @@ struct MockDirectSubmissionHw : public DirectSubmissionHw return handleResidencyReturn; } - uint64_t switchRingBuffers() override { - GraphicsAllocation *nextRingBuffer = switchRingBuffersAllocations(); - uint64_t currentBufferGpuVa = getCommandBufferPositionGpuAddress(ringCommandStream.getSpace(0)); - - ringCommandStream.replaceBuffer(nextRingBuffer->getUnderlyingBuffer(), ringCommandStream.getMaxAvailableSpace()); - ringCommandStream.replaceGraphicsAllocation(nextRingBuffer); - - return currentBufferGpuVa; - } + void handleSwitchRingBuffers() override {} uint64_t updateTagValue() override { return updateTagValueReturn; diff --git a/shared/test/unit_test/mocks/windows/mock_wddm_direct_submission.h b/shared/test/unit_test/mocks/windows/mock_wddm_direct_submission.h index b95c1b406b..49b31cb22b 100644 --- a/shared/test/unit_test/mocks/windows/mock_wddm_direct_submission.h +++ b/shared/test/unit_test/mocks/windows/mock_wddm_direct_submission.h @@ -14,6 +14,7 @@ template struct MockWddmDirectSubmission : public WddmDirectSubmission { using BaseClass = WddmDirectSubmission; using BaseClass::allocateOsResources; + using BaseClass::allocateResources; using BaseClass::commandBufferHeader; using BaseClass::completionRingBuffers; using BaseClass::currentRingBuffer;