From e29a85ebb39332153c5112704644b2fc8f21f8b1 Mon Sep 17 00:00:00 2001 From: Aravind Gopalakrishnan Date: Thu, 20 Jan 2022 21:20:56 +0000 Subject: [PATCH] Use ImmediateDispatch mode for L0 command queues Related-To: LOCI-1988 Signed-off-by: Aravind Gopalakrishnan --- .../command_stream_receiver.cpp | 3 + .../os_interface/linux/drm_command_stream.inl | 4 + .../windows/wddm_device_command_stream.inl | 4 + .../command_stream_receiver_tests.cpp | 6 + .../os_interface/linux/CMakeLists.txt | 1 + .../linux/drm_command_stream_l0_tests.cpp | 101 ++++++++++++++++ .../os_interface/windows/CMakeLists.txt | 1 + .../windows/wddm_command_stream_l0_tests.cpp | 113 ++++++++++++++++++ 8 files changed, 233 insertions(+) create mode 100644 shared/test/unit_test/os_interface/linux/drm_command_stream_l0_tests.cpp create mode 100644 shared/test/unit_test/os_interface/windows/wddm_command_stream_l0_tests.cpp diff --git a/shared/source/command_stream/command_stream_receiver.cpp b/shared/source/command_stream/command_stream_receiver.cpp index 9074d1a5c9..7c2263a914 100644 --- a/shared/source/command_stream/command_stream_receiver.cpp +++ b/shared/source/command_stream/command_stream_receiver.cpp @@ -47,6 +47,9 @@ CommandStreamReceiver::CommandStreamReceiver(ExecutionEnvironment &executionEnvi latestSentStatelessMocsConfig = CacheSettings::unknownMocs; submissionAggregator.reset(new SubmissionAggregator()); + if (ApiSpecificConfig::getApiType() == ApiSpecificConfig::L0) { + this->dispatchMode = DispatchMode::ImmediateDispatch; + } if (DebugManager.flags.CsrDispatchMode.get()) { this->dispatchMode = (DispatchMode)DebugManager.flags.CsrDispatchMode.get(); } diff --git a/shared/source/os_interface/linux/drm_command_stream.inl b/shared/source/os_interface/linux/drm_command_stream.inl index c87953caa3..092ff3acfa 100644 --- a/shared/source/os_interface/linux/drm_command_stream.inl +++ b/shared/source/os_interface/linux/drm_command_stream.inl @@ -57,6 +57,10 @@ DrmCommandStreamReceiver::DrmCommandStreamReceiver(ExecutionEnvironme this->dispatchMode = localMemoryEnabled ? DispatchMode::BatchedDispatch : DispatchMode::ImmediateDispatch; + if (ApiSpecificConfig::getApiType() == ApiSpecificConfig::L0) { + this->dispatchMode = DispatchMode::ImmediateDispatch; + } + if (DebugManager.flags.CsrDispatchMode.get()) { this->dispatchMode = static_cast(DebugManager.flags.CsrDispatchMode.get()); } 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 55cde7bfba..02ef024e63 100644 --- a/shared/source/os_interface/windows/wddm_device_command_stream.inl +++ b/shared/source/os_interface/windows/wddm_device_command_stream.inl @@ -54,6 +54,10 @@ WddmCommandStreamReceiver::WddmCommandStreamReceiver(ExecutionEnviron this->dispatchMode = DispatchMode::BatchedDispatch; + if (ApiSpecificConfig::getApiType() == ApiSpecificConfig::L0) { + this->dispatchMode = DispatchMode::ImmediateDispatch; + } + if (DebugManager.flags.CsrDispatchMode.get()) { this->dispatchMode = (DispatchMode)DebugManager.flags.CsrDispatchMode.get(); } diff --git a/shared/test/unit_test/command_stream/command_stream_receiver_tests.cpp b/shared/test/unit_test/command_stream/command_stream_receiver_tests.cpp index 0314a75e33..a43843526b 100644 --- a/shared/test/unit_test/command_stream/command_stream_receiver_tests.cpp +++ b/shared/test/unit_test/command_stream/command_stream_receiver_tests.cpp @@ -206,6 +206,12 @@ HWTEST_F(CommandStreamReceiverTest, givenDefaultCommandStreamReceiverThenDefault EXPECT_EQ(DispatchMode::ImmediateDispatch, csr.dispatchMode); } +HWTEST_F(CommandStreamReceiverTest, givenL0CommandStreamReceiverThenDefaultDispatchingPolicyIsImmediateSubmission) { + VariableBackup backup(&apiTypeForUlts, ApiSpecificConfig::L0); + auto &csr = pDevice->getUltCommandStreamReceiver(); + EXPECT_EQ(DispatchMode::ImmediateDispatch, csr.dispatchMode); +} + HWTEST_F(CommandStreamReceiverTest, givenCsrWhenGetIndirectHeapIsCalledThenHeapIsReturned) { auto &csr = pDevice->getUltCommandStreamReceiver(); auto &heap = csr.getIndirectHeap(IndirectHeap::DYNAMIC_STATE, 10u); diff --git a/shared/test/unit_test/os_interface/linux/CMakeLists.txt b/shared/test/unit_test/os_interface/linux/CMakeLists.txt index dc64485d22..5f0b8deaee 100644 --- a/shared/test/unit_test/os_interface/linux/CMakeLists.txt +++ b/shared/test/unit_test/os_interface/linux/CMakeLists.txt @@ -10,6 +10,7 @@ set(NEO_CORE_OS_INTERFACE_TESTS_LINUX ${CMAKE_CURRENT_SOURCE_DIR}/drm_special_heap_test.cpp ${CMAKE_CURRENT_SOURCE_DIR}/hw_info_config_uuid_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/os_context_linux_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/drm_command_stream_l0_tests.cpp ) set_property(GLOBAL PROPERTY NEO_CORE_OS_INTERFACE_TESTS_LINUX ${NEO_CORE_OS_INTERFACE_TESTS_LINUX}) diff --git a/shared/test/unit_test/os_interface/linux/drm_command_stream_l0_tests.cpp b/shared/test/unit_test/os_interface/linux/drm_command_stream_l0_tests.cpp new file mode 100644 index 0000000000..efb597623a --- /dev/null +++ b/shared/test/unit_test/os_interface/linux/drm_command_stream_l0_tests.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/command_stream/preemption.h" +#include "shared/source/helpers/api_specific_config.h" +#include "shared/source/os_interface/linux/drm_command_stream.h" +#include "shared/source/os_interface/linux/drm_memory_operations_handler.h" +#include "shared/source/os_interface/linux/os_context_linux.h" +#include "shared/test/common/helpers/debug_manager_state_restore.h" +#include "shared/test/common/helpers/default_hw_info.h" +#include "shared/test/common/helpers/engine_descriptor_helper.h" +#include "shared/test/common/helpers/variable_backup.h" +#include "shared/test/common/mocks/linux/mock_drm_command_stream_receiver.h" +#include "shared/test/common/mocks/mock_execution_environment.h" +#include "shared/test/common/os_interface/linux/device_command_stream_fixture.h" +#include "shared/test/common/test_macros/test.h" + +#include "drm/i915_drm.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace NEO { +extern ApiSpecificConfig::ApiType apiTypeForUlts; +} //namespace NEO +using namespace NEO; + +class DrmCommandStreamTestL0 : public ::testing::Test { + public: + template + void SetUpT() { + + //make sure this is disabled, we don't want to test this now + DebugManager.flags.EnableForcePin.set(false); + + mock = new ::testing::NiceMock(mockFd, *executionEnvironment.rootDeviceEnvironments[0]); + + executionEnvironment.rootDeviceEnvironments[0]->osInterface = std::make_unique(); + executionEnvironment.rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr(mock)); + executionEnvironment.rootDeviceEnvironments[0]->memoryOperationsInterface = DrmMemoryOperationsHandler::create(*mock, 0u); + + auto hwInfo = executionEnvironment.rootDeviceEnvironments[0]->getHardwareInfo(); + mock->createVirtualMemoryAddressSpace(HwHelper::getSubDevicesCount(hwInfo)); + osContext = std::make_unique(*mock, 0u, + EngineDescriptorHelper::getDefaultDescriptor(HwHelper::get(hwInfo->platform.eRenderCoreFamily).getGpgpuEngineInstances(*hwInfo)[0], + PreemptionHelper::getDefaultPreemptionMode(*hwInfo))); + osContext->ensureContextInitialized(); + + csr = new DrmCommandStreamReceiver(executionEnvironment, 0, 1, gemCloseWorkerMode::gemCloseWorkerActive); + ASSERT_NE(nullptr, csr); + csr->setupContext(*osContext); + + // Memory manager creates pinBB with ioctl, expect one call + EXPECT_CALL(*mock, ioctl(::testing::_, ::testing::_)) + .Times(1); + memoryManager = new DrmMemoryManager(gemCloseWorkerMode::gemCloseWorkerActive, + DebugManager.flags.EnableForcePin.get(), + true, + executionEnvironment); + executionEnvironment.memoryManager.reset(memoryManager); + ::testing::Mock::VerifyAndClearExpectations(mock); + + //assert we have memory manager + ASSERT_NE(nullptr, memoryManager); + } + + template + void TearDownT() { + memoryManager->waitForDeletions(); + memoryManager->peekGemCloseWorker()->close(true); + delete csr; + ::testing::Mock::VerifyAndClearExpectations(mock); + // Memory manager closes pinBB with ioctl, expect one call + EXPECT_CALL(*mock, ioctl(::testing::_, ::testing::_)) + .Times(::testing::AtLeast(1)); + } + + CommandStreamReceiver *csr = nullptr; + DrmMemoryManager *memoryManager = nullptr; + ::testing::NiceMock *mock; + const int mockFd = 33; + static const uint64_t alignment = MemoryConstants::allocationAlignment; + DebugManagerStateRestore dbgState; + MockExecutionEnvironment executionEnvironment; + std::unique_ptr osContext; +}; + +template +struct MockDrmCsrL0 : public DrmCommandStreamReceiver { + using DrmCommandStreamReceiver::DrmCommandStreamReceiver; + using DrmCommandStreamReceiver::dispatchMode; +}; + +HWTEST_TEMPLATED_F(DrmCommandStreamTestL0, givenL0ApiConfigWhenCreatingDrmCsrThenEnableImmediateDispatch) { + VariableBackup backup(&apiTypeForUlts, ApiSpecificConfig::L0); + MockDrmCsrL0 csr(executionEnvironment, 0, 1, gemCloseWorkerMode::gemCloseWorkerInactive); + EXPECT_EQ(DispatchMode::ImmediateDispatch, csr.dispatchMode); +} \ No newline at end of file diff --git a/shared/test/unit_test/os_interface/windows/CMakeLists.txt b/shared/test/unit_test/os_interface/windows/CMakeLists.txt index 99ee36cdc8..4b10df25b7 100644 --- a/shared/test/unit_test/os_interface/windows/CMakeLists.txt +++ b/shared/test/unit_test/os_interface/windows/CMakeLists.txt @@ -15,6 +15,7 @@ set(NEO_CORE_OS_INTERFACE_TESTS_WINDOWS ${CMAKE_CURRENT_SOURCE_DIR}/wddm_special_heap_test.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm_shared_allocations_test.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/wddm_command_stream_l0_tests.cpp ) set_property(GLOBAL PROPERTY NEO_CORE_OS_INTERFACE_TESTS_WINDOWS ${NEO_CORE_OS_INTERFACE_TESTS_WINDOWS}) diff --git a/shared/test/unit_test/os_interface/windows/wddm_command_stream_l0_tests.cpp b/shared/test/unit_test/os_interface/windows/wddm_command_stream_l0_tests.cpp new file mode 100644 index 0000000000..745f286cc6 --- /dev/null +++ b/shared/test/unit_test/os_interface/windows/wddm_command_stream_l0_tests.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/command_stream/command_stream_receiver.h" +#include "shared/source/command_stream/command_stream_receiver_with_aub_dump.h" +#include "shared/source/command_stream/device_command_stream.h" +#include "shared/source/command_stream/linear_stream.h" +#include "shared/source/command_stream/preemption.h" +#include "shared/source/direct_submission/dispatchers/render_dispatcher.h" +#include "shared/source/direct_submission/windows/wddm_direct_submission.h" +#include "shared/source/helpers/api_specific_config.h" +#include "shared/source/helpers/flush_stamp.h" +#include "shared/source/helpers/windows/gmm_callbacks.h" +#include "shared/source/memory_manager/internal_allocation_storage.h" +#include "shared/source/memory_manager/memory_manager.h" +#include "shared/source/os_interface/os_interface.h" +#include "shared/source/os_interface/windows/os_context_win.h" +#include "shared/source/os_interface/windows/wddm_device_command_stream.h" +#include "shared/source/os_interface/windows/wddm_memory_manager.h" +#include "shared/source/os_interface/windows/wddm_memory_operations_handler.h" +#include "shared/source/os_interface/windows/wddm_residency_controller.h" +#include "shared/test/common/helpers/execution_environment_helper.h" +#include "shared/test/common/mocks/mock_builtins.h" +#include "shared/test/common/mocks/mock_device.h" +#include "shared/test/common/mocks/mock_gmm_page_table_mngr.h" +#include "shared/test/common/mocks/mock_graphics_allocation.h" +#include "shared/test/common/mocks/mock_io_functions.h" +#include "shared/test/common/mocks/mock_submissions_aggregator.h" +#include "shared/test/common/mocks/mock_wddm_interface23.h" +#include "shared/test/common/mocks/windows/mock_gdi_interface.h" +#include "shared/test/common/mocks/windows/mock_wddm_direct_submission.h" +#include "shared/test/common/os_interface/windows/mock_wddm_memory_manager.h" +#include "shared/test/common/os_interface/windows/wddm_fixture.h" +#include "shared/test/common/test_macros/test.h" + +namespace NEO { +extern ApiSpecificConfig::ApiType apiTypeForUlts; +} //namespace NEO +using namespace NEO; + +template +struct MockWddmCsrL0 : public WddmCommandStreamReceiver { + using CommandStreamReceiver::clearColorAllocation; + using CommandStreamReceiver::commandStream; + using CommandStreamReceiver::dispatchMode; + using CommandStreamReceiver::getCS; + using CommandStreamReceiver::globalFenceAllocation; + using CommandStreamReceiver::useGpuIdleImplicitFlush; + using CommandStreamReceiver::useNewResourceImplicitFlush; + using CommandStreamReceiverHw::blitterDirectSubmission; + using CommandStreamReceiverHw::directSubmission; + using WddmCommandStreamReceiver::commandBufferHeader; + using WddmCommandStreamReceiver::initDirectSubmission; + using WddmCommandStreamReceiver::WddmCommandStreamReceiver; + + void overrideDispatchPolicy(DispatchMode overrideValue) { + this->dispatchMode = overrideValue; + } + + SubmissionAggregator *peekSubmissionAggregator() { + return this->submissionAggregator.get(); + } + + void overrideSubmissionAggregator(SubmissionAggregator *newSubmissionsAggregator) { + this->submissionAggregator.reset(newSubmissionsAggregator); + } + + void overrideRecorededCommandBuffer(Device &device) { + recordedCommandBuffer = std::unique_ptr(new CommandBuffer(device)); + } + + bool initDirectSubmission(Device &device, OsContext &osContext) override { + if (callParentInitDirectSubmission) { + return WddmCommandStreamReceiver::initDirectSubmission(device, osContext); + } + bool ret = true; + if (DebugManager.flags.EnableDirectSubmission.get() == 1) { + if (!initBlitterDirectSubmission) { + directSubmission = std::make_unique< + MockWddmDirectSubmission>>(device, osContext); + ret = directSubmission->initialize(true, false); + this->dispatchMode = DispatchMode::ImmediateDispatch; + } else { + blitterDirectSubmission = std::make_unique< + MockWddmDirectSubmission>>(device, osContext); + blitterDirectSubmission->initialize(true, false); + } + } + return ret; + } + + int flushCalledCount = 0; + std::unique_ptr recordedCommandBuffer = nullptr; + + bool callParentInitDirectSubmission = true; + bool initBlitterDirectSubmission = false; +}; + +using WddmSimpleTestL0 = ::testing::Test; +HWTEST_F(WddmSimpleTestL0, givenL0ApiAndDefaultWddmCsrWhenItIsCreatedThenImmediateDispatchIsTurnedOn) { + VariableBackup backup(&apiTypeForUlts, ApiSpecificConfig::L0); + HardwareInfo *hwInfo = nullptr; + ExecutionEnvironment *executionEnvironment = getExecutionEnvironmentImpl(hwInfo, 1); + std::unique_ptr device(Device::create(executionEnvironment, 0u)); + { + std::unique_ptr> mockCsr(new MockWddmCsrL0(*executionEnvironment, 0, 1)); + EXPECT_EQ(DispatchMode::ImmediateDispatch, mockCsr->dispatchMode); + } +} \ No newline at end of file