diff --git a/shared/source/os_interface/windows/wddm/wddm.cpp b/shared/source/os_interface/windows/wddm/wddm.cpp index 8d10174213..d5a5382abc 100644 --- a/shared/source/os_interface/windows/wddm/wddm.cpp +++ b/shared/source/os_interface/windows/wddm/wddm.cpp @@ -1013,7 +1013,10 @@ bool Wddm::submit(uint64_t commandBuffer, size_t size, void *commandHeader, Wddm printf("%u: Wddm Submission with context handle %u and HwQueue handle %u\n", SysCalls::getProcessId(), submitArguments.contextHandle, submitArguments.hwQueueHandle); } - getDeviceState(); + status = getDeviceState(); + if (!status) { + return false; + } status = wddmInterface->submit(commandBuffer, size, commandHeader, submitArguments); if (status) { submitArguments.monitorFence->lastSubmittedFence = submitArguments.monitorFence->currentFenceValue; @@ -1023,7 +1026,7 @@ bool Wddm::submit(uint64_t commandBuffer, size_t size, void *commandHeader, Wddm return status; } -void Wddm::getDeviceState() { +bool Wddm::getDeviceState() { if (checkDeviceState) { D3DKMT_GETDEVICESTATE getDevState = {}; NTSTATUS status = STATUS_SUCCESS; @@ -1036,8 +1039,11 @@ void Wddm::getDeviceState() { PRINT_DEBUG_STRING(getDevState.ExecutionState == D3DKMT_DEVICEEXECUTION_ERROR_OUTOFMEMORY, stderr, "Device execution error, out of memory %d\n", getDevState.ExecutionState); if (status == STATUS_SUCCESS) { DEBUG_BREAK_IF(getDevState.ExecutionState != D3DKMT_DEVICEEXECUTION_ACTIVE); + return getDevState.ExecutionState == D3DKMT_DEVICEEXECUTION_ACTIVE; } + return false; } + return true; } unsigned int Wddm::getEnablePreemptionRegValue() { diff --git a/shared/source/os_interface/windows/wddm/wddm.h b/shared/source/os_interface/windows/wddm/wddm.h index 62a839152a..6b5c9902e4 100644 --- a/shared/source/os_interface/windows/wddm/wddm.h +++ b/shared/source/os_interface/windows/wddm/wddm.h @@ -209,7 +209,7 @@ class Wddm : public DriverModel { bool createPagingQueue(); bool destroyPagingQueue(); bool destroyDevice(); - void getDeviceState(); + bool getDeviceState(); MOCKABLE_VIRTUAL void createPagingFenceLogger(); bool setLowPriorityContextParam(D3DKMT_HANDLE contextHandle); bool adjustEvictNeededParameter(bool evictNeeded) { 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 bb0da111ad..b747c22794 100644 --- a/shared/test/unit_test/os_interface/windows/wddm_tests.cpp +++ b/shared/test/unit_test/os_interface/windows/wddm_tests.cpp @@ -409,6 +409,32 @@ TEST_F(WddmTests, GivenWddmWhenMapGpuVaCalledThenGmmClientCallsMapGpuVa) { memoryManager->freeGraphicsMemory(allocation); } +TEST_F(WddmTests, givenCheckDeviceStateSetToTrueAndForceExecutionStateWhenSubmitThenProperValueIsReturned) { + DebugManagerStateRestore restorer{}; + DebugManager.flags.EnableDebugBreak.set(false); + + wddm->checkDeviceState = true; + uint64_t pagingFenceValue = 0u; + VariableBackup pagingFenceBackup(&wddm->pagingFenceAddress, &pagingFenceValue); + auto executionState = D3DKMT_DEVICEEXECUTION_ERROR_OUTOFMEMORY; + setMockDeviceExecutionStateFcn(executionState); + ::testing::internal::CaptureStderr(); + WddmSubmitArguments submitArguments{}; + EXPECT_FALSE(wddm->submit(0, 0, nullptr, submitArguments)); + std::string output = testing::internal::GetCapturedStderr(); + EXPECT_EQ(std::string("Device execution error, out of memory " + std::to_string(executionState) + "\n"), output); + + setMockDeviceExecutionStateFcn(D3DKMT_DEVICEEXECUTION_ACTIVE); + ::testing::internal::CaptureStderr(); + + COMMAND_BUFFER_HEADER commandBufferHeader{}; + MonitoredFence monitoredFence{}; + submitArguments.monitorFence = &monitoredFence; + EXPECT_TRUE(wddm->submit(0, 0, &commandBufferHeader, submitArguments)); + output = testing::internal::GetCapturedStderr(); + EXPECT_EQ(std::string(""), output); +} + TEST_F(WddmTests, givenCheckDeviceStateSetToTrueWhenCallGetDeviceStateAndForceExecutionStateThenProperMessageIsVisible) { DebugManagerStateRestore restorer{}; DebugManager.flags.EnableDebugBreak.set(false); @@ -417,13 +443,13 @@ TEST_F(WddmTests, givenCheckDeviceStateSetToTrueWhenCallGetDeviceStateAndForceEx auto executionState = D3DKMT_DEVICEEXECUTION_ERROR_OUTOFMEMORY; setMockDeviceExecutionStateFcn(executionState); ::testing::internal::CaptureStderr(); - wddm->getDeviceState(); + EXPECT_FALSE(wddm->getDeviceState()); std::string output = testing::internal::GetCapturedStderr(); EXPECT_EQ(std::string("Device execution error, out of memory " + std::to_string(executionState) + "\n"), output); setMockDeviceExecutionStateFcn(D3DKMT_DEVICEEXECUTION_ACTIVE); ::testing::internal::CaptureStderr(); - wddm->getDeviceState(); + EXPECT_TRUE(wddm->getDeviceState()); output = testing::internal::GetCapturedStderr(); EXPECT_EQ(std::string(""), output); } @@ -436,13 +462,13 @@ TEST_F(WddmTests, givenCheckDeviceStateSetToFalseWhenCallGetDeviceStateAndForceE auto executionState = D3DKMT_DEVICEEXECUTION_ERROR_OUTOFMEMORY; setMockDeviceExecutionStateFcn(executionState); ::testing::internal::CaptureStderr(); - wddm->getDeviceState(); + EXPECT_TRUE(wddm->getDeviceState()); std::string output = testing::internal::GetCapturedStderr(); EXPECT_EQ(std::string(""), output); setMockDeviceExecutionStateFcn(D3DKMT_DEVICEEXECUTION_ACTIVE); ::testing::internal::CaptureStderr(); - wddm->getDeviceState(); + EXPECT_TRUE(wddm->getDeviceState()); output = testing::internal::GetCapturedStderr(); EXPECT_EQ(std::string(""), output); }