diff --git a/level_zero/core/source/cmdlist/cmdlist_hw.inl b/level_zero/core/source/cmdlist/cmdlist_hw.inl index c061b52980..751bf1c213 100644 --- a/level_zero/core/source/cmdlist/cmdlist_hw.inl +++ b/level_zero/core/source/cmdlist/cmdlist_hw.inl @@ -1363,6 +1363,7 @@ ze_result_t CommandListCoreFamily::appendWaitOnEvents(uint32_t nu uint64_t gpuAddr = 0; constexpr uint32_t eventStateClear = static_cast(-1); + bool dcFlushRequired = false; for (uint32_t i = 0; i < numEvents; i++) { auto event = Event::fromHandle(phEvent[i]); @@ -1377,14 +1378,15 @@ ze_result_t CommandListCoreFamily::appendWaitOnEvents(uint32_t nu eventStateClear, COMPARE_OPERATION::COMPARE_OPERATION_SAD_NOT_EQUAL_SDD); - bool dcFlushEnable = (!event->waitScope) ? false : true; - if (dcFlushEnable) { - if (isCopyOnly()) { - NEO::EncodeMiFlushDW::programMiFlushDw(*commandContainer.getCommandStream(), 0, 0, false, false); - } else { - NEO::PipeControlArgs args(true); - NEO::MemorySynchronizationCommands::addPipeControl(*commandContainer.getCommandStream(), args); - } + dcFlushRequired |= (!event->waitScope) ? false : true; + } + + if (dcFlushRequired) { + if (isCopyOnly()) { + NEO::EncodeMiFlushDW::programMiFlushDw(*commandContainer.getCommandStream(), 0, 0, false, false); + } else { + NEO::PipeControlArgs args(true); + NEO::MemorySynchronizationCommands::addPipeControl(*commandContainer.getCommandStream(), args); } } diff --git a/level_zero/core/test/unit_tests/sources/cmdlist/test_cmdlist_1.cpp b/level_zero/core/test/unit_tests/sources/cmdlist/test_cmdlist_1.cpp index 967f46f55e..42e3340125 100644 --- a/level_zero/core/test/unit_tests/sources/cmdlist/test_cmdlist_1.cpp +++ b/level_zero/core/test/unit_tests/sources/cmdlist/test_cmdlist_1.cpp @@ -843,6 +843,33 @@ HWTEST_F(CommandListCreate, givenCommandListyWhenAppendWaitEventsWithDcFlushTheP EXPECT_NE(cmdList.end(), itor); } +HWTEST_F(CommandListCreate, givenCommandListyWhenAppendWaitEventsWithDcFlushThePipeControlIsProgrammedOnlyOnce) { + using PIPE_CONTROL = typename FamilyType::PIPE_CONTROL; + using SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT; + ze_result_t returnValue; + std::unique_ptr commandList(CommandList::create(productFamily, device, NEO::EngineGroupType::RenderCompute, returnValue)); + auto &commandContainer = commandList->commandContainer; + MockEvent event, event2; + event.signalScope = 0; + event.waitScope = ZE_EVENT_SCOPE_FLAG_HOST; + event2.waitScope = ZE_EVENT_SCOPE_FLAG_HOST; + ze_event_handle_t events[] = {&event, &event2}; + + commandList->appendWaitOnEvents(2, events); + GenCmdList cmdList; + ASSERT_TRUE(FamilyType::PARSE::parseCommandBuffer( + cmdList, ptrOffset(commandContainer.getCommandStream()->getCpuBase(), 0), commandContainer.getCommandStream()->getUsed())); + + auto itor = find(cmdList.begin(), cmdList.end()); + EXPECT_NE(cmdList.end(), itor); + itor++; + auto itor2 = find(itor, cmdList.end()); + EXPECT_NE(cmdList.end(), itor2); + itor2++; + auto itor3 = find(itor2, cmdList.end()); + EXPECT_EQ(cmdList.end(), itor3); +} + using Platforms = IsAtLeastProduct; HWTEST2_F(CommandListCreate, givenCopyCommandListWhenProfilingBeforeCommandForCopyOnlyThenCommandsHaveCorrectEventOffsets, Platforms) {