From 469ab367b10f2ef18eec8a11e0792ec6e52f0ebc Mon Sep 17 00:00:00 2001 From: Zbigniew Zdanowicz Date: Tue, 26 Jul 2022 13:54:00 +0000 Subject: [PATCH] Limit number of pipeline select commands when using multiple command queues Related-To: NEO-7187 Signed-off-by: Zbigniew Zdanowicz --- .../core/source/cmdqueue/cmdqueue_hw.inl | 3 +- .../core/source/cmdqueue/cmdqueue_imp.h | 1 - .../test_cmdqueue_enqueue_cmdlist_2.cpp | 62 +++++++++++++++++++ .../command_stream/command_stream_receiver.h | 8 +++ .../command_stream_receiver_tests.cpp | 6 ++ 5 files changed, 78 insertions(+), 2 deletions(-) diff --git a/level_zero/core/source/cmdqueue/cmdqueue_hw.inl b/level_zero/core/source/cmdqueue/cmdqueue_hw.inl index 3dc8ef3bf8..a04ee088e5 100644 --- a/level_zero/core/source/cmdqueue/cmdqueue_hw.inl +++ b/level_zero/core/source/cmdqueue/cmdqueue_hw.inl @@ -251,6 +251,7 @@ ze_result_t CommandQueueHw::executeCommandLists( gsbaStateDirty |= csr->getGSBAStateDirty(); frontEndStateDirty |= csr->getMediaVFEStateDirty(); + bool gpgpuEnabled = csr->getPreambleSetFlag(); if (!isCopyOnlyCommandQueue) { if (!gpgpuEnabled) { @@ -315,6 +316,7 @@ ze_result_t CommandQueueHw::executeCommandLists( if (!isCopyOnlyCommandQueue) { if (!gpgpuEnabled) { programPipelineSelect(child); + csr->setPreambleSetFlag(true); } if (NEO::Debugger::isDebugEnabled(internalUsage) && !commandQueueDebugCmdsProgrammed) { @@ -585,7 +587,6 @@ template void CommandQueueHw::programPipelineSelect(NEO::LinearStream &commandStream) { NEO::PipelineSelectArgs args = {0, 0}; NEO::PreambleHelper::programPipelineSelect(&commandStream, args, device->getHwInfo()); - gpgpuEnabled = true; } template diff --git a/level_zero/core/source/cmdqueue/cmdqueue_imp.h b/level_zero/core/source/cmdqueue/cmdqueue_imp.h index 00ec9e6dae..4d41408c3d 100644 --- a/level_zero/core/source/cmdqueue/cmdqueue_imp.h +++ b/level_zero/core/source/cmdqueue/cmdqueue_imp.h @@ -101,7 +101,6 @@ struct CommandQueueImp : public CommandQueue { std::atomic taskCount{0}; - bool gpgpuEnabled = false; bool useKmdWaitFunction = false; }; diff --git a/level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue_enqueue_cmdlist_2.cpp b/level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue_enqueue_cmdlist_2.cpp index b47639f374..f504a7d76c 100644 --- a/level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue_enqueue_cmdlist_2.cpp +++ b/level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue_enqueue_cmdlist_2.cpp @@ -121,5 +121,67 @@ HWTEST2_F(CommandQueueExecuteCommandListsSimpleTest, whenUsingFenceThenLastPipeC commandQueue->destroy(); } +HWTEST2_F(CommandQueueExecuteCommandListsSimpleTest, givenTwoCommandQueuesUsingSingleCsrWhenExecutingFirstTimeOnBothThenPipelineSelectProgrammedOnce, IsAtMostXeHpcCore) { + using PIPELINE_SELECT = typename FamilyType::PIPELINE_SELECT; + + bool additionalPipelineSelect = NEO::HwInfoConfig::get(device->getHwInfo().platform.eProductFamily)->is3DPipelineSelectWARequired() && + neoDevice->getDefaultEngine().commandStreamReceiver->isRcs(); + + ze_result_t returnValue; + + ze_command_list_handle_t commandList = CommandList::create(productFamily, device, NEO::EngineGroupType::RenderCompute, 0u, returnValue)->toHandle(); + ASSERT_EQ(ZE_RESULT_SUCCESS, returnValue); + + ze_command_queue_desc_t queueDesc = {}; + queueDesc.mode = ZE_COMMAND_QUEUE_MODE_ASYNCHRONOUS; + auto commandQueue = whiteboxCast(CommandQueue::create(productFamily, device, neoDevice->getDefaultEngine().commandStreamReceiver, &queueDesc, false, false, returnValue)); + ASSERT_EQ(ZE_RESULT_SUCCESS, returnValue); + ASSERT_NE(nullptr, commandQueue->commandStream); + + auto usedSpaceBefore = commandQueue->commandStream->getUsed(); + returnValue = commandQueue->executeCommandLists(1, &commandList, nullptr, false); + ASSERT_EQ(ZE_RESULT_SUCCESS, returnValue); + auto usedSpaceAfter = commandQueue->commandStream->getUsed(); + ASSERT_GT(usedSpaceAfter, usedSpaceBefore); + + GenCmdList cmdList; + ASSERT_TRUE(FamilyType::PARSE::parseCommandBuffer( + cmdList, + ptrOffset(commandQueue->commandStream->getCpuBase(), usedSpaceBefore), + usedSpaceAfter - usedSpaceBefore)); + + auto pipelineSelect = findAll(cmdList.begin(), cmdList.end()); + size_t expectedFirstPipelineSelectCount = 1u; + if (additionalPipelineSelect) { + expectedFirstPipelineSelectCount += 2; + } + EXPECT_EQ(expectedFirstPipelineSelectCount, pipelineSelect.size()); + + cmdList.clear(); + + auto commandQueue2 = whiteboxCast(CommandQueue::create(productFamily, device, neoDevice->getDefaultEngine().commandStreamReceiver, &queueDesc, false, false, returnValue)); + ASSERT_EQ(ZE_RESULT_SUCCESS, returnValue); + ASSERT_NE(nullptr, commandQueue2->commandStream); + + usedSpaceBefore = commandQueue2->commandStream->getUsed(); + returnValue = commandQueue2->executeCommandLists(1, &commandList, nullptr, false); + ASSERT_EQ(ZE_RESULT_SUCCESS, returnValue); + usedSpaceAfter = commandQueue2->commandStream->getUsed(); + ASSERT_GT(usedSpaceAfter, usedSpaceBefore); + + ASSERT_TRUE(FamilyType::PARSE::parseCommandBuffer( + cmdList, + ptrOffset(commandQueue2->commandStream->getCpuBase(), usedSpaceBefore), + usedSpaceAfter - usedSpaceBefore)); + + pipelineSelect = findAll(cmdList.begin(), cmdList.end()); + constexpr size_t expectedSecondPipelineSelectCount = 0u; + EXPECT_EQ(expectedSecondPipelineSelectCount, pipelineSelect.size()); + + CommandList::fromHandle(commandList)->destroy(); + commandQueue->destroy(); + commandQueue2->destroy(); +} + } // namespace ult } // namespace L0 diff --git a/shared/source/command_stream/command_stream_receiver.h b/shared/source/command_stream/command_stream_receiver.h index 072e7034dc..2401ffcd5f 100644 --- a/shared/source/command_stream/command_stream_receiver.h +++ b/shared/source/command_stream/command_stream_receiver.h @@ -340,6 +340,14 @@ class CommandStreamReceiver { LogicalStateHelper *getLogicalStateHelper() const; + bool getPreambleSetFlag() const { + return isPreambleSent; + } + + void setPreambleSetFlag(bool value) { + isPreambleSent = value; + } + protected: void cleanupResources(); void printDeviceIndex(); 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 06fc36f20b..eb2e755b23 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 @@ -2097,3 +2097,9 @@ HWTEST_F(CommandStreamReceiverTest, givenMultipleActivePartitionsWhenWaitLogIsEn EXPECT_STREQ(expectedOutput.str().c_str(), output.c_str()); } + +TEST_F(CommandStreamReceiverTest, givenPreambleFlagIsSetWhenGettingFlagStateThenExpectCorrectState) { + EXPECT_FALSE(commandStreamReceiver->getPreambleSetFlag()); + commandStreamReceiver->setPreambleSetFlag(true); + EXPECT_TRUE(commandStreamReceiver->getPreambleSetFlag()); +}