From 5772b17924895c34aeb11dd8abfd147822dd58f8 Mon Sep 17 00:00:00 2001 From: "Dunajski, Bartosz" Date: Wed, 29 Nov 2023 15:15:54 +0000 Subject: [PATCH] refactor: Add debug flag to check Device State on failed Wddm submission Signed-off-by: Dunajski, Bartosz --- .../debug_settings/debug_variables_base.inl | 1 + .../source/os_interface/windows/wddm/wddm.cpp | 2 + .../source/os_interface/windows/wddm/wddm.h | 2 +- shared/test/common/test_files/igdrcl.config | 1 + .../os_interface/windows/wddm_tests.cpp | 84 +++++++++++++++++++ 5 files changed, 89 insertions(+), 1 deletion(-) diff --git a/shared/source/debug_settings/debug_variables_base.inl b/shared/source/debug_settings/debug_variables_base.inl index 7e2f3d92f6..c6ab1c2709 100644 --- a/shared/source/debug_settings/debug_variables_base.inl +++ b/shared/source/debug_settings/debug_variables_base.inl @@ -251,6 +251,7 @@ DECLARE_DEBUG_VARIABLE(int64_t, OverrideEventSynchronizeTimeout, -1, "-1: defaul DECLARE_DEBUG_VARIABLE(int32_t, ForceTlbFlush, -1, "-1: default, 0: Tlb flush disabled, 1: Tlb Flush enabled") DECLARE_DEBUG_VARIABLE(int32_t, DebugSetMemoryDiagnosticsDelay, -1, "-1: default, >=0: delay time in minutes necessary for completion of Memory diagnostics") DECLARE_DEBUG_VARIABLE(int32_t, EnableDeviceStateVerification, -1, "-1: default, 0: disable, 1: enable check of device state before submit on Windows") +DECLARE_DEBUG_VARIABLE(int32_t, EnableDeviceStateVerificationAfterFailedSubmission, -1, "-1: default, 0: disable, 1: enable check of device state after failed submit on Windows") DECLARE_DEBUG_VARIABLE(int32_t, EnableDynamicPostSyncAllocLayout, -1, "-1: default, 0: Keep Timestamp size layout, 1: Use write immediate layout (qword) and switch dynamically to TS for profiling") DECLARE_DEBUG_VARIABLE(int32_t, PrintTimestampPacketUsage, -1, "-1: default, 0: Disabled, 1: Print when TSP is allocated, initialized, returned to pool, etc.") DECLARE_DEBUG_VARIABLE(int32_t, SynchronizeEventBeforeReset, -1, "-1: default, 0: Disabled, 1: Synchronize Event completion on host before calling reset. 2: Synchronize + print extra logs.") diff --git a/shared/source/os_interface/windows/wddm/wddm.cpp b/shared/source/os_interface/windows/wddm/wddm.cpp index 53bfa0b4fb..e0a349fd0d 100644 --- a/shared/source/os_interface/windows/wddm/wddm.cpp +++ b/shared/source/os_interface/windows/wddm/wddm.cpp @@ -1029,6 +1029,8 @@ bool Wddm::submit(uint64_t commandBuffer, size_t size, void *commandHeader, Wddm if (status) { submitArguments.monitorFence->lastSubmittedFence = submitArguments.monitorFence->currentFenceValue; submitArguments.monitorFence->currentFenceValue++; + } else if (DebugManager.flags.EnableDeviceStateVerificationAfterFailedSubmission.get() == 1) { + getDeviceState(); } return status; diff --git a/shared/source/os_interface/windows/wddm/wddm.h b/shared/source/os_interface/windows/wddm/wddm.h index ccfc1cec52..e2d85fa944 100644 --- a/shared/source/os_interface/windows/wddm/wddm.h +++ b/shared/source/os_interface/windows/wddm/wddm.h @@ -216,7 +216,7 @@ class Wddm : public DriverModel { } bool getDeviceExecutionState(D3DKMT_DEVICESTATE_TYPE stateType, void *privateData); - bool getDeviceState(); + MOCKABLE_VIRTUAL bool getDeviceState(); protected: bool translateTopologyInfo(TopologyMapping &mapping); diff --git a/shared/test/common/test_files/igdrcl.config b/shared/test/common/test_files/igdrcl.config index 970fa1fe0e..4c2997976e 100644 --- a/shared/test/common/test_files/igdrcl.config +++ b/shared/test/common/test_files/igdrcl.config @@ -563,4 +563,5 @@ ForceThreadGroupDispatchSizeAlgorithm = -1 EnableImplicitConvertionToCounterBasedEvents = -1 SetAmountOfInternalHeapsToPreallocate = -1 DoNotUseProductConfigForValidationWa = 0 +EnableDeviceStateVerificationAfterFailedSubmission = -1 # Please don't edit below this line diff --git a/shared/test/unit_test/os_interface/windows/wddm_tests.cpp b/shared/test/unit_test/os_interface/windows/wddm_tests.cpp index 364c2ca492..e3494f625a 100644 --- a/shared/test/unit_test/os_interface/windows/wddm_tests.cpp +++ b/shared/test/unit_test/os_interface/windows/wddm_tests.cpp @@ -551,6 +551,90 @@ TEST_F(WddmTests, givenCheckDeviceStateSetToFalseWhenCallGetDeviceStateAndForceE EXPECT_EQ(std::string(""), output); } +TEST_F(WddmTests, givenDebugFlagSetWhenFailedOnSubmissionThenCheckDeviceState) { + DebugManagerStateRestore restorer; + + constexpr uint32_t submitId = 0; + constexpr uint32_t deviceStateId = 1; + + std::vector operations; + + class MyMockWddm : public WddmMock { + public: + MyMockWddm(RootDeviceEnvironment &rootDeviceEnvironment, std::vector &operations, uint32_t deviceStateId) + : WddmMock(rootDeviceEnvironment), operations(operations), deviceStateId(deviceStateId) { + } + + bool getDeviceState() override { + operations.push_back(deviceStateId); + + return true; + } + + std::vector &operations; + const uint32_t deviceStateId; + }; + + class MyWddmMockInterface20 : public WddmMockInterface20 { + public: + MyWddmMockInterface20(Wddm &wddm, std::vector &operations, uint32_t submitId) : WddmMockInterface20(wddm), operations(operations), submitId(submitId) { + } + + bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments) override { + operations.push_back(submitId); + + return submitRetVal; + } + + std::vector &operations; + const uint32_t submitId; + bool submitRetVal = true; + }; + + MyMockWddm myMockWddm(*rootDeviceEnvironment, operations, deviceStateId); + auto wddmMockInterface = new MyWddmMockInterface20(myMockWddm, operations, submitId); + + myMockWddm.init(); + + myMockWddm.wddmInterface.reset(wddmMockInterface); + + COMMAND_BUFFER_HEADER commandBufferHeader{}; + MonitoredFence monitoredFence{}; + WddmSubmitArguments submitArguments{}; + submitArguments.monitorFence = &monitoredFence; + + EXPECT_TRUE(myMockWddm.submit(0, 0, &commandBufferHeader, submitArguments)); + + ASSERT_EQ(2u, operations.size()); + EXPECT_EQ(deviceStateId, operations[0]); + EXPECT_EQ(submitId, operations[1]); + + wddmMockInterface->submitRetVal = false; + + EXPECT_FALSE(myMockWddm.submit(0, 0, &commandBufferHeader, submitArguments)); + + ASSERT_EQ(4u, operations.size()); + EXPECT_EQ(deviceStateId, operations[2]); + EXPECT_EQ(submitId, operations[3]); + + DebugManager.flags.EnableDeviceStateVerificationAfterFailedSubmission.set(1); + + EXPECT_FALSE(myMockWddm.submit(0, 0, &commandBufferHeader, submitArguments)); + + ASSERT_EQ(7u, operations.size()); + EXPECT_EQ(deviceStateId, operations[4]); + EXPECT_EQ(submitId, operations[5]); + EXPECT_EQ(deviceStateId, operations[6]); + + wddmMockInterface->submitRetVal = true; + + EXPECT_TRUE(myMockWddm.submit(0, 0, &commandBufferHeader, submitArguments)); + + ASSERT_EQ(9u, operations.size()); + EXPECT_EQ(deviceStateId, operations[7]); + EXPECT_EQ(submitId, operations[8]); +} + TEST_F(WddmTests, givenCheckDeviceStateSetToTrueWhenCallGetDeviceStateReturnsPageFaultThenProperMessageIsVisible) { DebugManagerStateRestore restorer{}; DebugManager.flags.EnableDebugBreak.set(false);