From 3970f1bc4ccc0d3aa75b69b5c5dfd39dc53dbb2c Mon Sep 17 00:00:00 2001 From: Maciej Plewka Date: Thu, 4 Jan 2024 09:10:49 +0000 Subject: [PATCH] fix: create hwQueue when reinitialize osContext Signed-off-by: Maciej Plewka Related-To: NEO-9877 --- .../os_interface/windows/os_context_win.cpp | 8 ++- shared/test/common/mocks/CMakeLists.txt | 3 +- .../test/common/mocks/mock_wddm_interface.h | 24 +++++++++ .../windows/os_context_win_tests.cpp | 50 ++++++++++++++++++- 4 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 shared/test/common/mocks/mock_wddm_interface.h diff --git a/shared/source/os_interface/windows/os_context_win.cpp b/shared/source/os_interface/windows/os_context_win.cpp index 2f24f090e7..fe58370488 100644 --- a/shared/source/os_interface/windows/os_context_win.cpp +++ b/shared/source/os_interface/windows/os_context_win.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -58,9 +58,15 @@ void OsContextWin::reInitializeContext() { bool disableContextCreationFlag = envReader.getSetting("NEO_L0_SYSMAN_NO_CONTEXT_MODE", false); if (!disableContextCreationFlag) { if (contextInitialized && (false == this->wddm.skipResourceCleanup())) { + wddm.getWddmInterface()->destroyHwQueue(hardwareQueue.handle); wddm.destroyContext(wddmContextHandle); } UNRECOVERABLE_IF(!wddm.createContext(*this)); + auto wddmInterface = wddm.getWddmInterface(); + if (wddmInterface->hwQueuesSupported()) { + UNRECOVERABLE_IF(!wddmInterface->createHwQueue(*this)); + UNRECOVERABLE_IF(!wddmInterface->createMonitoredFence(*this)); + } } }; diff --git a/shared/test/common/mocks/CMakeLists.txt b/shared/test/common/mocks/CMakeLists.txt index 7b177fdc62..6a2121bdad 100644 --- a/shared/test/common/mocks/CMakeLists.txt +++ b/shared/test/common/mocks/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2020-2023 Intel Corporation +# Copyright (C) 2020-2024 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -117,6 +117,7 @@ endif() if(WIN32 OR NOT DISABLE_WDDM_LINUX) list(APPEND NEO_CORE_tests_mocks ${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm.h + ${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface20.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_interface23.h ${CMAKE_CURRENT_SOURCE_DIR}/mock_wddm_residency_allocations_container.h diff --git a/shared/test/common/mocks/mock_wddm_interface.h b/shared/test/common/mocks/mock_wddm_interface.h new file mode 100644 index 0000000000..aa8fed8ce9 --- /dev/null +++ b/shared/test/common/mocks/mock_wddm_interface.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2024 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "shared/source/os_interface/windows/wddm/wddm_interface.h" +#include "shared/test/common/test_macros/mock_method_macros.h" + +namespace NEO { +class WddmMockInterface : public WddmInterface { + public: + using WddmInterface::WddmInterface; + ADDMETHOD_NOBASE(createHwQueue, bool, true, (OsContextWin & osContext)); + ADDMETHOD_NOBASE_VOIDRETURN(destroyHwQueue, (D3DKMT_HANDLE hwQueue)); + ADDMETHOD_NOBASE(createMonitoredFence, bool, true, (OsContextWin & osContext)); + ADDMETHOD_NOBASE_VOIDRETURN(destroyMonitorFence, (MonitoredFence & monitorFence)); + ADDMETHOD_NOBASE(hwQueuesSupported, bool, false, ()); + ADDMETHOD_NOBASE(submit, bool, true, (uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments)); +}; +} // namespace NEO diff --git a/shared/test/unit_test/os_interface/windows/os_context_win_tests.cpp b/shared/test/unit_test/os_interface/windows/os_context_win_tests.cpp index 50818913e7..3a4d14f8f8 100644 --- a/shared/test/unit_test/os_interface/windows/os_context_win_tests.cpp +++ b/shared/test/unit_test/os_interface/windows/os_context_win_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2023 Intel Corporation + * Copyright (C) 2018-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -8,6 +8,7 @@ #include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/helpers/engine_descriptor_helper.h" #include "shared/test/common/mocks/mock_wddm.h" +#include "shared/test/common/mocks/mock_wddm_interface.h" #include "shared/test/common/os_interface/windows/wddm_fixture.h" using namespace NEO; @@ -99,6 +100,53 @@ TEST_F(OsContextWinTest, givenWddmOnLinuxThenDirectSubmissionIsNotSupported) { EXPECT_FALSE(osContext->isDirectSubmissionSupported()); } +TEST_F(OsContextWinTest, givenWddmWhenReinitializeCalledThenHwQueueDestroyCalled) { + auto wddm = static_cast(osInterface->getDriverModel()->as()); + auto mockWddmInterface = std::make_unique(*wddm); + auto pMockWddmInterface = mockWddmInterface.get(); + wddm->wddmInterface.reset(mockWddmInterface.release()); + osContext->reInitializeContext(); + EXPECT_EQ(pMockWddmInterface->destroyHwQueueCalled, 1u); +} + +TEST_F(OsContextWinTest, givenWddmWithHwQueuesEnabledWhenReinitializeCalledThenCreateHwQueueCalled) { + auto wddm = static_cast(osInterface->getDriverModel()->as()); + auto mockWddmInterface = std::make_unique(*wddm); + mockWddmInterface->hwQueuesSupportedResult = true; + auto pMockWddmInterface = mockWddmInterface.get(); + wddm->wddmInterface.reset(mockWddmInterface.release()); + osContext->reInitializeContext(); + EXPECT_EQ(pMockWddmInterface->createHwQueueCalled, 1u); +} +TEST_F(OsContextWinTest, givenWddmWithHwQueuesEnabledWhenReinitializeCalledThenCreateMonitorFenceCalled) { + auto wddm = static_cast(osInterface->getDriverModel()->as()); + auto mockWddmInterface = std::make_unique(*wddm); + mockWddmInterface->hwQueuesSupportedResult = true; + auto pMockWddmInterface = mockWddmInterface.get(); + wddm->wddmInterface.reset(mockWddmInterface.release()); + osContext->reInitializeContext(); + EXPECT_EQ(pMockWddmInterface->createMonitoredFenceCalled, 1u); +} + +TEST_F(OsContextWinTest, givenWddmWithHwQueuesDisabledWhenReinitializeCalledThenCreateHwQueueNotCalled) { + auto wddm = static_cast(osInterface->getDriverModel()->as()); + auto mockWddmInterface = std::make_unique(*wddm); + mockWddmInterface->hwQueuesSupportedResult = false; + auto pMockWddmInterface = mockWddmInterface.get(); + wddm->wddmInterface.reset(mockWddmInterface.release()); + osContext->reInitializeContext(); + EXPECT_EQ(pMockWddmInterface->createHwQueueCalled, 0u); +} +TEST_F(OsContextWinTest, givenWddmWithHwQueuesDisabledWhenReinitializeCalledThenCreateMonitorFenceNotCalled) { + auto wddm = static_cast(osInterface->getDriverModel()->as()); + auto mockWddmInterface = std::make_unique(*wddm); + mockWddmInterface->hwQueuesSupportedResult = false; + auto pMockWddmInterface = mockWddmInterface.get(); + wddm->wddmInterface.reset(mockWddmInterface.release()); + osContext->reInitializeContext(); + EXPECT_EQ(pMockWddmInterface->createMonitoredFenceCalled, 0u); +} + struct OsContextWinTestNoCleanup : public WddmTestWithMockGdiDllNoCleanup { void SetUp() override { WddmTestWithMockGdiDllNoCleanup::SetUp();