From f235ba015eaf25a047f89ff8800e5a806e129e01 Mon Sep 17 00:00:00 2001 From: "Chodor, Jaroslaw" Date: Mon, 8 Jan 2018 16:13:51 +0100 Subject: [PATCH] Refactoring preemption tests Change-Id: I7e34f12e7d974e24cc63aaaad77d293b744d1c74 --- .../command_stream_receiver_hw.inl | 6 +- runtime/command_stream/preemption.h | 6 +- runtime/gen8/preemption.cpp | 6 +- runtime/gen9/preemption.cpp | 6 +- unit_tests/fixtures/preemption_fixture.h | 21 +++ unit_tests/gen8/test_preemption.cpp | 93 +++--------- unit_tests/gen9/test_preemption.cpp | 134 ++++-------------- unit_tests/preemption/preemption_tests.cpp | 77 ++++++++++ 8 files changed, 151 insertions(+), 198 deletions(-) diff --git a/runtime/command_stream/command_stream_receiver_hw.inl b/runtime/command_stream/command_stream_receiver_hw.inl index 92409e98de..f11b5e6551 100644 --- a/runtime/command_stream/command_stream_receiver_hw.inl +++ b/runtime/command_stream/command_stream_receiver_hw.inl @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Intel Corporation + * Copyright (c) 2018, Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -503,7 +503,7 @@ size_t CommandStreamReceiverHw::getRequiredCsrSize() { size += getCmdSizeForCoherency(); if (csrSizeRequestFlags.preemptionRequestChanged) { - size += PreemptionHelper::getRequiredCsrSize(memoryManager->device->getPreemptionMode()); + size += PreemptionHelper::getRequiredCmdStreamSize(memoryManager->device->getPreemptionMode()); } return alignUp(size, MemoryConstants::cacheLineSize); } @@ -531,7 +531,7 @@ inline void CommandStreamReceiverHw::waitForTaskCountWithKmdNotifyFal template inline void CommandStreamReceiverHw::programPreemption(LinearStream &csr, DispatchFlags &dispatchFlags) { if (csrSizeRequestFlags.preemptionRequestChanged) { - PreemptionHelper::programPreemptionMode(&csr, dispatchFlags.preemptionMode, preemptionCsrAllocation, nullptr); + PreemptionHelper::programCmdStream(&csr, dispatchFlags.preemptionMode, preemptionCsrAllocation, nullptr); this->lastPreemptionMode = dispatchFlags.preemptionMode; } } diff --git a/runtime/command_stream/preemption.h b/runtime/command_stream/preemption.h index cc3e973bfe..e589ebc547 100644 --- a/runtime/command_stream/preemption.h +++ b/runtime/command_stream/preemption.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Intel Corporation + * Copyright (c) 2018, Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -39,10 +39,10 @@ class PreemptionHelper { static void adjustDefaultPreemptionMode(RuntimeCapabilityTable &deviceCapabilities, bool allowMidThread, bool allowThreadGroup, bool allowMidBatch); template - static void programPreemptionMode(LinearStream *cmdStream, PreemptionMode &preemptionMode, GraphicsAllocation *preemptionCsr, GraphicsAllocation *sipKernel); + static void programCmdStream(LinearStream *cmdStream, PreemptionMode &preemptionMode, GraphicsAllocation *preemptionCsr, GraphicsAllocation *sipKernel); template - static size_t getRequiredCsrSize(PreemptionMode preemptionMode); + static size_t getRequiredCmdStreamSize(PreemptionMode preemptionMode); template static size_t getPreemptionWaCsSize(const Device &device); diff --git a/runtime/gen8/preemption.cpp b/runtime/gen8/preemption.cpp index 17a28ebb5b..daca46931e 100644 --- a/runtime/gen8/preemption.cpp +++ b/runtime/gen8/preemption.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Intel Corporation + * Copyright (c) 2018, Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -35,7 +35,7 @@ static constexpr uint32_t cmdLevelVal = (1 << 2); }; // namespace PreemptionBDW template <> -void PreemptionHelper::programPreemptionMode(LinearStream *cmdStream, PreemptionMode &preemptionMode, GraphicsAllocation *preemptionCsr, GraphicsAllocation *sipKernel) { +void PreemptionHelper::programCmdStream(LinearStream *cmdStream, PreemptionMode &preemptionMode, GraphicsAllocation *preemptionCsr, GraphicsAllocation *sipKernel) { uint32_t regVal = 0; if (preemptionMode == PreemptionMode::ThreadGroup) { regVal = PreemptionBDW::threadGroupVal; @@ -47,7 +47,7 @@ void PreemptionHelper::programPreemptionMode(LinearStream *cmdStream, } template <> -size_t PreemptionHelper::getRequiredCsrSize(PreemptionMode preemptionMode) { +size_t PreemptionHelper::getRequiredCmdStreamSize(PreemptionMode preemptionMode) { return sizeof(typename GfxFamily::MI_LOAD_REGISTER_IMM); } diff --git a/runtime/gen9/preemption.cpp b/runtime/gen9/preemption.cpp index 107a5ffa55..61ba4c4f8b 100644 --- a/runtime/gen9/preemption.cpp +++ b/runtime/gen9/preemption.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Intel Corporation + * Copyright (c) 2018, Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -40,7 +40,7 @@ static constexpr uint32_t midThreadVal = 0; }; // namespace PreemptionSKL template <> -void PreemptionHelper::programPreemptionMode(LinearStream *cmdStream, PreemptionMode &preemptionMode, GraphicsAllocation *preemptionCsr, GraphicsAllocation *sipKernel) { +void PreemptionHelper::programCmdStream(LinearStream *cmdStream, PreemptionMode &preemptionMode, GraphicsAllocation *preemptionCsr, GraphicsAllocation *sipKernel) { uint32_t regVal = 0; if (preemptionMode == PreemptionMode::MidThread) { regVal = PreemptionSKL::midThreadVal | PreemptionSKL::mask; @@ -61,7 +61,7 @@ void PreemptionHelper::programPreemptionMode(LinearStream *cmdStream, } template <> -size_t PreemptionHelper::getRequiredCsrSize(PreemptionMode preemptionMode) { +size_t PreemptionHelper::getRequiredCmdStreamSize(PreemptionMode preemptionMode) { size_t size = sizeof(typename GfxFamily::MI_LOAD_REGISTER_IMM); if (preemptionMode == PreemptionMode::MidThread) { size += sizeof(typename GfxFamily::GPGPU_CSR_BASE_ADDRESS); diff --git a/unit_tests/fixtures/preemption_fixture.h b/unit_tests/fixtures/preemption_fixture.h index ad4ff0dc20..5c5d0bc5d6 100644 --- a/unit_tests/fixtures/preemption_fixture.h +++ b/unit_tests/fixtures/preemption_fixture.h @@ -29,6 +29,8 @@ #include #include +#include +#include namespace iOpenCL { struct SPatchExecutionEnvironment; @@ -90,3 +92,22 @@ struct MidThreadPreemptionEnqueueKernelTest : OCLRT::PreemptionEnqueueKernelTest OCLRT::HardwareInfo *globalHwInfo; OCLRT::PreemptionMode originalPreemptionMode; }; + +struct PreemptionTestHwDetails { + struct PreemptionModeHashT { + auto operator()(const OCLRT::PreemptionMode &preemptionMode) const -> std::underlying_type::type { + return static_cast::type>(preemptionMode); + } + }; + + bool supportsPreemptionProgramming() const { + return modeToRegValueMap.size() > 0; + } + + uint32_t regAddress = 0; + std::unordered_map modeToRegValueMap; + uint32_t defaultRegValue = 0; +}; + +template +PreemptionTestHwDetails GetPreemptionTestHwDetails(); diff --git a/unit_tests/gen8/test_preemption.cpp b/unit_tests/gen8/test_preemption.cpp index 76d33f01fd..433399c63d 100644 --- a/unit_tests/gen8/test_preemption.cpp +++ b/unit_tests/gen8/test_preemption.cpp @@ -21,6 +21,7 @@ */ #include "runtime/command_stream/preemption.h" +#include "runtime/helpers/hw_helper.h" #include "unit_tests/command_queue/enqueue_fixture.h" #include "unit_tests/helpers/hw_parse.h" #include "unit_tests/fixtures/hello_world_fixture.h" @@ -32,66 +33,21 @@ using namespace OCLRT; -typedef DevicePreemptionTests Gen8PreemptionTests; -typedef PreemptionEnqueueKernelTest Gen8PreemptionEnqueueKernelTest; +using Gen8PreemptionTests = DevicePreemptionTests; +using Gen8PreemptionEnqueueKernelTest = PreemptionEnqueueKernelTest; -GEN8TEST_F(Gen8PreemptionTests, programThreadGroupPreemptionLri) { - preemptionMode = PreemptionMode::ThreadGroup; - typedef typename FamilyType::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM; - size_t requiredSize = PreemptionHelper::getRequiredCsrSize(preemptionMode); - size_t expectedSize = sizeof(MI_LOAD_REGISTER_IMM); - EXPECT_EQ(expectedSize, requiredSize); - auto &cmdStream = cmdQ->getCS(requiredSize); - - EXPECT_TRUE(PreemptionHelper::allowThreadGroupPreemption(kernel.get(), waTable)); - - PreemptionHelper::programPreemptionMode(&cmdStream, preemptionMode, nullptr, nullptr); - EXPECT_EQ(sizeof(MI_LOAD_REGISTER_IMM), cmdStream.getUsed()); - - auto lri = (MI_LOAD_REGISTER_IMM *)cmdStream.getBase(); - EXPECT_EQ(0x2248u, lri->getRegisterOffset()); - uint32_t expectedData = 0; - EXPECT_EQ(expectedData, lri->getDataDword()); +template <> +PreemptionTestHwDetails GetPreemptionTestHwDetails() { + PreemptionTestHwDetails ret; + ret.modeToRegValueMap[PreemptionMode::ThreadGroup] = 0; + ret.modeToRegValueMap[PreemptionMode::MidBatch] = (1 << 2); + ret.defaultRegValue = ret.modeToRegValueMap[PreemptionMode::MidBatch]; + ret.regAddress = 0x2248u; + return ret; } -GEN8TEST_F(Gen8PreemptionTests, programMidBatchPreemptionLri) { - preemptionMode = PreemptionMode::MidBatch; - typedef typename FamilyType::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM; - size_t requiredSize = PreemptionHelper::getRequiredCsrSize(preemptionMode); - size_t expectedSize = sizeof(MI_LOAD_REGISTER_IMM); - EXPECT_EQ(expectedSize, requiredSize); - - auto &cmdStream = cmdQ->getCS(requiredSize); - +GEN8TEST_F(Gen8PreemptionTests, allowThreadGroupPreemptionReturnsTrue) { EXPECT_TRUE(PreemptionHelper::allowThreadGroupPreemption(kernel.get(), waTable)); - - PreemptionHelper::programPreemptionMode(&cmdStream, preemptionMode, nullptr, nullptr); - EXPECT_EQ(requiredSize, cmdStream.getUsed()); - - auto lri = (MI_LOAD_REGISTER_IMM *)cmdStream.getBase(); - EXPECT_EQ(0x2248u, lri->getRegisterOffset()); - uint32_t expectedData = DwordBuilder::build(2, false); - EXPECT_EQ(expectedData, lri->getDataDword()); -} - -GEN8TEST_F(Gen8PreemptionTests, programPreemptionLri) { - preemptionMode = PreemptionMode::ThreadGroup; - typedef typename FamilyType::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM; - size_t requiredSize = PreemptionHelper::getRequiredCsrSize(preemptionMode); - size_t expectedSize = sizeof(MI_LOAD_REGISTER_IMM); - EXPECT_EQ(expectedSize, requiredSize); - auto &cmdStream = cmdQ->getCS(requiredSize); - - device->setPreemptionMode(preemptionMode); - EXPECT_TRUE(PreemptionHelper::allowThreadGroupPreemption(kernel.get(), waTable)); - - PreemptionHelper::programPreemptionMode(&cmdStream, preemptionMode, nullptr, nullptr); - EXPECT_EQ(requiredSize, cmdStream.getUsed()); - - auto lri = (MI_LOAD_REGISTER_IMM *)cmdStream.getBase(); - EXPECT_EQ(0x2248u, lri->getRegisterOffset()); - uint32_t expectedData = 0; - EXPECT_EQ(expectedData, lri->getDataDword()); } GEN8TEST_F(Gen8PreemptionEnqueueKernelTest, givenSecondEnqueueWithTheSamePreemptionRequestThenDontReprogram) { @@ -99,38 +55,21 @@ GEN8TEST_F(Gen8PreemptionEnqueueKernelTest, givenSecondEnqueueWithTheSamePreempt auto &csr = pDevice->getUltCommandStreamReceiver(); csr.getMemoryManager()->setForce32BitAllocations(false); csr.overrideMediaVFEStateDirty(false); - HardwareParse hwParser; size_t off[3] = {0, 0, 0}; size_t gws[3] = {1, 1, 1}; MockKernelWithInternals mockKernel(*pDevice); + HardwareParse hwParser; pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr); hwParser.parseCommands(csr.commandStream); - hwParser.findHardwareCommands(); auto offset = csr.commandStream.getUsed(); - - bool foundOne = false; - for (auto it : hwParser.lriList) { - auto cmd = genCmdCast(it); - if (cmd->getRegisterOffset() == 0x2248u) { - EXPECT_FALSE(foundOne); - foundOne = true; - } - } - EXPECT_TRUE(foundOne); - - hwParser.cmdList.clear(); - hwParser.lriList.clear(); - pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr); + pCmdQ->flush(); hwParser.parseCommands(csr.commandStream, offset); - hwParser.findHardwareCommands(); - for (auto it : hwParser.lriList) { - auto cmd = genCmdCast(it); - EXPECT_FALSE(cmd->getRegisterOffset() == 0x2248u); - } + size_t numMmiosFound = countMmio(hwParser.cmdList.begin(), hwParser.cmdList.end(), 0x2248u); + EXPECT_EQ(1U, numMmiosFound); } GEN8TEST_F(Gen8PreemptionEnqueueKernelTest, givenValidKernelForPreemptionWhenEnqueueKernelCalledThenPassDevicePreemptionMode) { diff --git a/unit_tests/gen9/test_preemption.cpp b/unit_tests/gen9/test_preemption.cpp index 39c87e493c..7ba9721b5e 100644 --- a/unit_tests/gen9/test_preemption.cpp +++ b/unit_tests/gen9/test_preemption.cpp @@ -27,6 +27,7 @@ #include "unit_tests/mocks/mock_command_queue.h" #include "unit_tests/mocks/mock_csr.h" #include "unit_tests/mocks/mock_buffer.h" +#include "unit_tests/mocks/mock_command_queue.h" #include "unit_tests/mocks/mock_submissions_aggregator.h" namespace OCLRT { @@ -43,74 +44,20 @@ void HardwareParse::findCsrBaseAddress() { using namespace OCLRT; -typedef DevicePreemptionTests Gen9PreemptionTests; -typedef PreemptionEnqueueKernelTest Gen9PreemptionEnqueueKernelTest; -typedef MidThreadPreemptionEnqueueKernelTest Gen9MidThreadPreemptionEnqueueKernelTest; -typedef ThreadGroupPreemptionEnqueueKernelTest Gen9ThreadGroupPreemptionEnqueueKernelTest; +using Gen9PreemptionTests = DevicePreemptionTests; +using Gen9PreemptionEnqueueKernelTest = PreemptionEnqueueKernelTest; +using Gen9MidThreadPreemptionEnqueueKernelTest = MidThreadPreemptionEnqueueKernelTest; +using Gen9ThreadGroupPreemptionEnqueueKernelTest = ThreadGroupPreemptionEnqueueKernelTest; -GEN9TEST_F(Gen9PreemptionTests, programThreadGroupPreemptionLri) { - preemptionMode = PreemptionMode::ThreadGroup; - typedef typename FamilyType::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM; - size_t requiredSize = PreemptionHelper::getRequiredCsrSize(preemptionMode); - size_t expectedSize = sizeof(MI_LOAD_REGISTER_IMM); - EXPECT_EQ(expectedSize, requiredSize); - - auto &cmdStream = cmdQ->getCS(requiredSize); - - EXPECT_TRUE(PreemptionHelper::allowThreadGroupPreemption(kernel.get(), waTable)); - PreemptionHelper::programPreemptionMode(&cmdStream, preemptionMode, nullptr, nullptr); - EXPECT_EQ(requiredSize, cmdStream.getUsed()); - - auto lri = (MI_LOAD_REGISTER_IMM *)cmdStream.getBase(); - EXPECT_EQ(0x2580u, lri->getRegisterOffset()); - uint32_t expectedData = DwordBuilder::build(1, true) | DwordBuilder::build(2, true, false); - EXPECT_EQ(expectedData, lri->getDataDword()); -} - -GEN9TEST_F(Gen9PreemptionTests, programMidBatchPreemptionLri) { - preemptionMode = PreemptionMode::MidBatch; - typedef typename FamilyType::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM; - size_t requiredSize = PreemptionHelper::getRequiredCsrSize(preemptionMode); - size_t expectedSize = sizeof(MI_LOAD_REGISTER_IMM); - EXPECT_EQ(expectedSize, requiredSize); - auto &cmdStream = cmdQ->getCS(requiredSize); - EXPECT_TRUE(PreemptionHelper::allowThreadGroupPreemption(kernel.get(), waTable)); - - PreemptionHelper::programPreemptionMode(&cmdStream, preemptionMode, nullptr, nullptr); - EXPECT_EQ(requiredSize, cmdStream.getUsed()); - - auto lri = (MI_LOAD_REGISTER_IMM *)cmdStream.getBase(); - EXPECT_EQ(0x2580u, lri->getRegisterOffset()); - uint32_t expectedData = DwordBuilder::build(2, true) | DwordBuilder::build(1, true, false); - EXPECT_EQ(expectedData, lri->getDataDword()); -} - -GEN9TEST_F(Gen9PreemptionTests, programMidThreadPreemptionLri) { - preemptionMode = PreemptionMode::MidThread; - typedef typename FamilyType::MI_LOAD_REGISTER_IMM MI_LOAD_REGISTER_IMM; - typedef typename FamilyType::GPGPU_CSR_BASE_ADDRESS GPGPU_CSR_BASE_ADDRESS; - size_t requiredSize = PreemptionHelper::getRequiredCsrSize(preemptionMode); - size_t expectedSize = sizeof(MI_LOAD_REGISTER_IMM) + sizeof(GPGPU_CSR_BASE_ADDRESS); - EXPECT_EQ(expectedSize, requiredSize); - auto &cmdStream = cmdQ->getCS(requiredSize); - size_t minSize = device->getHardwareInfo().pSysInfo->CsrSizeInMb * MemoryConstants::megaByte; - uint64_t minAlignment = 2 * 256 * MemoryConstants::kiloByte; - MockGraphicsAllocation csrSurface((void *)minAlignment, minSize); - executionEnvironment->DisableMidThreadPreemption = 0; - - device->setPreemptionMode(preemptionMode); - EXPECT_TRUE(PreemptionHelper::allowMidThreadPreemption(kernel.get(), *device)); - - PreemptionHelper::programPreemptionMode(&cmdStream, preemptionMode, &csrSurface, nullptr); - EXPECT_EQ(requiredSize, cmdStream.getUsed()); - - auto lri = (MI_LOAD_REGISTER_IMM *)cmdStream.getBase(); - EXPECT_EQ(0x2580u, lri->getRegisterOffset()); - uint32_t expectedData = DwordBuilder::build(2, true, false) | DwordBuilder::build(1, true, false); - EXPECT_EQ(expectedData, lri->getDataDword()); - - auto gpgpuCsr = (GPGPU_CSR_BASE_ADDRESS *)((uintptr_t)lri + sizeof(MI_LOAD_REGISTER_IMM)); - EXPECT_EQ(minAlignment, gpgpuCsr->getGpgpuCsrBaseAddress()); +template <> +PreemptionTestHwDetails GetPreemptionTestHwDetails() { + PreemptionTestHwDetails ret; + ret.modeToRegValueMap[PreemptionMode::ThreadGroup] = DwordBuilder::build(1, true) | DwordBuilder::build(2, true, false); + ret.modeToRegValueMap[PreemptionMode::MidBatch] = DwordBuilder::build(2, true) | DwordBuilder::build(1, true, false); + ret.modeToRegValueMap[PreemptionMode::MidThread] = DwordBuilder::build(2, true, false) | DwordBuilder::build(1, true, false); + ret.defaultRegValue = ret.modeToRegValueMap[PreemptionMode::MidBatch]; + ret.regAddress = 0x2580u; + return ret; } GEN9TEST_F(Gen9ThreadGroupPreemptionEnqueueKernelTest, givenSecondEnqueueWithTheSamePreemptionRequestThenDontReprogramThreadGroupNoWa) { @@ -124,58 +71,27 @@ GEN9TEST_F(Gen9ThreadGroupPreemptionEnqueueKernelTest, givenSecondEnqueueWithThe csr.overrideMediaVFEStateDirty(false); auto csrSurface = csr.getPreemptionCsrAllocation(); EXPECT_EQ(nullptr, csrSurface); - HardwareParse hwCsrParser; - HardwareParse hwCmdQParser; size_t off[3] = {0, 0, 0}; size_t gws[3] = {1, 1, 1}; MockKernelWithInternals mockKernel(*pDevice); + HardwareParse hwParserCsr; + HardwareParse hwParserCmdQ; pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr); - hwCsrParser.parseCommands(csr.commandStream); - hwCsrParser.findHardwareCommands(); - hwCmdQParser.parseCommands(pCmdQ->getCS()); - hwCmdQParser.findHardwareCommands(); + hwParserCsr.parseCommands(csr.commandStream); + hwParserCmdQ.parseCommands(pCmdQ->getCS()); auto offsetCsr = csr.commandStream.getUsed(); auto offsetCmdQ = pCmdQ->getCS().getUsed(); - - bool foundOne = false; - for (auto it : hwCsrParser.lriList) { - auto cmd = genCmdCast(it); - if (cmd->getRegisterOffset() == 0x2580u) { - EXPECT_FALSE(foundOne); - foundOne = true; - } - } - EXPECT_TRUE(foundOne); - hwCsrParser.cmdList.clear(); - hwCsrParser.lriList.clear(); - - bool foundWaLri = false; - for (auto it : hwCmdQParser.lriList) { - auto cmd = genCmdCast(it); - if (cmd->getRegisterOffset() == 0x2600u) { - foundWaLri = true; - } - } - EXPECT_FALSE(foundWaLri); - hwCmdQParser.cmdList.clear(); - hwCmdQParser.lriList.clear(); - pCmdQ->enqueueKernel(mockKernel.mockKernel, 1, off, gws, nullptr, 0, nullptr, nullptr); - hwCsrParser.parseCommands(csr.commandStream, offsetCsr); - hwCsrParser.findHardwareCommands(); - hwCmdQParser.parseCommands(pCmdQ->getCS(), offsetCmdQ); - hwCmdQParser.findHardwareCommands(); + pCmdQ->flush(); + hwParserCsr.parseCommands(csr.commandStream, offsetCsr); + hwParserCmdQ.parseCommands(pCmdQ->getCS(), offsetCmdQ); - for (auto it : hwCsrParser.lriList) { - auto cmd = genCmdCast(it); - EXPECT_FALSE(cmd->getRegisterOffset() == 0x2580u); - } - for (auto it : hwCmdQParser.lriList) { - auto cmd = genCmdCast(it); - EXPECT_FALSE(cmd->getRegisterOffset() == 0x2600u); - } + EXPECT_EQ(1U, countMmio(hwParserCsr.cmdList.begin(), hwParserCsr.cmdList.end(), 0x2580u)); + EXPECT_EQ(0U, countMmio(hwParserCsr.cmdList.begin(), hwParserCsr.cmdList.end(), 0x2600u)); + EXPECT_EQ(0U, countMmio(hwParserCmdQ.cmdList.begin(), hwParserCmdQ.cmdList.end(), 0x2580u)); + EXPECT_EQ(0U, countMmio(hwParserCmdQ.cmdList.begin(), hwParserCmdQ.cmdList.end(), 0x2600u)); } GEN9TEST_F(Gen9ThreadGroupPreemptionEnqueueKernelTest, givenSecondEnqueueWithTheSamePreemptionRequestThenDontReprogramThreadGroupWa) { diff --git a/unit_tests/preemption/preemption_tests.cpp b/unit_tests/preemption/preemption_tests.cpp index 4dbef9aef5..cba22b44a5 100644 --- a/unit_tests/preemption/preemption_tests.cpp +++ b/unit_tests/preemption/preemption_tests.cpp @@ -26,8 +26,11 @@ #include "unit_tests/helpers/debug_manager_state_restore.h" #include "unit_tests/helpers/hw_parse.h" #include "unit_tests/mocks/mock_device.h" +#include "unit_tests/mocks/mock_graphics_allocation.h" #include "unit_tests/mocks/mock_kernel.h" +#include "gmock/gmock-matchers.h" + using namespace OCLRT; class ThreadGroupPreemptionTests : public DevicePreemptionTests { @@ -285,6 +288,80 @@ TEST(PreemptionTest, defaultMode) { EXPECT_EQ(0, DebugManager.flags.ForcePreemptionMode.get()); } +struct PreemptionHwTest : ::testing::Test, ::testing::WithParamInterface { +}; + +HWTEST_P(PreemptionHwTest, getRequiredCmdStreamSizeReturnsSizeOfMiLoadRegisterImmWhenPreemptionModeIsChanging) { + PreemptionMode mode = GetParam(); + + if (false == GetPreemptionTestHwDetails().supportsPreemptionProgramming()) { + EXPECT_EQ(0U, PreemptionHelper::getRequiredCmdStreamSize(mode)); + return; + } + + using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM; + + size_t requiredSize = PreemptionHelper::getRequiredCmdStreamSize(mode); + EXPECT_LE(sizeof(MI_LOAD_REGISTER_IMM), requiredSize); + + StackVec buffer(requiredSize); + LinearStream cmdStream(buffer.begin(), buffer.size()); + + auto mockDevice = std::unique_ptr(MockDevice::create(nullptr)); + + size_t minCsrSize = mockDevice->getHardwareInfo().pSysInfo->CsrSizeInMb * MemoryConstants::megaByte; + uint64_t minCsrAlignment = 2 * 256 * MemoryConstants::kiloByte; + MockGraphicsAllocation csrSurface((void *)minCsrAlignment, minCsrSize); + + PreemptionHelper::programCmdStream(&cmdStream, mode, &csrSurface, nullptr); + EXPECT_EQ(requiredSize, cmdStream.getUsed()); +} + +HWTEST_P(PreemptionHwTest, programCmdStreamAddsProperMiLoadRegisterImmCommandToTheStream) { + PreemptionMode mode = GetParam(); + + if (false == GetPreemptionTestHwDetails().supportsPreemptionProgramming()) { + LinearStream cmdStream(nullptr, 0U); + PreemptionHelper::programCmdStream(&cmdStream, mode, nullptr, nullptr); + EXPECT_EQ(0U, cmdStream.getUsed()); + return; + } + + using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM; + auto hwDetails = GetPreemptionTestHwDetails(); + + uint32_t defaultRegValue = hwDetails.defaultRegValue; + + uint32_t expectedRegValue = defaultRegValue; + if (hwDetails.modeToRegValueMap.find(mode) != hwDetails.modeToRegValueMap.end()) { + expectedRegValue = hwDetails.modeToRegValueMap[mode]; + } + + size_t requiredSize = PreemptionHelper::getRequiredCmdStreamSize(mode); + StackVec buffer(requiredSize); + LinearStream cmdStream(buffer.begin(), buffer.size()); + + auto mockDevice = std::unique_ptr(MockDevice::create(nullptr)); + + size_t minCsrSize = mockDevice->getHardwareInfo().pSysInfo->CsrSizeInMb * MemoryConstants::megaByte; + uint64_t minCsrAlignment = 2 * 256 * MemoryConstants::kiloByte; + MockGraphicsAllocation csrSurface((void *)minCsrAlignment, minCsrSize); + + PreemptionHelper::programCmdStream(&cmdStream, mode, &csrSurface, nullptr); + + HardwareParse cmdParser; + cmdParser.parseCommands(cmdStream); + const uint32_t regAddress = hwDetails.regAddress; + MI_LOAD_REGISTER_IMM *cmd = findMmioCmd(cmdParser.cmdList.begin(), cmdParser.cmdList.end(), regAddress); + ASSERT_NE(nullptr, cmd); + EXPECT_EQ(expectedRegValue, cmd->getDataDword()); +} + +INSTANTIATE_TEST_CASE_P( + CreateParametrizedPreemptionHwTest, + PreemptionHwTest, + ::testing::Values(PreemptionMode::Disabled, PreemptionMode::MidBatch, PreemptionMode::ThreadGroup, PreemptionMode::MidThread)); + HWTEST_F(MidThreadPreemptionTests, createCsrSurfaceNoWa) { const WorkaroundTable *waTable = platformDevices[0]->pWaTable; WorkaroundTable tmpWaTable;