From a72109d2093fb1d86ad59e39cd280c02836c97de Mon Sep 17 00:00:00 2001 From: Mateusz Jablonski Date: Mon, 15 Jul 2019 09:12:53 +0200 Subject: [PATCH] Correct residency of private scratch allocation Related-To: NEO-3190 Change-Id: Ia18e2d2ce5e30901f55e7a050a3e453fb4969ada Signed-off-by: Mateusz Jablonski --- .../command_stream_receiver_hw_base.inl | 9 +- .../command_queue/enqueue_kernel_2_tests.cpp | 2 +- ...and_stream_receiver_flush_task_2_tests.cpp | 97 +++++++++++++++++++ 3 files changed, 105 insertions(+), 3 deletions(-) diff --git a/runtime/command_stream/command_stream_receiver_hw_base.inl b/runtime/command_stream/command_stream_receiver_hw_base.inl index 606ca61218..ad0b88e82a 100644 --- a/runtime/command_stream/command_stream_receiver_hw_base.inl +++ b/runtime/command_stream/command_stream_receiver_hw_base.inl @@ -209,7 +209,7 @@ CompletionStamp CommandStreamReceiverHw::flushTask( bool stateBaseAddressDirty = false; bool checkVfeStateDirty = false; - if (requiredScratchSize) { + if (requiredScratchSize || requiredPrivateScratchSize) { scratchSpaceController->setRequiredScratchSpace(ssh.getCpuBase(), requiredScratchSize, requiredPrivateScratchSize, @@ -220,7 +220,12 @@ CompletionStamp CommandStreamReceiverHw::flushTask( if (checkVfeStateDirty) { setMediaVFEStateDirty(true); } - makeResident(*scratchSpaceController->getScratchSpaceAllocation()); + if (scratchSpaceController->getScratchSpaceAllocation()) { + makeResident(*scratchSpaceController->getScratchSpaceAllocation()); + } + if (scratchSpaceController->getPrivateScratchSpaceAllocation()) { + makeResident(*scratchSpaceController->getPrivateScratchSpaceAllocation()); + } } auto &commandStreamCSR = this->getCS(getRequiredCmdStreamSizeAligned(dispatchFlags, device)); diff --git a/unit_tests/command_queue/enqueue_kernel_2_tests.cpp b/unit_tests/command_queue/enqueue_kernel_2_tests.cpp index 20a77cd67f..5626335181 100644 --- a/unit_tests/command_queue/enqueue_kernel_2_tests.cpp +++ b/unit_tests/command_queue/enqueue_kernel_2_tests.cpp @@ -442,7 +442,7 @@ HWTEST_P(EnqueueKernelWithScratch, GivenKernelRequiringScratchWhenItIsEnqueuedWi EXPECT_TRUE(mockCsr->isMadeResident(graphicsAllocation)); - // Enqueue With ScratchSize bigger then previous + // Enqueue With ScratchSize bigger than previous scratchSize = 8196; mediaVFEstate.PerThreadScratchSpace = scratchSize; diff --git a/unit_tests/command_stream/command_stream_receiver_flush_task_2_tests.cpp b/unit_tests/command_stream/command_stream_receiver_flush_task_2_tests.cpp index e9148c1fe2..9df3bc6dbb 100644 --- a/unit_tests/command_stream/command_stream_receiver_flush_task_2_tests.cpp +++ b/unit_tests/command_stream/command_stream_receiver_flush_task_2_tests.cpp @@ -15,6 +15,7 @@ #include "test.h" #include "unit_tests/fixtures/ult_command_stream_receiver_fixture.h" #include "unit_tests/helpers/debug_manager_state_restore.h" +#include "unit_tests/mocks/mock_allocation_properties.h" #include "unit_tests/mocks/mock_buffer.h" #include "unit_tests/mocks/mock_command_queue.h" #include "unit_tests/mocks/mock_csr.h" @@ -443,6 +444,102 @@ HWTEST_F(CommandStreamReceiverFlushTaskTests, handleTagAndScratchAllocationsResi EXPECT_TRUE(commandStreamReceiver->isMadeNonResident(scratchAllocation)); } +struct MockScratchController : public ScratchSpaceController { + using ScratchSpaceController::privateScratchAllocation; + using ScratchSpaceController::scratchAllocation; + using ScratchSpaceController::ScratchSpaceController; + void setRequiredScratchSpace(void *sshBaseAddress, + uint32_t requiredPerThreadScratchSize, + uint32_t requiredPerThreadPrivateScratchSize, + uint32_t currentTaskCount, + uint32_t deviceIdx, + bool &stateBaseAddressDirty, + bool &vfeStateDirty) override { + if (requiredPerThreadScratchSize > scratchSizeBytes) { + scratchSizeBytes = requiredPerThreadScratchSize; + scratchAllocation = getMemoryManager()->allocateGraphicsMemoryWithProperties(MockAllocationProperties{requiredPerThreadScratchSize}); + } + if (requiredPerThreadPrivateScratchSize > privateScratchSizeBytes) { + privateScratchSizeBytes = requiredPerThreadPrivateScratchSize; + privateScratchAllocation = getMemoryManager()->allocateGraphicsMemoryWithProperties(MockAllocationProperties{requiredPerThreadPrivateScratchSize}); + } + } + uint64_t calculateNewGSH() override { return 0u; }; + uint64_t getScratchPatchAddress() override { return 0u; }; + + void reserveHeap(IndirectHeap::Type heapType, IndirectHeap *&indirectHeap) override{}; +}; + +HWTEST_F(CommandStreamReceiverFlushTaskTests, whenScratchIsRequiredForFirstFlushAndPrivateScratchForSecondFlushThenHandleResidencyProperly) { + auto commandStreamReceiver = new MockCsrHw(*pDevice->executionEnvironment); + auto scratchController = new MockScratchController(*pDevice->executionEnvironment, *commandStreamReceiver->getInternalAllocationStorage()); + commandStreamReceiver->scratchSpaceController.reset(scratchController); + pDevice->resetCommandStreamReceiver(commandStreamReceiver); + + commandStreamReceiver->setRequiredScratchSizes(1024, 0); + + flushTask(*commandStreamReceiver); + + EXPECT_NE(nullptr, scratchController->scratchAllocation); + EXPECT_EQ(nullptr, scratchController->privateScratchAllocation); + + auto scratchAllocation = scratchController->scratchAllocation; + + EXPECT_TRUE(commandStreamReceiver->isMadeResident(scratchAllocation)); + EXPECT_TRUE(commandStreamReceiver->isMadeNonResident(scratchAllocation)); + + commandStreamReceiver->madeResidentGfxAllocations.clear(); // this is only history - we can clean this + commandStreamReceiver->madeNonResidentGfxAllocations.clear(); + commandStreamReceiver->setRequiredScratchSizes(0, 1024); + + flushTask(*commandStreamReceiver); // 2nd flush + + EXPECT_NE(nullptr, scratchController->scratchAllocation); + EXPECT_NE(nullptr, scratchController->privateScratchAllocation); + + auto privateScratchAllocation = scratchController->privateScratchAllocation; + + EXPECT_TRUE(commandStreamReceiver->isMadeResident(scratchAllocation)); + EXPECT_TRUE(commandStreamReceiver->isMadeNonResident(scratchAllocation)); + EXPECT_TRUE(commandStreamReceiver->isMadeResident(privateScratchAllocation)); + EXPECT_TRUE(commandStreamReceiver->isMadeNonResident(privateScratchAllocation)); +} + +HWTEST_F(CommandStreamReceiverFlushTaskTests, whenPrivateScratchIsRequiredForFirstFlushAndCommonScratchForSecondFlushThenHandleResidencyProperly) { + auto commandStreamReceiver = new MockCsrHw(*pDevice->executionEnvironment); + auto scratchController = new MockScratchController(*pDevice->executionEnvironment, *commandStreamReceiver->getInternalAllocationStorage()); + commandStreamReceiver->scratchSpaceController.reset(scratchController); + pDevice->resetCommandStreamReceiver(commandStreamReceiver); + + commandStreamReceiver->setRequiredScratchSizes(0, 1024); + + flushTask(*commandStreamReceiver); + + EXPECT_EQ(nullptr, scratchController->scratchAllocation); + EXPECT_NE(nullptr, scratchController->privateScratchAllocation); + + auto privateScratchAllocation = scratchController->privateScratchAllocation; + + EXPECT_TRUE(commandStreamReceiver->isMadeResident(privateScratchAllocation)); + EXPECT_TRUE(commandStreamReceiver->isMadeNonResident(privateScratchAllocation)); + + commandStreamReceiver->madeResidentGfxAllocations.clear(); // this is only history - we can clean this + commandStreamReceiver->madeNonResidentGfxAllocations.clear(); + commandStreamReceiver->setRequiredScratchSizes(1024, 0); + + flushTask(*commandStreamReceiver); // 2nd flush + + EXPECT_NE(nullptr, scratchController->scratchAllocation); + EXPECT_NE(nullptr, scratchController->privateScratchAllocation); + + auto scratchAllocation = scratchController->scratchAllocation; + + EXPECT_TRUE(commandStreamReceiver->isMadeResident(scratchAllocation)); + EXPECT_TRUE(commandStreamReceiver->isMadeNonResident(scratchAllocation)); + EXPECT_TRUE(commandStreamReceiver->isMadeResident(privateScratchAllocation)); + EXPECT_TRUE(commandStreamReceiver->isMadeNonResident(privateScratchAllocation)); +} + HWCMDTEST_F(IGFX_GEN8_CORE, CommandStreamReceiverFlushTaskTests, givenTwoConsecutiveNDRangeKernelsStateBaseAddressIsProgrammedOnceAndScratchAddressInMediaVFEStateIsProgrammedTwiceBothWithCorrectAddress) { typedef typename FamilyType::PARSE PARSE; typedef typename PARSE::MEDIA_VFE_STATE MEDIA_VFE_STATE;