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 a41f9123cf..ac08f70234 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 @@ -760,6 +760,68 @@ struct DrmCommandStreamBlitterDirectSubmissionTest : public DrmCommandStreamDire std::unique_ptr osContext; }; +struct DrmDirectSubmissionFunctionsCalled { + bool stopRingBuffer; + bool wait; + bool deallocateResources; +}; + +template +struct MockDrmDirectSubmissionToTestDtor : public DrmDirectSubmission> { + MockDrmDirectSubmissionToTestDtor(Device &device, OsContext &osContext, DrmDirectSubmissionFunctionsCalled &functionsCalled) + : DrmDirectSubmission>(device, osContext), functionsCalled(functionsCalled) { + } + ~MockDrmDirectSubmissionToTestDtor() override { + if (ringStart) { + stopRingBuffer(); + wait(static_cast(this->currentTagData.tagValue)); + } + deallocateResources(); + } + using DrmDirectSubmission>::ringStart; + bool stopRingBuffer() override { + functionsCalled.stopRingBuffer = true; + return true; + } + void wait(uint32_t taskCountToWait) override { + functionsCalled.wait = true; + } + void deallocateResources() override { + functionsCalled.deallocateResources = true; + } + DrmDirectSubmissionFunctionsCalled &functionsCalled; +}; + +HWTEST_TEMPLATED_F(DrmCommandStreamDirectSubmissionTest, givenEnabledDirectSubmissionWhenDtorIsCalledButRingIsNotStartedThenDontCallStopRingBufferNorWaitForTagValue) { + DrmDirectSubmissionFunctionsCalled functionsCalled{}; + auto directSubmission = std::make_unique>(*device.get(), *device->getDefaultEngine().osContext, functionsCalled); + ASSERT_NE(nullptr, directSubmission); + + EXPECT_FALSE(directSubmission->ringStart); + + directSubmission.reset(); + + EXPECT_FALSE(functionsCalled.stopRingBuffer); + EXPECT_FALSE(functionsCalled.wait); + EXPECT_TRUE(functionsCalled.deallocateResources); +} + +template +struct MockDrmDirectSubmissionToTestRingStop : public DrmDirectSubmission> { + MockDrmDirectSubmissionToTestRingStop(Device &device, OsContext &osContext) + : DrmDirectSubmission>(device, osContext) { + } + using DrmDirectSubmission>::ringStart; +}; + +HWTEST_TEMPLATED_F(DrmCommandStreamDirectSubmissionTest, givenEnabledDirectSubmissionWhenStopRingBufferIsCalledThenClearRingStart) { + auto directSubmission = std::make_unique>(*device.get(), *device->getDefaultEngine().osContext); + ASSERT_NE(nullptr, directSubmission); + + directSubmission->stopRingBuffer(); + EXPECT_FALSE(directSubmission->ringStart); +} + template struct MockDrmDirectSubmission : public DrmDirectSubmission> { using DrmDirectSubmission>::currentTagData; diff --git a/shared/source/direct_submission/direct_submission_hw.h b/shared/source/direct_submission/direct_submission_hw.h index f0b36b9ab4..c612234040 100644 --- a/shared/source/direct_submission/direct_submission_hw.h +++ b/shared/source/direct_submission/direct_submission_hw.h @@ -61,7 +61,7 @@ class DirectSubmissionHw { bool initialize(bool submitOnInit); - bool stopRingBuffer(); + MOCKABLE_VIRTUAL bool stopRingBuffer(); bool startRingBuffer(); @@ -73,7 +73,7 @@ class DirectSubmissionHw { static constexpr size_t prefetchSize = 8 * MemoryConstants::cacheLineSize; static constexpr size_t prefetchNoops = prefetchSize / sizeof(uint32_t); bool allocateResources(); - void deallocateResources(); + MOCKABLE_VIRTUAL void deallocateResources(); MOCKABLE_VIRTUAL bool makeResourcesResident(DirectSubmissionAllocations &allocations); virtual bool allocateOsResources() = 0; virtual bool submit(uint64_t gpuAddress, size_t size) = 0; diff --git a/shared/source/direct_submission/linux/drm_direct_submission.h b/shared/source/direct_submission/linux/drm_direct_submission.h index 7a56bfb13a..9c97f0e1b9 100644 --- a/shared/source/direct_submission/linux/drm_direct_submission.h +++ b/shared/source/direct_submission/linux/drm_direct_submission.h @@ -34,7 +34,7 @@ class DrmDirectSubmission : public DirectSubmissionHw { uint64_t updateTagValue() override; void getTagAddressValue(TagData &tagData) override; - void wait(uint32_t taskCountToWait); + MOCKABLE_VIRTUAL void wait(uint32_t taskCountToWait); TagData currentTagData; volatile uint32_t *tagAddress; diff --git a/shared/source/direct_submission/linux/drm_direct_submission.inl b/shared/source/direct_submission/linux/drm_direct_submission.inl index 9d6635ee71..55bd73c396 100644 --- a/shared/source/direct_submission/linux/drm_direct_submission.inl +++ b/shared/source/direct_submission/linux/drm_direct_submission.inl @@ -50,8 +50,10 @@ DrmDirectSubmission::DrmDirectSubmission(Device &device, template inline DrmDirectSubmission::~DrmDirectSubmission() { - this->stopRingBuffer(); - this->wait(static_cast(this->currentTagData.tagValue)); + if (this->ringStart) { + this->stopRingBuffer(); + this->wait(static_cast(this->currentTagData.tagValue)); + } this->deallocateResources(); }