From 560b588cbeb829fa2b2546d6e9237124f9488b1c Mon Sep 17 00:00:00 2001 From: Maciej Plewka Date: Fri, 17 Nov 2023 13:14:41 +0000 Subject: [PATCH] fix: Update residency fence value after ring buffer switch Signed-off-by: Maciej Plewka --- .../command_stream/submissions_aggregator.h | 1 + .../direct_submission/direct_submission_hw.h | 6 +- .../direct_submission_hw.inl | 12 ++-- .../linux/drm_direct_submission.h | 2 +- .../linux/drm_direct_submission.inl | 2 +- .../windows/wddm_direct_submission.h | 3 +- .../windows/wddm_direct_submission.inl | 19 ++++++- .../memory_manager/graphics_allocation.cpp | 9 +++ .../memory_manager/graphics_allocation.h | 1 + .../windows/wddm_device_command_stream.inl | 1 + shared/test/common/mocks/CMakeLists.txt | 2 + .../common/mocks/mock_direct_submission_hw.h | 3 +- .../common/mocks/mock_graphics_allocation.h | 5 ++ .../test/common/mocks/mock_os_context_win.h | 28 ++++++++++ .../mocks/mock_wddm_residency_controller.h | 34 +++++++++++ .../linux/drm_direct_submission_tests.cpp | 10 ++-- .../windows/wddm_direct_submission_tests.cpp | 56 +++++++++++++++++-- .../windows/mock_wddm_direct_submission.h | 8 +++ .../wddm_residency_controller_tests.cpp | 19 ++----- 19 files changed, 182 insertions(+), 39 deletions(-) create mode 100644 shared/test/common/mocks/mock_os_context_win.h create mode 100644 shared/test/common/mocks/mock_wddm_residency_controller.h diff --git a/shared/source/command_stream/submissions_aggregator.h b/shared/source/command_stream/submissions_aggregator.h index f2d64e4dbe..6df7e3a625 100644 --- a/shared/source/command_stream/submissions_aggregator.h +++ b/shared/source/command_stream/submissions_aggregator.h @@ -37,6 +37,7 @@ struct BatchBuffer { bool dispatchMonitorFence); BatchBuffer() {} GraphicsAllocation *commandBufferAllocation = nullptr; + ResidencyContainer *allocationsForResidency = nullptr; size_t startOffset = 0u; size_t chainedBatchBufferStartOffset = 0u; uint64_t taskStartAddress = 0; // if task not available, use CSR stream diff --git a/shared/source/direct_submission/direct_submission_hw.h b/shared/source/direct_submission/direct_submission_hw.h index 51d19f94d6..3da7e737b8 100644 --- a/shared/source/direct_submission/direct_submission_hw.h +++ b/shared/source/direct_submission/direct_submission_hw.h @@ -111,9 +111,9 @@ class DirectSubmissionHw { size_t getSizeNewResourceHandler(); virtual void handleStopRingBuffer(){}; virtual void ensureRingCompletion(){}; - void switchRingBuffersNeeded(size_t size); - virtual uint64_t switchRingBuffers(); - virtual void handleSwitchRingBuffers() = 0; + void switchRingBuffersNeeded(size_t size, ResidencyContainer *allocationsForResidency); + uint64_t switchRingBuffers(ResidencyContainer *allocationsForResidency); + virtual void handleSwitchRingBuffers(ResidencyContainer *allocationsForResidency) = 0; GraphicsAllocation *switchRingBuffersAllocations(); constexpr static uint64_t updateTagValueFail = std::numeric_limits::max(); diff --git a/shared/source/direct_submission/direct_submission_hw.inl b/shared/source/direct_submission/direct_submission_hw.inl index 20fb32159d..d9aed6f205 100644 --- a/shared/source/direct_submission/direct_submission_hw.inl +++ b/shared/source/direct_submission/direct_submission_hw.inl @@ -518,7 +518,7 @@ bool DirectSubmissionHw::startRingBuffer() { size_t requiredSize = startSize + getSizeDispatch(false, false, dispatchMonitorFenceRequired(true)) + getSizeEnd(false); if (ringCommandStream.getAvailableSpace() < requiredSize) { - switchRingBuffers(); + switchRingBuffers(nullptr); } uint64_t gpuStartVa = ringCommandStream.getCurrentGpuAddressPosition(); @@ -978,7 +978,7 @@ bool DirectSubmissionHw::dispatchCommandBuffer(BatchBuffe } } - this->switchRingBuffersNeeded(requiredMinimalSize); + this->switchRingBuffersNeeded(requiredMinimalSize, batchBuffer.allocationsForResidency); if (this->relaxedOrderingEnabled && batchBuffer.hasStallingCmds && this->relaxedOrderingSchedulerRequired) { dispatchRelaxedOrderingQueueStall(); @@ -1047,14 +1047,14 @@ bool DirectSubmissionHw::isNewResourceHandleNeeded() { } template -void DirectSubmissionHw::switchRingBuffersNeeded(size_t size) { +void DirectSubmissionHw::switchRingBuffersNeeded(size_t size, ResidencyContainer *allocationsForResidency) { if (this->ringCommandStream.getAvailableSpace() < size) { - this->switchRingBuffers(); + this->switchRingBuffers(allocationsForResidency); } } template -inline uint64_t DirectSubmissionHw::switchRingBuffers() { +inline uint64_t DirectSubmissionHw::switchRingBuffers(ResidencyContainer *allocationsForResidency) { GraphicsAllocation *nextRingBuffer = switchRingBuffersAllocations(); void *flushPtr = ringCommandStream.getSpace(0); uint64_t currentBufferGpuVa = ringCommandStream.getCurrentGpuAddressPosition(); @@ -1067,7 +1067,7 @@ inline uint64_t DirectSubmissionHw::switchRingBuffers() { ringCommandStream.replaceBuffer(nextRingBuffer->getUnderlyingBuffer(), ringCommandStream.getMaxAvailableSpace()); ringCommandStream.replaceGraphicsAllocation(nextRingBuffer); - handleSwitchRingBuffers(); + handleSwitchRingBuffers(allocationsForResidency); return currentBufferGpuVa; } diff --git a/shared/source/direct_submission/linux/drm_direct_submission.h b/shared/source/direct_submission/linux/drm_direct_submission.h index 8dafa7fe91..7f3349c7fe 100644 --- a/shared/source/direct_submission/linux/drm_direct_submission.h +++ b/shared/source/direct_submission/linux/drm_direct_submission.h @@ -30,7 +30,7 @@ class DrmDirectSubmission : public DirectSubmissionHw { void handleStopRingBuffer() override; void ensureRingCompletion() override; - void handleSwitchRingBuffers() override; + void handleSwitchRingBuffers(ResidencyContainer *allocationsForResidency) override; uint64_t updateTagValue(bool requireMonitorFence) override; void getTagAddressValue(TagData &tagData) override; bool isCompleted(uint32_t ringBufferIndex) override; diff --git a/shared/source/direct_submission/linux/drm_direct_submission.inl b/shared/source/direct_submission/linux/drm_direct_submission.inl index 8165a9bd6c..6f921e2546 100644 --- a/shared/source/direct_submission/linux/drm_direct_submission.inl +++ b/shared/source/direct_submission/linux/drm_direct_submission.inl @@ -195,7 +195,7 @@ void DrmDirectSubmission::handleStopRingBuffer() { } template -void DrmDirectSubmission::handleSwitchRingBuffers() { +void DrmDirectSubmission::handleSwitchRingBuffers(ResidencyContainer *allocationsForResidency) { if (this->disableMonitorFence) { this->currentTagData.tagValue++; diff --git a/shared/source/direct_submission/windows/wddm_direct_submission.h b/shared/source/direct_submission/windows/wddm_direct_submission.h index 306f4390a0..18f012ff26 100644 --- a/shared/source/direct_submission/windows/wddm_direct_submission.h +++ b/shared/source/direct_submission/windows/wddm_direct_submission.h @@ -32,13 +32,14 @@ class WddmDirectSubmission : public DirectSubmissionHw { bool handleResidency() override; void handleCompletionFence(uint64_t completionValue, MonitoredFence &fence); void ensureRingCompletion() override; - void handleSwitchRingBuffers() override; + void handleSwitchRingBuffers(ResidencyContainer *allocationsForResidency) override; void handleStopRingBuffer() override; uint64_t updateTagValue(bool requireMonitorFence) override; bool dispatchMonitorFenceRequired(bool requireMonitorFence) override; uint64_t updateTagValueImpl(); void getTagAddressValue(TagData &tagData) override; bool isCompleted(uint32_t ringBufferIndex) override; + MOCKABLE_VIRTUAL void updateMonitorFenceValueForResidencyList(ResidencyContainer *allocationsForResidency); OsContextWin *osContextWin; Wddm *wddm; diff --git a/shared/source/direct_submission/windows/wddm_direct_submission.inl b/shared/source/direct_submission/windows/wddm_direct_submission.inl index d4fb8ebb3b..586421394d 100644 --- a/shared/source/direct_submission/windows/wddm_direct_submission.inl +++ b/shared/source/direct_submission/windows/wddm_direct_submission.inl @@ -62,7 +62,7 @@ inline void WddmDirectSubmission::flushMonitorFence() { this->getSizeNewResourceHandler() + this->getSizeSwitchRingBufferSection() + this->getSizeEnd(false); - this->switchRingBuffersNeeded(requiredMinimalSize); + this->switchRingBuffersNeeded(requiredMinimalSize, nullptr); this->handleNewResourcesSubmission(); @@ -129,9 +129,10 @@ void WddmDirectSubmission::handleStopRingBuffer() { } template -void WddmDirectSubmission::handleSwitchRingBuffers() { +void WddmDirectSubmission::handleSwitchRingBuffers(ResidencyContainer *allocationsForResidency) { if (this->disableMonitorFence) { updateTagValueImpl(); + updateMonitorFenceValueForResidencyList(allocationsForResidency); } } @@ -194,4 +195,18 @@ inline bool WddmDirectSubmission::isCompleted(uint32_t ri return true; } +template +void WddmDirectSubmission::updateMonitorFenceValueForResidencyList(ResidencyContainer *allocationsForResidency) { + if (allocationsForResidency == nullptr) { + return; + } + const auto currentFence = osContextWin->getResidencyController().getMonitoredFence().currentFenceValue; + auto contextId = osContextWin->getContextId(); + for (uint32_t i = 0; i < allocationsForResidency->size(); i++) { + WddmAllocation *allocation = static_cast((*allocationsForResidency)[i]); + // Update fence value not to early destroy / evict allocation + allocation->updateCompletionDataForAllocationAndFragments(currentFence, contextId); + } +} + } // namespace NEO diff --git a/shared/source/memory_manager/graphics_allocation.cpp b/shared/source/memory_manager/graphics_allocation.cpp index aee64e02f2..9e999e5cbc 100644 --- a/shared/source/memory_manager/graphics_allocation.cpp +++ b/shared/source/memory_manager/graphics_allocation.cpp @@ -124,6 +124,15 @@ uint32_t GraphicsAllocation::getNumHandlesForKmdSharedAllocation(uint32_t numBan return (numBanks > 1) && (DebugManager.flags.CreateKmdMigratedSharedAllocationWithMultipleBOs.get() != 0) ? numBanks : 1u; } +void GraphicsAllocation::updateCompletionDataForAllocationAndFragments(uint64_t newFenceValue, uint32_t contextId) { + getResidencyData().updateCompletionData(newFenceValue, contextId); + + for (uint32_t allocationId = 0; allocationId < fragmentsStorage.fragmentCount; allocationId++) { + auto residencyData = fragmentsStorage.fragmentStorageData[allocationId].residency; + residencyData->updateCompletionData(newFenceValue, contextId); + } +} + constexpr TaskCountType GraphicsAllocation::objectNotUsed; constexpr TaskCountType GraphicsAllocation::objectNotResident; constexpr TaskCountType GraphicsAllocation::objectAlwaysResident; diff --git a/shared/source/memory_manager/graphics_allocation.h b/shared/source/memory_manager/graphics_allocation.h index 0271dcb310..91185e75c6 100644 --- a/shared/source/memory_manager/graphics_allocation.h +++ b/shared/source/memory_manager/graphics_allocation.h @@ -306,6 +306,7 @@ class GraphicsAllocation : public IDNode { SurfaceStateInHeapInfo getBindlessInfo() { return bindlessInfo; } + MOCKABLE_VIRTUAL void updateCompletionDataForAllocationAndFragments(uint64_t newFenceValue, uint32_t contextId); OsHandleStorage fragmentsStorage; StorageInfo storageInfo = {}; diff --git a/shared/source/os_interface/windows/wddm_device_command_stream.inl b/shared/source/os_interface/windows/wddm_device_command_stream.inl index df0a1c2157..6c8f373c3b 100644 --- a/shared/source/os_interface/windows/wddm_device_command_stream.inl +++ b/shared/source/os_interface/windows/wddm_device_command_stream.inl @@ -82,6 +82,7 @@ SubmissionStatus WddmCommandStreamReceiver::flush(BatchBuffer &batchB if (submissionStatus != SubmissionStatus::SUCCESS) { return submissionStatus; } + batchBuffer.allocationsForResidency = &allocationsForResidency; if (this->directSubmission.get()) { this->startControllingDirectSubmissions(); auto ret = this->directSubmission->dispatchCommandBuffer(batchBuffer, *(this->flushStamp.get())); diff --git a/shared/test/common/mocks/CMakeLists.txt b/shared/test/common/mocks/CMakeLists.txt index a5e7da4aa2..8f7c1e87e1 100644 --- a/shared/test/common/mocks/CMakeLists.txt +++ b/shared/test/common/mocks/CMakeLists.txt @@ -79,6 +79,7 @@ set(NEO_CORE_tests_mocks ${CMAKE_CURRENT_SOURCE_DIR}/mock_modules_zebin.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_multi_graphics_allocation.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_os_context.h + ${CMAKE_CURRENT_SOURCE_DIR}/mock_os_context_win.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_os_library.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_os_library.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mock_ostime.h @@ -90,6 +91,7 @@ set(NEO_CORE_tests_mocks ${CMAKE_CURRENT_SOURCE_DIR}/mock_tbx_csr.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_timestamp_container.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_timestamp_packet.h + ${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_residency_controller.h ${CMAKE_CURRENT_SOURCE_DIR}/ult_device_factory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ult_device_factory.h ) diff --git a/shared/test/common/mocks/mock_direct_submission_hw.h b/shared/test/common/mocks/mock_direct_submission_hw.h index af6cbaa836..a535b3f3ea 100644 --- a/shared/test/common/mocks/mock_direct_submission_hw.h +++ b/shared/test/common/mocks/mock_direct_submission_hw.h @@ -82,6 +82,7 @@ struct MockDirectSubmissionHw : public DirectSubmissionHw using BaseClass::startRingBuffer; using BaseClass::stopRingBuffer; using BaseClass::switchRingBuffersAllocations; + using BaseClass::switchRingBuffersNeeded; using BaseClass::systemMemoryFenceAddressSet; using BaseClass::unblockGpu; using BaseClass::useNotifyForPostSync; @@ -152,7 +153,7 @@ struct MockDirectSubmissionHw : public DirectSubmissionHw return handleResidencyReturn; } - void handleSwitchRingBuffers() override {} + void handleSwitchRingBuffers(ResidencyContainer *allocationsForResidency) override {} uint64_t updateTagValue(bool requireMonitorFence) override { return updateTagValueReturn; diff --git a/shared/test/common/mocks/mock_graphics_allocation.h b/shared/test/common/mocks/mock_graphics_allocation.h index 34438b75ad..8360870b2c 100644 --- a/shared/test/common/mocks/mock_graphics_allocation.h +++ b/shared/test/common/mocks/mock_graphics_allocation.h @@ -57,6 +57,11 @@ class MockGraphicsAllocation : public MemoryAllocation { handle = internalHandle; return peekInternalHandleResult; } + void updateCompletionDataForAllocationAndFragments(uint64_t newFenceValue, uint32_t contextId) override { + updateCompletionDataForAllocationAndFragmentsCalledtimes++; + } + + uint64_t updateCompletionDataForAllocationAndFragmentsCalledtimes = 0; int peekInternalHandleResult = 0; uint64_t internalHandle = 0; }; diff --git a/shared/test/common/mocks/mock_os_context_win.h b/shared/test/common/mocks/mock_os_context_win.h new file mode 100644 index 0000000000..733005f517 --- /dev/null +++ b/shared/test/common/mocks/mock_os_context_win.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/os_interface/windows/os_context_win.h" +#include "shared/test/common/mocks/mock_wddm_residency_controller.h" + +namespace NEO { +class MockOsContextWin : public OsContextWin { + public: + MockOsContextWin(Wddm &wddm, uint32_t rootDeviceIndex, uint32_t contextId, const EngineDescriptor &engineDescriptor) + : OsContextWin(wddm, rootDeviceIndex, contextId, engineDescriptor), + mockResidencyController(wddm, contextId) {} + + WddmResidencyController &getResidencyController() override { + getResidencyControllerCalledTimes++; + return mockResidencyController; + }; + + uint64_t getResidencyControllerCalledTimes = 0; + MockWddmResidencyController mockResidencyController; +}; + +} // namespace NEO \ No newline at end of file diff --git a/shared/test/common/mocks/mock_wddm_residency_controller.h b/shared/test/common/mocks/mock_wddm_residency_controller.h new file mode 100644 index 0000000000..d43ef83135 --- /dev/null +++ b/shared/test/common/mocks/mock_wddm_residency_controller.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/os_interface/windows/wddm_residency_controller.h" + +namespace NEO { +class MockWddmResidencyController : public WddmResidencyController { + public: + using WddmResidencyController::lastTrimFenceValue; + using WddmResidencyController::trimCallbackHandle; + using WddmResidencyController::trimCandidateList; + using WddmResidencyController::trimCandidatesCount; + using WddmResidencyController::trimResidency; + using WddmResidencyController::trimResidencyToBudget; + using WddmResidencyController::WddmResidencyController; + + uint32_t acquireLockCallCount = 0u; + bool forceTrimCandidateListCompaction = false; + + std::unique_lock acquireLock() override { + acquireLockCallCount++; + return WddmResidencyController::acquireLock(); + } + + bool checkTrimCandidateListCompaction() override { + return forceTrimCandidateListCompaction || WddmResidencyController::checkTrimCandidateListCompaction(); + } +}; +} // namespace NEO \ No newline at end of file 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 d1599cd0b3..9c069b542e 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 @@ -119,7 +119,7 @@ HWTEST_F(DrmDirectSubmissionTest, givenDrmDirectSubmissionWhenCallingLinuxImplem EXPECT_TRUE(drmDirectSubmission.handleResidency()); - EXPECT_NE(0ull, drmDirectSubmission.switchRingBuffers()); + EXPECT_NE(0ull, drmDirectSubmission.switchRingBuffers(nullptr)); EXPECT_EQ(0ull, drmDirectSubmission.updateTagValue(drmDirectSubmission.dispatchMonitorFenceRequired(false))); @@ -895,7 +895,7 @@ HWTEST_F(DrmDirectSubmissionTest, givenDrmDirectSubmissionWhenHandleSwitchRingBu auto newCompletionFenceValue = 10u; drmDirectSubmission.currentTagData.tagValue = newCompletionFenceValue; drmDirectSubmission.ringBuffers[prevRingBufferIndex].completionFence = prevCompletionFenceVal; - drmDirectSubmission.handleSwitchRingBuffers(); + drmDirectSubmission.handleSwitchRingBuffers(nullptr); EXPECT_EQ(drmDirectSubmission.ringBuffers[prevRingBufferIndex].completionFence, newCompletionFenceValue + 1); } HWTEST_F(DrmDirectSubmissionTest, givenDrmDirectSubmissionWhenEnableRingSwitchTagUpdateWaEnabledAndRingNotStartedThenCompletionFenceIsNotUpdated) { @@ -910,7 +910,7 @@ HWTEST_F(DrmDirectSubmissionTest, givenDrmDirectSubmissionWhenEnableRingSwitchTa drmDirectSubmission.currentTagData.tagValue = newCompletionFenceValue; drmDirectSubmission.ringBuffers[prevRingBufferIndex].completionFence = prevCompletionFenceVal; - drmDirectSubmission.handleSwitchRingBuffers(); + drmDirectSubmission.handleSwitchRingBuffers(nullptr); EXPECT_EQ(drmDirectSubmission.ringBuffers[prevRingBufferIndex].completionFence, prevCompletionFenceVal); } HWTEST_F(DrmDirectSubmissionTest, givenDrmDirectSubmissionWhenEnableRingSwitchTagUpdateWaEnabledAndRingStartedThenCompletionFenceIsUpdated) { @@ -925,7 +925,7 @@ HWTEST_F(DrmDirectSubmissionTest, givenDrmDirectSubmissionWhenEnableRingSwitchTa drmDirectSubmission.currentTagData.tagValue = newCompletionFenceValue; drmDirectSubmission.ringBuffers[prevRingBufferIndex].completionFence = prevCompletionFenceVal; - drmDirectSubmission.handleSwitchRingBuffers(); + drmDirectSubmission.handleSwitchRingBuffers(nullptr); EXPECT_EQ(drmDirectSubmission.ringBuffers[prevRingBufferIndex].completionFence, newCompletionFenceValue + 1); drmDirectSubmission.ringStart = false; } @@ -939,7 +939,7 @@ HWTEST_F(DrmDirectSubmissionTest, givenDrmDirectSubmissionWhenEnableRingSwitchTa drmDirectSubmission.currentTagData.tagValue = newCompletionFenceValue; drmDirectSubmission.ringBuffers[prevRingBufferIndex].completionFence = prevCompletionFenceVal; - drmDirectSubmission.handleSwitchRingBuffers(); + drmDirectSubmission.handleSwitchRingBuffers(nullptr); EXPECT_EQ(drmDirectSubmission.ringBuffers[prevRingBufferIndex].completionFence, newCompletionFenceValue + 1); } 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 d960659706..894491383d 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 @@ -17,6 +17,7 @@ #include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/helpers/unit_test_helper.h" #include "shared/test/common/mocks/mock_io_functions.h" +#include "shared/test/common/mocks/mock_os_context_win.h" #include "shared/test/common/os_interface/windows/wddm_fixture.h" #include "shared/test/common/test_macros/hw_test.h" #include "shared/test/unit_test/mocks/windows/mock_wddm_direct_submission.h" @@ -287,7 +288,7 @@ HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenSwitchingRingBufferStartedThenEx size_t usedSpace = wddmDirectSubmission.ringCommandStream.getUsed(); uint64_t expectedGpuVa = wddmDirectSubmission.ringBuffers[0].ringBuffer->getGpuAddress() + usedSpace; - uint64_t gpuVa = wddmDirectSubmission.switchRingBuffers(); + uint64_t gpuVa = wddmDirectSubmission.switchRingBuffers(nullptr); EXPECT_EQ(expectedGpuVa, gpuVa); EXPECT_EQ(wddmDirectSubmission.ringBuffers[1].ringBuffer, wddmDirectSubmission.ringCommandStream.getGraphicsAllocation()); @@ -316,7 +317,7 @@ HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenSwitchingRingBufferNotStartedThe uint64_t expectedGpuVa = wddmDirectSubmission.ringBuffers[0].ringBuffer->getGpuAddress(); - uint64_t gpuVa = wddmDirectSubmission.switchRingBuffers(); + uint64_t gpuVa = wddmDirectSubmission.switchRingBuffers(nullptr); EXPECT_EQ(expectedGpuVa, gpuVa); EXPECT_EQ(wddmDirectSubmission.ringBuffers[1].ringBuffer, wddmDirectSubmission.ringCommandStream.getGraphicsAllocation()); @@ -375,7 +376,7 @@ HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenSwitchingRingBufferStartedAndWai size_t usedSpace = wddmDirectSubmission.ringCommandStream.getUsed(); uint64_t expectedGpuVa = wddmDirectSubmission.ringBuffers[0].ringBuffer->getGpuAddress() + usedSpace; - uint64_t gpuVa = wddmDirectSubmission.switchRingBuffers(); + uint64_t gpuVa = wddmDirectSubmission.switchRingBuffers(nullptr); EXPECT_EQ(expectedGpuVa, gpuVa); EXPECT_EQ(wddmDirectSubmission.ringBuffers[2u].ringBuffer, wddmDirectSubmission.ringCommandStream.getGraphicsAllocation()); @@ -409,7 +410,7 @@ HWTEST_F(WddmDirectSubmissionTest, givenWddmWhenSwitchingRingBufferStartedAndWai size_t usedSpace = wddmDirectSubmission.ringCommandStream.getUsed(); uint64_t expectedGpuVa = wddmDirectSubmission.ringBuffers[0].ringBuffer->getGpuAddress() + usedSpace; - uint64_t gpuVa = wddmDirectSubmission.switchRingBuffers(); + uint64_t gpuVa = wddmDirectSubmission.switchRingBuffers(nullptr); EXPECT_EQ(expectedGpuVa, gpuVa); EXPECT_EQ(wddmDirectSubmission.ringBuffers.size(), 2u); EXPECT_EQ(wddmDirectSubmission.ringBuffers[1u].ringBuffer, wddmDirectSubmission.ringCommandStream.getGraphicsAllocation()); @@ -567,7 +568,7 @@ HWTEST_F(WddmDirectSubmissionTest, givenWddmDisableMonitorFenceWhenHandleSwitchR MockWddmDirectSubmission> wddmDirectSubmission(*device->getDefaultEngine().commandStreamReceiver); wddmDirectSubmission.disableMonitorFence = true; - wddmDirectSubmission.handleSwitchRingBuffers(); + wddmDirectSubmission.handleSwitchRingBuffers(nullptr); EXPECT_EQ(value + 1, contextFence.currentFenceValue); EXPECT_EQ(value, wddmDirectSubmission.ringBuffers[wddmDirectSubmission.currentRingBuffer].completionFence); } @@ -976,3 +977,48 @@ HWTEST_F(WddmDirectSubmissionTest, memoryManager->freeGraphicsMemory(clientCommandBuffer); } + +HWTEST_F(WddmDirectSubmissionTest, givenNullPtrResidencyControllerWhenUpdatingResidencyAfterSwitchRingThenReturnBeforeAccessingContextId) { + + using Dispatcher = RenderDispatcher; + auto mockOsContextWin = std::make_unique(*wddm, 0, 0, EngineDescriptorHelper::getDefaultDescriptor()); + + MockWddmDirectSubmission wddmDirectSubmission(*device->getDefaultEngine().commandStreamReceiver); + wddmDirectSubmission.osContextWin = mockOsContextWin.get(); + wddmDirectSubmission.updateMonitorFenceValueForResidencyList(nullptr); + EXPECT_EQ(mockOsContextWin->getResidencyControllerCalledTimes, 0u); +} + +HWTEST_F(WddmDirectSubmissionTest, givenEmptyResidencyControllerWhenUpdatingResidencyAfterSwitchRingThenReturnAfterAccessingContextId) { + + using Dispatcher = RenderDispatcher; + auto mockOsContextWin = std::make_unique(*wddm, 0, 0, EngineDescriptorHelper::getDefaultDescriptor()); + + MockWddmDirectSubmission wddmDirectSubmission(*device->getDefaultEngine().commandStreamReceiver); + wddmDirectSubmission.osContextWin = mockOsContextWin.get(); + ResidencyContainer container; + wddmDirectSubmission.updateMonitorFenceValueForResidencyList(&container); + EXPECT_EQ(mockOsContextWin->getResidencyControllerCalledTimes, 1u); +} + +HWTEST_F(WddmDirectSubmissionTest, givenResidencyControllerWhenUpdatingResidencyAfterSwitchRingThenAllocationCallUpdateResidency) { + + using Dispatcher = RenderDispatcher; + auto mockOsContextWin = std::make_unique(*wddm, 0, 0, EngineDescriptorHelper::getDefaultDescriptor()); + + MockWddmDirectSubmission wddmDirectSubmission(*device->getDefaultEngine().commandStreamReceiver); + wddmDirectSubmission.osContextWin = mockOsContextWin.get(); + ResidencyContainer container; + NEO::MockGraphicsAllocation mockGa; + container.push_back(&mockGa); + wddmDirectSubmission.updateMonitorFenceValueForResidencyList(&container); + EXPECT_EQ(mockGa.updateCompletionDataForAllocationAndFragmentsCalledtimes, 1u); +} + +HWTEST_F(WddmDirectSubmissionTest, givenDirectSubmissionWhenSwitchingRingBuffersThenUpdateResidencyCalled) { + using Dispatcher = RenderDispatcher; + + MockWddmDirectSubmission wddmDirectSubmission(*device->getDefaultEngine().commandStreamReceiver); + wddmDirectSubmission.handleSwitchRingBuffers(nullptr); + EXPECT_EQ(wddmDirectSubmission.updateMonitorFenceValueForResidencyListCalled, 1u); +} \ No newline at end of file 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 9095f2c1e6..c9e3006285 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 @@ -47,10 +47,18 @@ struct MockWddmDirectSubmission : public WddmDirectSubmission rootDeviceEnvironment; WddmMock *wddm = nullptr; std::unique_ptr mockOsContextWin; - MockWddmResidencyController *residencyController = nullptr; + NEO::MockWddmResidencyController *residencyController = nullptr; }; struct WddmResidencyControllerWithGdiTest : ::testing::Test { @@ -112,7 +103,7 @@ struct WddmResidencyControllerWithGdiTest : ::testing::Test { std::unique_ptr rootDeviceEnvironment; WddmMock *wddm = nullptr; std::unique_ptr mockOsContextWin; - MockWddmResidencyController *residencyController = nullptr; + NEO::MockWddmResidencyController *residencyController = nullptr; MockGdi *gdi = nullptr; }; @@ -201,7 +192,7 @@ TEST(WddmResidencyController, givenWddmResidencyControllerWhenItIsConstructedThe wddm->init(); std::memset(&gdi->getRegisterTrimNotificationArg(), 0, sizeof(D3DKMT_REGISTERTRIMNOTIFICATION)); - MockWddmResidencyController residencyController{*wddm, 0u}; + NEO::MockWddmResidencyController residencyController{*wddm, 0u}; EXPECT_EQ(0u, wddm->registerTrimCallbackResult.called); EXPECT_EQ(nullptr, residencyController.trimCallbackHandle);