diff --git a/opencl/test/unit_test/command_stream/command_stream_receiver_flush_task_4_tests.cpp b/opencl/test/unit_test/command_stream/command_stream_receiver_flush_task_4_tests.cpp index 60806083b6..6865da2700 100644 --- a/opencl/test/unit_test/command_stream/command_stream_receiver_flush_task_4_tests.cpp +++ b/opencl/test/unit_test/command_stream/command_stream_receiver_flush_task_4_tests.cpp @@ -16,6 +16,8 @@ #include "opencl/test/unit_test/test_macros/test_checks_ocl.h" #include "test.h" +#include "test_traits_common.h" + using namespace NEO; using MultiRootDeviceCommandStreamReceiverBufferTests = MultiRootDeviceFixture; @@ -662,6 +664,41 @@ HWTEST_F(CommandStreamReceiverFlushTaskTests, givenStaticPartitioningEnabledWhen EXPECT_TRUE(found); } +struct PreambleThreadArbitrationMatcher { + template + static constexpr bool isMatched() { + if constexpr (HwMapper::GfxProduct::supportsCmdSet(IGFX_GEN8_CORE)) { + return TestTraits::get()>::implementsPreambleThreadArbitration; + } + return false; + } +}; + +HWTEST2_F(CommandStreamReceiverFlushTaskTests, givenVariousInputWhenFlushingTaskThenProgramThreadArbitrationPolicyWhenNeeded, PreambleThreadArbitrationMatcher) { + using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM; + auto &hwHelper = HwHelper::get(pDevice->getHardwareInfo().platform.eRenderCoreFamily); + auto &commandStreamReceiver = pDevice->getUltCommandStreamReceiver(); + + commandStreamReceiver.requiredThreadArbitrationPolicy = hwHelper.getDefaultThreadArbitrationPolicy(); + flushTask(commandStreamReceiver); + size_t parsingOffset = commandStreamReceiver.commandStream.getUsed(); + for (auto arbitrationChanged : ::testing::Bool()) { + commandStreamReceiver.lastSentThreadArbitrationPolicy = arbitrationChanged ? ThreadArbitrationPolicy::NotPresent + : hwHelper.getDefaultThreadArbitrationPolicy(); + for (auto isPreambleNeeded : ::testing::Bool()) { + commandStreamReceiver.isPreambleSent = !isPreambleNeeded; + + flushTask(commandStreamReceiver); + HardwareParse csHwParser; + csHwParser.parseCommands(commandStreamReceiver.commandStream, parsingOffset); + auto miLoadRegisterCommandsCount = findAll(csHwParser.cmdList.begin(), csHwParser.cmdList.end()).size(); + size_t expectedCount = (isPreambleNeeded ? 2 : (arbitrationChanged ? 1 : 0)); + EXPECT_EQ(expectedCount, miLoadRegisterCommandsCount); + parsingOffset = commandStreamReceiver.commandStream.getUsed(); + } + } +} + namespace CpuIntrinsicsTests { extern volatile uint32_t *pauseAddress; extern uint32_t pauseValue; diff --git a/opencl/test/unit_test/command_stream/command_stream_receiver_hw_1_tests.cpp b/opencl/test/unit_test/command_stream/command_stream_receiver_hw_1_tests.cpp index 51529ce228..4187c6ef84 100644 --- a/opencl/test/unit_test/command_stream/command_stream_receiver_hw_1_tests.cpp +++ b/opencl/test/unit_test/command_stream/command_stream_receiver_hw_1_tests.cpp @@ -140,35 +140,49 @@ HWTEST_F(UltCommandStreamReceiverTest, givenSentStateSipFlagSetAndSourceLevelDeb pDevice->setDebuggerActive(false); } -HWTEST_F(UltCommandStreamReceiverTest, givenPreambleSentAndThreadArbitrationPolicyChangedWhenEstimatingPreambleCmdSizeThenResultDependsOnPolicyProgrammingCmdSize) { +HWTEST_F(UltCommandStreamReceiverTest, givenPreambleSentAndThreadArbitrationPolicyChangedWhenEstimatingFlushTaskSizeThenResultDependsOnPolicyProgrammingCmdSize) { auto &commandStreamReceiver = pDevice->getUltCommandStreamReceiver(); commandStreamReceiver.isPreambleSent = true; commandStreamReceiver.requiredThreadArbitrationPolicy = commandStreamReceiver.lastSentThreadArbitrationPolicy; - auto policyNotChanged = commandStreamReceiver.getRequiredCmdSizeForPreamble(*pDevice); + auto policyNotChangedPreamble = commandStreamReceiver.getRequiredCmdSizeForPreamble(*pDevice); + auto policyNotChangedFlush = commandStreamReceiver.getRequiredCmdStreamSize(flushTaskFlags, *pDevice); commandStreamReceiver.requiredThreadArbitrationPolicy = commandStreamReceiver.lastSentThreadArbitrationPolicy + 1; - auto policyChanged = commandStreamReceiver.getRequiredCmdSizeForPreamble(*pDevice); + auto policyChangedPreamble = commandStreamReceiver.getRequiredCmdSizeForPreamble(*pDevice); + auto policyChangedFlush = commandStreamReceiver.getRequiredCmdStreamSize(flushTaskFlags, *pDevice); - auto actualDifference = policyChanged - policyNotChanged; - auto expectedDifference = PreambleHelper::getThreadArbitrationCommandsSize(); - EXPECT_EQ(expectedDifference, actualDifference); + auto actualDifferenceForPreamble = policyChangedPreamble - policyNotChangedPreamble; + auto actualDifferenceForFlush = policyChangedFlush - policyNotChangedFlush; + auto expectedDifference = PreambleHelper::getThreadArbitrationCommandsSize() + + commandStreamReceiver.getCmdSizeForComputeMode(); + EXPECT_EQ(0u, actualDifferenceForPreamble); + EXPECT_EQ(expectedDifference, actualDifferenceForFlush); } -HWTEST_F(UltCommandStreamReceiverTest, givenPreambleSentWhenEstimatingPreambleCmdSizeThenResultDependsOnPolicyProgrammingAndAdditionalCmdsSize) { +HWTEST_F(UltCommandStreamReceiverTest, givenPreambleSentWhenEstimatingFlushTaskSizeThenResultDependsOnPolicyProgrammingAndAdditionalCmdsSize) { auto &commandStreamReceiver = pDevice->getUltCommandStreamReceiver(); commandStreamReceiver.requiredThreadArbitrationPolicy = commandStreamReceiver.lastSentThreadArbitrationPolicy; commandStreamReceiver.isPreambleSent = false; - auto preambleNotSent = commandStreamReceiver.getRequiredCmdSizeForPreamble(*pDevice); + auto preambleNotSentPreamble = commandStreamReceiver.getRequiredCmdSizeForPreamble(*pDevice); + auto preambleNotSentFlush = commandStreamReceiver.getRequiredCmdStreamSize(flushTaskFlags, *pDevice); commandStreamReceiver.isPreambleSent = true; - auto preambleSent = commandStreamReceiver.getRequiredCmdSizeForPreamble(*pDevice); + auto preambleSentPreamble = commandStreamReceiver.getRequiredCmdSizeForPreamble(*pDevice); + auto preambleSentFlush = commandStreamReceiver.getRequiredCmdStreamSize(flushTaskFlags, *pDevice); - auto actualDifference = preambleNotSent - preambleSent; - auto expectedDifference = PreambleHelper::getThreadArbitrationCommandsSize() + PreambleHelper::getAdditionalCommandsSize(*pDevice); + auto actualDifferenceForPreamble = preambleNotSentPreamble - preambleSentPreamble; + auto actualDifferenceForFlush = preambleNotSentFlush - preambleSentFlush; - EXPECT_EQ(expectedDifference, actualDifference); + commandStreamReceiver.isPreambleSent = false; + auto expectedDifferenceForPreamble = PreambleHelper::getAdditionalCommandsSize(*pDevice); + auto expectedDifferenceForFlush = expectedDifferenceForPreamble + PreambleHelper::getThreadArbitrationCommandsSize() + + commandStreamReceiver.getCmdSizeForL3Config() + + PreambleHelper::getCmdSizeForPipelineSelect(pDevice->getHardwareInfo()); + + EXPECT_EQ(expectedDifferenceForPreamble, actualDifferenceForPreamble); + EXPECT_EQ(expectedDifferenceForFlush, actualDifferenceForFlush); } HWCMDTEST_F(IGFX_GEN8_CORE, UltCommandStreamReceiverTest, givenMediaVfeStateDirtyEstimatingPreambleCmdSizeThenResultDependsVfeStateProgrammingCmdSize) { @@ -218,12 +232,12 @@ HWTEST_F(UltCommandStreamReceiverTest, givenPreambleSentAndForceSemaphoreDelayBe auto preambleSent = commandStreamReceiver.getRequiredCmdSizeForPreamble(*pDevice); auto actualDifferenceWhenSemaphoreDelayNotReprogrammed = preambleNotSentAndSemaphoreDelayNotReprogrammed - preambleSent; - auto expectedDifference = PreambleHelper::getThreadArbitrationCommandsSize() + PreambleHelper::getAdditionalCommandsSize(*pDevice); + auto expectedDifference = PreambleHelper::getAdditionalCommandsSize(*pDevice); EXPECT_EQ(expectedDifference, actualDifferenceWhenSemaphoreDelayNotReprogrammed); auto actualDifferenceWhenSemaphoreDelayReprogrammed = preambleNotSentAndSemaphoreDelayReprogrammed - preambleSent; - expectedDifference = PreambleHelper::getThreadArbitrationCommandsSize() + PreambleHelper::getAdditionalCommandsSize(*pDevice) + PreambleHelper::getSemaphoreDelayCommandSize(); + expectedDifference = PreambleHelper::getAdditionalCommandsSize(*pDevice) + PreambleHelper::getSemaphoreDelayCommandSize(); EXPECT_EQ(expectedDifference, actualDifferenceWhenSemaphoreDelayReprogrammed); } diff --git a/shared/source/command_stream/command_stream_receiver_hw_base.inl b/shared/source/command_stream/command_stream_receiver_hw_base.inl index a1dd0f719f..bb58d8e43f 100644 --- a/shared/source/command_stream/command_stream_receiver_hw_base.inl +++ b/shared/source/command_stream/command_stream_receiver_hw_base.inl @@ -129,9 +129,6 @@ inline size_t CommandStreamReceiverHw::getRequiredCmdSizeForPreamble( if (!this->isPreambleSent) { size += PreambleHelper::getAdditionalCommandsSize(device); } - if (!this->isPreambleSent || this->lastSentThreadArbitrationPolicy != this->requiredThreadArbitrationPolicy) { - size += PreambleHelper::getThreadArbitrationCommandsSize(); - } if (!this->isPreambleSent) { if (DebugManager.flags.ForceSemaphoreDelayBetweenWaits.get() > -1) { size += PreambleHelper::getSemaphoreDelayCommandSize(); @@ -333,6 +330,7 @@ CompletionStamp CommandStreamReceiverHw::flushTask( pageTableManagerInitialized = pageTableManager->initPageTableManagerRegisters(this); } + bool isPreambleNeeded = !this->isPreambleSent; programHardwareContext(commandStreamCSR); programComputeMode(commandStreamCSR, dispatchFlags, device.getHardwareInfo()); programPipelineSelect(commandStreamCSR, dispatchFlags.pipelineSelectArgs); @@ -342,7 +340,7 @@ CompletionStamp CommandStreamReceiverHw::flushTask( addPipeControlBefore3dState(commandStreamCSR, dispatchFlags); programPerDssBackedBuffer(commandStreamCSR, device, dispatchFlags); - if (this->lastSentThreadArbitrationPolicy != this->requiredThreadArbitrationPolicy) { + if (this->lastSentThreadArbitrationPolicy != this->requiredThreadArbitrationPolicy || isPreambleNeeded) { PreambleHelper::programThreadArbitration(&commandStreamCSR, this->requiredThreadArbitrationPolicy); this->lastSentThreadArbitrationPolicy = this->requiredThreadArbitrationPolicy; } @@ -824,6 +822,10 @@ size_t CommandStreamReceiverHw::getRequiredCmdStreamSize(const Dispat size += TimestampPacketHelper::getRequiredCmdStreamSize(dispatchFlags.csrDependencies); size += TimestampPacketHelper::getRequiredCmdStreamSizeForTaskCountContainer(dispatchFlags.csrDependencies); + if (!this->isPreambleSent || this->lastSentThreadArbitrationPolicy != this->requiredThreadArbitrationPolicy) { + size += PreambleHelper::getThreadArbitrationCommandsSize(); + } + if (stallingCommandsOnNextFlushRequired) { size += getCmdSizeForStallingCommands(dispatchFlags); } diff --git a/shared/source/helpers/preamble_base.inl b/shared/source/helpers/preamble_base.inl index e0eb320232..b4952fade2 100644 --- a/shared/source/helpers/preamble_base.inl +++ b/shared/source/helpers/preamble_base.inl @@ -77,7 +77,6 @@ template void PreambleHelper::programPreamble(LinearStream *pCommandStream, Device &device, uint32_t l3Config, uint32_t requiredThreadArbitrationPolicy, GraphicsAllocation *preemptionCsr) { programL3(pCommandStream, l3Config); - programThreadArbitration(pCommandStream, requiredThreadArbitrationPolicy); programPreemption(pCommandStream, device, preemptionCsr); if (device.isDebuggerActive()) { programKernelDebugging(pCommandStream); diff --git a/shared/test/common/gen11/test_preamble_gen11.cpp b/shared/test/common/gen11/test_preamble_gen11.cpp index c3180b1eb7..1bb2351cd6 100644 --- a/shared/test/common/gen11/test_preamble_gen11.cpp +++ b/shared/test/common/gen11/test_preamble_gen11.cpp @@ -115,7 +115,7 @@ GEN11TEST_F(PreemptionWatermarkGen11, WhenPreambleIsCreatedThenWorkAroundsIsNotP } typedef PreambleFixture ThreadArbitrationGen11; -GEN11TEST_F(ThreadArbitrationGen11, givenPreambleWhenItIsProgrammedThenThreadArbitrationIsSet) { +GEN11TEST_F(ThreadArbitrationGen11, givenPreambleWhenItIsProgrammedThenThreadArbitrationIsNotSet) { DebugManagerStateRestore dbgRestore; DebugManager.flags.ForcePreemptionMode.set(static_cast(PreemptionMode::Disabled)); typedef ICLFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM; @@ -129,6 +129,28 @@ GEN11TEST_F(ThreadArbitrationGen11, givenPreambleWhenItIsProgrammedThenThreadArb parseCommands(cs); + auto ppC = find(cmdList.begin(), cmdList.end()); + ASSERT_EQ(cmdList.end(), ppC); + + auto cmd = findMmioCmd(cmdList.begin(), cmdList.end(), RowChickenReg4::address); + ASSERT_EQ(nullptr, cmd); + + MockDevice device; + EXPECT_EQ(0u, PreambleHelper::getAdditionalCommandsSize(device)); + EXPECT_EQ(sizeof(MI_LOAD_REGISTER_IMM) + sizeof(PIPE_CONTROL), PreambleHelper::getThreadArbitrationCommandsSize()); +} + +GEN11TEST_F(ThreadArbitrationGen11, whenThreadArbitrationPolicyIsProgrammedThenCorrectValuesAreSet) { + DebugManagerStateRestore dbgRestore; + DebugManager.flags.ForcePreemptionMode.set(static_cast(PreemptionMode::Disabled)); + typedef ICLFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM; + typedef ICLFamily::PIPE_CONTROL PIPE_CONTROL; + LinearStream &cs = linearStream; + MockDevice mockDevice; + PreambleHelper::programThreadArbitration(&linearStream, ThreadArbitrationPolicy::RoundRobin); + + parseCommands(cs); + auto ppC = find(cmdList.begin(), cmdList.end()); ASSERT_NE(ppC, cmdList.end()); @@ -186,4 +208,4 @@ GEN11TEST_F(PreambleFixtureGen11, whenKernelDebuggingCommandsAreProgrammedThenCo pCmd = reinterpret_cast(*it); EXPECT_EQ(0xe400u, pCmd->getRegisterOffset()); EXPECT_EQ((1u << 7) | (1u << 4), pCmd->getDataDword()); -} \ No newline at end of file +} diff --git a/shared/test/common/gen11/test_traits_gen11.h b/shared/test/common/gen11/test_traits_gen11.h index 399d73c32f..c6419dac41 100644 --- a/shared/test/common/gen11/test_traits_gen11.h +++ b/shared/test/common/gen11/test_traits_gen11.h @@ -16,4 +16,5 @@ struct TestTraits { static constexpr bool auxTranslationSupported = false; static constexpr bool isUsingNonDefaultIoctls = false; static constexpr bool deviceEnqueueSupport = true; + static constexpr bool implementsPreambleThreadArbitration = true; }; diff --git a/shared/test/common/gen12lp/test_traits_gen12lp.h b/shared/test/common/gen12lp/test_traits_gen12lp.h index 653738108a..2ac92fce03 100644 --- a/shared/test/common/gen12lp/test_traits_gen12lp.h +++ b/shared/test/common/gen12lp/test_traits_gen12lp.h @@ -16,4 +16,5 @@ struct TestTraits { static constexpr bool auxTranslationSupported = true; static constexpr bool isUsingNonDefaultIoctls = false; static constexpr bool deviceEnqueueSupport = false; + static constexpr bool implementsPreambleThreadArbitration = false; }; diff --git a/shared/test/common/gen8/test_traits_gen8.h b/shared/test/common/gen8/test_traits_gen8.h index c7ef14bdaf..760cd645c5 100644 --- a/shared/test/common/gen8/test_traits_gen8.h +++ b/shared/test/common/gen8/test_traits_gen8.h @@ -15,4 +15,5 @@ struct TestTraits { static constexpr bool iohInSbaSupported = true; static constexpr bool isUsingNonDefaultIoctls = false; static constexpr bool deviceEnqueueSupport = false; + static constexpr bool implementsPreambleThreadArbitration = false; }; diff --git a/shared/test/common/gen9/preamble_tests_gen9.cpp b/shared/test/common/gen9/preamble_tests_gen9.cpp index 5c9f877c4a..656e0720ea 100644 --- a/shared/test/common/gen9/preamble_tests_gen9.cpp +++ b/shared/test/common/gen9/preamble_tests_gen9.cpp @@ -6,6 +6,7 @@ */ #include "shared/test/common/helpers/debug_manager_state_restore.h" +#include "shared/test/unit_test/preamble/preamble_fixture.h" #include "shared/test/unit_test/source_level_debugger/source_level_debugger_preamble_test.h" #include "gtest/gtest.h" @@ -61,3 +62,59 @@ GEN9TEST_F(PreambleTestGen9, givenGen9ThenL3IsProgrammed) { EXPECT_EQ(l3ConfigDifference, isL3Programmable); } + +using ThreadArbitrationGen9 = PreambleFixture; +GEN9TEST_F(ThreadArbitrationGen9, givenPreambleWhenItIsProgrammedThenThreadArbitrationIsNotSet) { + DebugManagerStateRestore dbgRestore; + DebugManager.flags.ForcePreemptionMode.set(static_cast(PreemptionMode::Disabled)); + typedef SKLFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM; + typedef SKLFamily::PIPE_CONTROL PIPE_CONTROL; + LinearStream &cs = linearStream; + uint32_t l3Config = PreambleHelper::getL3Config(*defaultHwInfo, true); + MockDevice mockDevice; + PreambleHelper::programPreamble(&linearStream, mockDevice, l3Config, + ThreadArbitrationPolicy::RoundRobin, + nullptr); + + parseCommands(cs); + + auto ppC = find(cmdList.begin(), cmdList.end()); + ASSERT_EQ(cmdList.end(), ppC); + + auto itorLRI = reverse_find(cmdList.rbegin(), cmdList.rend()); + ASSERT_NE(cmdList.rend(), itorLRI); + + const auto &lri = *reinterpret_cast(*itorLRI); + EXPECT_NE(0xE404u, lri.getRegisterOffset()); + EXPECT_NE(0x100u, lri.getDataDword()); + + MockDevice device; + EXPECT_EQ(0u, PreambleHelper::getAdditionalCommandsSize(device)); + EXPECT_EQ(sizeof(MI_LOAD_REGISTER_IMM) + sizeof(PIPE_CONTROL), PreambleHelper::getThreadArbitrationCommandsSize()); +} + +GEN9TEST_F(ThreadArbitrationGen9, whenThreadArbitrationPolicyIsProgrammedThenCorrectValuesAreSet) { + DebugManagerStateRestore dbgRestore; + DebugManager.flags.ForcePreemptionMode.set(static_cast(PreemptionMode::Disabled)); + typedef SKLFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM; + typedef SKLFamily::PIPE_CONTROL PIPE_CONTROL; + LinearStream &cs = linearStream; + MockDevice mockDevice; + PreambleHelper::programThreadArbitration(&linearStream, ThreadArbitrationPolicy::RoundRobin); + + parseCommands(cs); + + auto ppC = find(cmdList.begin(), cmdList.end()); + ASSERT_NE(ppC, cmdList.end()); + + auto itorLRI = reverse_find(cmdList.rbegin(), cmdList.rend()); + ASSERT_NE(cmdList.rend(), itorLRI); + + const auto &lri = *reinterpret_cast(*itorLRI); + EXPECT_EQ(0xE404u, lri.getRegisterOffset()); + EXPECT_EQ(0x100u, lri.getDataDword()); + + MockDevice device; + EXPECT_EQ(0u, PreambleHelper::getAdditionalCommandsSize(device)); + EXPECT_EQ(sizeof(MI_LOAD_REGISTER_IMM) + sizeof(PIPE_CONTROL), PreambleHelper::getThreadArbitrationCommandsSize()); +} diff --git a/shared/test/common/gen9/skl/test_preamble_skl.cpp b/shared/test/common/gen9/skl/test_preamble_skl.cpp index da1cfcd36f..7c9bbf4819 100644 --- a/shared/test/common/gen9/skl/test_preamble_skl.cpp +++ b/shared/test/common/gen9/skl/test_preamble_skl.cpp @@ -71,35 +71,6 @@ SKLTEST_F(Gen9L3Config, GivenSlmWhenProgrammingL3ThenProgrammingIsCorrect) { } typedef PreambleFixture ThreadArbitration; -SKLTEST_F(ThreadArbitration, givenPreambleWhenItIsProgrammedThenThreadArbitrationIsSetToRoundRobin) { - DebugManagerStateRestore dbgRestore; - DebugManager.flags.ForcePreemptionMode.set(static_cast(PreemptionMode::Disabled)); - typedef SKLFamily::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM; - typedef SKLFamily::PIPE_CONTROL PIPE_CONTROL; - LinearStream &cs = linearStream; - uint32_t l3Config = PreambleHelper::getL3Config(*defaultHwInfo, true); - MockDevice mockDevice; - PreambleHelper::programPreamble(&linearStream, mockDevice, l3Config, - ThreadArbitrationPolicy::RoundRobin, - nullptr); - - parseCommands(cs); - - auto ppC = find(cmdList.begin(), cmdList.end()); - ASSERT_NE(ppC, cmdList.end()); - - auto itorLRI = reverse_find(cmdList.rbegin(), cmdList.rend()); - ASSERT_NE(cmdList.rend(), itorLRI); - - const auto &lri = *reinterpret_cast(*itorLRI); - EXPECT_EQ(0xE404u, lri.getRegisterOffset()); - EXPECT_EQ(0x100u, lri.getDataDword()); - - MockDevice device; - EXPECT_EQ(0u, PreambleHelper::getAdditionalCommandsSize(device)); - EXPECT_EQ(sizeof(MI_LOAD_REGISTER_IMM) + sizeof(PIPE_CONTROL), PreambleHelper::getThreadArbitrationCommandsSize()); -} - SKLTEST_F(ThreadArbitration, GivenDefaultWhenProgrammingPreambleThenArbitrationPolicyIsRoundRobin) { EXPECT_EQ(ThreadArbitrationPolicy::RoundRobin, HwHelperHw::get().getDefaultThreadArbitrationPolicy()); } diff --git a/shared/test/common/gen9/test_traits_gen9.h b/shared/test/common/gen9/test_traits_gen9.h index e089bd7836..8cf6f6bf2b 100644 --- a/shared/test/common/gen9/test_traits_gen9.h +++ b/shared/test/common/gen9/test_traits_gen9.h @@ -15,4 +15,5 @@ struct TestTraits { static constexpr bool iohInSbaSupported = true; static constexpr bool isUsingNonDefaultIoctls = false; static constexpr bool deviceEnqueueSupport = true; + static constexpr bool implementsPreambleThreadArbitration = true; };