1 /*
2  * Copyright (C) 2018-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #include "shared/source/command_stream/preemption.h"
9 #include "shared/source/helpers/hw_helper.h"
10 #include "shared/test/common/cmd_parse/hw_parse.h"
11 #include "shared/test/common/fixtures/preemption_fixture.h"
12 #include "shared/test/common/helpers/debug_manager_state_restore.h"
13 #include "shared/test/common/helpers/dispatch_flags_helper.h"
14 #include "shared/test/common/libult/ult_command_stream_receiver.h"
15 #include "shared/test/common/mocks/mock_builtins.h"
16 #include "shared/test/common/mocks/mock_device.h"
17 #include "shared/test/common/mocks/mock_graphics_allocation.h"
18 
19 #include "gmock/gmock.h"
20 
21 using namespace NEO;
22 
23 class MidThreadPreemptionTests : public DevicePreemptionTests {
24   public:
SetUp()25     void SetUp() override {
26         dbgRestore.reset(new DebugManagerStateRestore());
27         DebugManager.flags.ForcePreemptionMode.set(static_cast<int32_t>(PreemptionMode::MidThread));
28         preemptionMode = PreemptionMode::MidThread;
29         DevicePreemptionTests::SetUp();
30     }
31 };
32 
TEST_F(DevicePreemptionTests,GivenMidThreadPreemptionWhenSettingDefaultPreemptionThenPreemptionLevelIsSetCorrectly)33 TEST_F(DevicePreemptionTests, GivenMidThreadPreemptionWhenSettingDefaultPreemptionThenPreemptionLevelIsSetCorrectly) {
34     RuntimeCapabilityTable devCapabilities = {};
35 
36     devCapabilities.defaultPreemptionMode = PreemptionMode::MidThread;
37 
38     PreemptionHelper::adjustDefaultPreemptionMode(devCapabilities, true, true, true);
39     EXPECT_EQ(PreemptionMode::MidThread, devCapabilities.defaultPreemptionMode);
40 }
41 
TEST_F(DevicePreemptionTests,GivenThreadGroupPreemptionWhenSettingDefaultPreemptionThenPreemptionLevelIsSetCorrectly)42 TEST_F(DevicePreemptionTests, GivenThreadGroupPreemptionWhenSettingDefaultPreemptionThenPreemptionLevelIsSetCorrectly) {
43     RuntimeCapabilityTable devCapabilities = {};
44 
45     devCapabilities.defaultPreemptionMode = PreemptionMode::ThreadGroup;
46 
47     PreemptionHelper::adjustDefaultPreemptionMode(devCapabilities, true, true, true);
48     EXPECT_EQ(PreemptionMode::ThreadGroup, devCapabilities.defaultPreemptionMode);
49 }
50 
TEST_F(DevicePreemptionTests,GivenNoMidThreadSupportWhenSettingDefaultPreemptionThenThreadGroupPreemptionIsSet)51 TEST_F(DevicePreemptionTests, GivenNoMidThreadSupportWhenSettingDefaultPreemptionThenThreadGroupPreemptionIsSet) {
52     RuntimeCapabilityTable devCapabilities = {};
53 
54     devCapabilities.defaultPreemptionMode = PreemptionMode::MidThread;
55 
56     PreemptionHelper::adjustDefaultPreemptionMode(devCapabilities, false, true, true);
57     EXPECT_EQ(PreemptionMode::ThreadGroup, devCapabilities.defaultPreemptionMode);
58 }
59 
TEST_F(DevicePreemptionTests,GivenMidBatchPreemptionWhenSettingDefaultPreemptionThenPreemptionLevelIsSetCorrectly)60 TEST_F(DevicePreemptionTests, GivenMidBatchPreemptionWhenSettingDefaultPreemptionThenPreemptionLevelIsSetCorrectly) {
61     RuntimeCapabilityTable devCapabilities = {};
62 
63     devCapabilities.defaultPreemptionMode = PreemptionMode::MidBatch;
64 
65     PreemptionHelper::adjustDefaultPreemptionMode(devCapabilities, true, true, true);
66     EXPECT_EQ(PreemptionMode::MidBatch, devCapabilities.defaultPreemptionMode);
67 }
68 
TEST_F(DevicePreemptionTests,GivenNoThreadGroupSupportWhenSettingDefaultPreemptionThenMidBatchPreemptionIsSet)69 TEST_F(DevicePreemptionTests, GivenNoThreadGroupSupportWhenSettingDefaultPreemptionThenMidBatchPreemptionIsSet) {
70     RuntimeCapabilityTable devCapabilities = {};
71 
72     devCapabilities.defaultPreemptionMode = PreemptionMode::MidThread;
73 
74     PreemptionHelper::adjustDefaultPreemptionMode(devCapabilities, false, false, true);
75     EXPECT_EQ(PreemptionMode::MidBatch, devCapabilities.defaultPreemptionMode);
76 }
77 
TEST_F(DevicePreemptionTests,GivenDisabledPreemptionWhenSettingDefaultPreemptionThenPreemptionLevelIsDisabled)78 TEST_F(DevicePreemptionTests, GivenDisabledPreemptionWhenSettingDefaultPreemptionThenPreemptionLevelIsDisabled) {
79     RuntimeCapabilityTable devCapabilities = {};
80 
81     devCapabilities.defaultPreemptionMode = PreemptionMode::Disabled;
82 
83     PreemptionHelper::adjustDefaultPreemptionMode(devCapabilities, true, true, true);
84     EXPECT_EQ(PreemptionMode::Disabled, devCapabilities.defaultPreemptionMode);
85 }
86 
TEST_F(DevicePreemptionTests,GivenNoPreemptionSupportWhenSettingDefaultPreemptionThenDisabledIsSet)87 TEST_F(DevicePreemptionTests, GivenNoPreemptionSupportWhenSettingDefaultPreemptionThenDisabledIsSet) {
88     RuntimeCapabilityTable devCapabilities = {};
89 
90     devCapabilities.defaultPreemptionMode = PreemptionMode::MidThread;
91 
92     PreemptionHelper::adjustDefaultPreemptionMode(devCapabilities, false, false, false);
93     EXPECT_EQ(PreemptionMode::Disabled, devCapabilities.defaultPreemptionMode);
94 }
95 
96 struct PreemptionHwTest : ::testing::Test, ::testing::WithParamInterface<PreemptionMode> {
97 };
98 
HWTEST_P(PreemptionHwTest,GivenPreemptionModeIsNotChangingWhenGettingRequiredCmdStreamSizeThenZeroIsReturned)99 HWTEST_P(PreemptionHwTest, GivenPreemptionModeIsNotChangingWhenGettingRequiredCmdStreamSizeThenZeroIsReturned) {
100     PreemptionMode mode = GetParam();
101     size_t requiredSize = PreemptionHelper::getRequiredCmdStreamSize<FamilyType>(mode, mode);
102     EXPECT_EQ(0U, requiredSize);
103 
104     StackVec<char, 4096> buffer(requiredSize);
105     LinearStream cmdStream(buffer.begin(), buffer.size());
106 
107     auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
108     {
109         auto builtIns = new MockBuiltins();
110 
111         mockDevice->getExecutionEnvironment()->rootDeviceEnvironments[0]->builtins.reset(builtIns);
112         PreemptionHelper::programCmdStream<FamilyType>(cmdStream, mode, mode, nullptr);
113     }
114     EXPECT_EQ(0U, cmdStream.getUsed());
115 }
116 
HWTEST_P(PreemptionHwTest,GivenPreemptionModeIsChangingWhenGettingRequiredCmdStreamSizeThenCorrectSizeIsReturned)117 HWTEST_P(PreemptionHwTest, GivenPreemptionModeIsChangingWhenGettingRequiredCmdStreamSizeThenCorrectSizeIsReturned) {
118     PreemptionMode mode = GetParam();
119     PreemptionMode differentPreemptionMode = static_cast<PreemptionMode>(0);
120 
121     if (false == GetPreemptionTestHwDetails<FamilyType>().supportsPreemptionProgramming()) {
122         EXPECT_EQ(0U, PreemptionHelper::getRequiredCmdStreamSize<FamilyType>(mode, differentPreemptionMode));
123         return;
124     }
125 
126     using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
127 
128     size_t requiredSize = PreemptionHelper::getRequiredCmdStreamSize<FamilyType>(mode, differentPreemptionMode);
129     EXPECT_EQ(sizeof(MI_LOAD_REGISTER_IMM), requiredSize);
130 
131     StackVec<char, 4096> buffer(requiredSize);
132     LinearStream cmdStream(buffer.begin(), buffer.size());
133 
134     auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
135 
136     size_t minCsrSize = mockDevice->getHardwareInfo().gtSystemInfo.CsrSizeInMb * MemoryConstants::megaByte;
137     uint64_t minCsrAlignment = 2 * 256 * MemoryConstants::kiloByte;
138     MockGraphicsAllocation csrSurface((void *)minCsrAlignment, minCsrSize);
139 
140     PreemptionHelper::programCmdStream<FamilyType>(cmdStream, mode, differentPreemptionMode, nullptr);
141     EXPECT_EQ(requiredSize, cmdStream.getUsed());
142 }
143 
HWTEST_P(PreemptionHwTest,WhenProgrammingCmdStreamThenProperMiLoadRegisterImmCommandIsAddedToStream)144 HWTEST_P(PreemptionHwTest, WhenProgrammingCmdStreamThenProperMiLoadRegisterImmCommandIsAddedToStream) {
145     PreemptionMode mode = GetParam();
146     PreemptionMode differentPreemptionMode = static_cast<PreemptionMode>(0);
147     auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
148 
149     if (false == GetPreemptionTestHwDetails<FamilyType>().supportsPreemptionProgramming()) {
150         LinearStream cmdStream(nullptr, 0U);
151         PreemptionHelper::programCmdStream<FamilyType>(cmdStream, mode, differentPreemptionMode, nullptr);
152         EXPECT_EQ(0U, cmdStream.getUsed());
153         return;
154     }
155 
156     using MI_LOAD_REGISTER_IMM = typename FamilyType::MI_LOAD_REGISTER_IMM;
157     auto hwDetails = GetPreemptionTestHwDetails<FamilyType>();
158 
159     uint32_t defaultRegValue = hwDetails.defaultRegValue;
160 
161     uint32_t expectedRegValue = defaultRegValue;
162     if (hwDetails.modeToRegValueMap.find(mode) != hwDetails.modeToRegValueMap.end()) {
163         expectedRegValue = hwDetails.modeToRegValueMap[mode];
164     }
165 
166     size_t requiredSize = PreemptionHelper::getRequiredCmdStreamSize<FamilyType>(mode, differentPreemptionMode);
167     StackVec<char, 4096> buffer(requiredSize);
168     LinearStream cmdStream(buffer.begin(), buffer.size());
169 
170     size_t minCsrSize = mockDevice->getHardwareInfo().gtSystemInfo.CsrSizeInMb * MemoryConstants::megaByte;
171     uint64_t minCsrAlignment = 2 * 256 * MemoryConstants::kiloByte;
172     MockGraphicsAllocation csrSurface((void *)minCsrAlignment, minCsrSize);
173 
174     PreemptionHelper::programCmdStream<FamilyType>(cmdStream, mode, differentPreemptionMode, &csrSurface);
175 
176     HardwareParse cmdParser;
177     cmdParser.parseCommands<FamilyType>(cmdStream);
178     const uint32_t regAddress = hwDetails.regAddress;
179     MI_LOAD_REGISTER_IMM *cmd = findMmioCmd<FamilyType>(cmdParser.cmdList.begin(), cmdParser.cmdList.end(), regAddress);
180     ASSERT_NE(nullptr, cmd);
181     EXPECT_EQ(expectedRegValue, cmd->getDataDword());
182 }
183 
184 INSTANTIATE_TEST_CASE_P(
185     CreateParametrizedPreemptionHwTest,
186     PreemptionHwTest,
187     ::testing::Values(PreemptionMode::Disabled, PreemptionMode::MidBatch, PreemptionMode::ThreadGroup, PreemptionMode::MidThread));
188 
189 struct PreemptionTest : ::testing::Test, ::testing::WithParamInterface<PreemptionMode> {
190 };
191 
HWTEST_P(PreemptionTest,whenInNonMidThreadModeThenSizeForStateSipIsZero)192 HWTEST_P(PreemptionTest, whenInNonMidThreadModeThenSizeForStateSipIsZero) {
193     PreemptionMode mode = GetParam();
194     auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
195     mockDevice->setPreemptionMode(mode);
196 
197     auto size = PreemptionHelper::getRequiredStateSipCmdSize<FamilyType>(*mockDevice, false);
198     EXPECT_EQ(0u, size);
199 }
200 
HWTEST_P(PreemptionTest,whenInNonMidThreadModeThenStateSipIsNotProgrammed)201 HWTEST_P(PreemptionTest, whenInNonMidThreadModeThenStateSipIsNotProgrammed) {
202     PreemptionMode mode = GetParam();
203     auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
204     mockDevice->setPreemptionMode(mode);
205 
206     auto requiredSize = PreemptionHelper::getRequiredStateSipCmdSize<FamilyType>(*mockDevice, false);
207     StackVec<char, 4096> buffer(requiredSize);
208     LinearStream cmdStream(buffer.begin(), buffer.size());
209 
210     PreemptionHelper::programStateSip<FamilyType>(cmdStream, *mockDevice);
211     EXPECT_EQ(0u, cmdStream.getUsed());
212 }
213 
HWTEST_P(PreemptionTest,whenInNonMidThreadModeThenSizeForCsrBaseAddressIsZero)214 HWTEST_P(PreemptionTest, whenInNonMidThreadModeThenSizeForCsrBaseAddressIsZero) {
215     PreemptionMode mode = GetParam();
216     auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
217     mockDevice->setPreemptionMode(mode);
218 
219     auto size = PreemptionHelper::getRequiredPreambleSize<FamilyType>(*mockDevice);
220     EXPECT_EQ(0u, size);
221 }
222 
HWTEST_P(PreemptionTest,whenInNonMidThreadModeThenCsrBaseAddressIsNotProgrammed)223 HWTEST_P(PreemptionTest, whenInNonMidThreadModeThenCsrBaseAddressIsNotProgrammed) {
224     PreemptionMode mode = GetParam();
225     auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
226     mockDevice->setPreemptionMode(mode);
227 
228     auto requiredSize = PreemptionHelper::getRequiredPreambleSize<FamilyType>(*mockDevice);
229     StackVec<char, 4096> buffer(requiredSize);
230     LinearStream cmdStream(buffer.begin(), buffer.size());
231 
232     PreemptionHelper::programCsrBaseAddress<FamilyType>(cmdStream, *mockDevice, nullptr);
233     EXPECT_EQ(0u, cmdStream.getUsed());
234 }
235 
236 INSTANTIATE_TEST_CASE_P(
237     NonMidThread,
238     PreemptionTest,
239     ::testing::Values(PreemptionMode::Disabled, PreemptionMode::MidBatch, PreemptionMode::ThreadGroup));
240 
HWTEST_F(MidThreadPreemptionTests,GivenNoWaWhenCreatingCsrSurfaceThenSurfaceIsCorrect)241 HWTEST_F(MidThreadPreemptionTests, GivenNoWaWhenCreatingCsrSurfaceThenSurfaceIsCorrect) {
242     HardwareInfo hwInfo = *defaultHwInfo;
243     hwInfo.workaroundTable.flags.waCSRUncachable = false;
244 
245     std::unique_ptr<MockDevice> mockDevice(MockDevice::createWithNewExecutionEnvironment<MockDevice>(&hwInfo));
246     ASSERT_NE(nullptr, mockDevice.get());
247 
248     auto &csr = mockDevice->getUltCommandStreamReceiver<FamilyType>();
249     MemoryAllocation *csrSurface = static_cast<MemoryAllocation *>(csr.getPreemptionAllocation());
250     ASSERT_NE(nullptr, csrSurface);
251     EXPECT_FALSE(csrSurface->uncacheable);
252 
253     GraphicsAllocation *devCsrSurface = csr.getPreemptionAllocation();
254     EXPECT_EQ(csrSurface, devCsrSurface);
255 }
256 
HWTEST_F(MidThreadPreemptionTests,givenMidThreadPreemptionWhenFailingOnCsrSurfaceAllocationThenFailToCreateDevice)257 HWTEST_F(MidThreadPreemptionTests, givenMidThreadPreemptionWhenFailingOnCsrSurfaceAllocationThenFailToCreateDevice) {
258 
259     class FailingMemoryManager : public OsAgnosticMemoryManager {
260       public:
261         FailingMemoryManager(ExecutionEnvironment &executionEnvironment) : OsAgnosticMemoryManager(executionEnvironment) {}
262 
263         GraphicsAllocation *allocateGraphicsMemoryWithAlignment(const AllocationData &allocationData) override {
264             auto hwInfo = executionEnvironment.rootDeviceEnvironments[allocationData.rootDeviceIndex]->getHardwareInfo();
265             if (++allocateGraphicsMemoryCount > HwHelper::get(hwInfo->platform.eRenderCoreFamily).getGpgpuEngineInstances(*hwInfo).size() - 1) {
266                 return nullptr;
267             }
268             return OsAgnosticMemoryManager::allocateGraphicsMemoryWithAlignment(allocationData);
269         }
270 
271         uint32_t allocateGraphicsMemoryCount = 0;
272     };
273     ExecutionEnvironment *executionEnvironment = MockDevice::prepareExecutionEnvironment(nullptr, 0u);
274     executionEnvironment->memoryManager = std::make_unique<FailingMemoryManager>(*executionEnvironment);
275     if (executionEnvironment->memoryManager.get()->isLimitedGPU(0)) {
276         GTEST_SKIP();
277     }
278 
279     std::unique_ptr<MockDevice> mockDevice(MockDevice::create<MockDevice>(executionEnvironment, 0));
280     EXPECT_EQ(nullptr, mockDevice.get());
281 }
282 
HWTEST2_F(MidThreadPreemptionTests,GivenWaWhenCreatingCsrSurfaceThenSurfaceIsCorrect,IsAtMostGen12lp)283 HWTEST2_F(MidThreadPreemptionTests, GivenWaWhenCreatingCsrSurfaceThenSurfaceIsCorrect, IsAtMostGen12lp) {
284     HardwareInfo hwInfo = *defaultHwInfo;
285     hwInfo.workaroundTable.flags.waCSRUncachable = true;
286 
287     std::unique_ptr<MockDevice> mockDevice(MockDevice::createWithNewExecutionEnvironment<MockDevice>(&hwInfo));
288     ASSERT_NE(nullptr, mockDevice.get());
289 
290     auto &csr = mockDevice->getUltCommandStreamReceiver<FamilyType>();
291     MemoryAllocation *csrSurface = static_cast<MemoryAllocation *>(csr.getPreemptionAllocation());
292     ASSERT_NE(nullptr, csrSurface);
293     EXPECT_TRUE(csrSurface->uncacheable);
294 
295     GraphicsAllocation *devCsrSurface = csr.getPreemptionAllocation();
296     EXPECT_EQ(csrSurface, devCsrSurface);
297 
298     constexpr size_t expectedMask = (256 * MemoryConstants::kiloByte) - 1;
299 
300     size_t addressValue = reinterpret_cast<size_t>(devCsrSurface->getUnderlyingBuffer());
301     EXPECT_EQ(0u, expectedMask & addressValue);
302 }
303 
HWCMDTEST_F(IGFX_GEN8_CORE,MidThreadPreemptionTests,givenDirtyCsrStateWhenStateBaseAddressIsProgrammedThenStateSipIsAdded)304 HWCMDTEST_F(IGFX_GEN8_CORE, MidThreadPreemptionTests, givenDirtyCsrStateWhenStateBaseAddressIsProgrammedThenStateSipIsAdded) {
305     using STATE_BASE_ADDRESS = typename FamilyType::STATE_BASE_ADDRESS;
306     using STATE_SIP = typename FamilyType::STATE_SIP;
307 
308     auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
309 
310     if (mockDevice->getHardwareInfo().capabilityTable.defaultPreemptionMode == PreemptionMode::MidThread) {
311         mockDevice->setPreemptionMode(PreemptionMode::MidThread);
312 
313         auto &csr = mockDevice->getUltCommandStreamReceiver<FamilyType>();
314         csr.isPreambleSent = true;
315 
316         auto requiredSize = PreemptionHelper::getRequiredStateSipCmdSize<FamilyType>(*mockDevice, false);
317         StackVec<char, 4096> buff(requiredSize);
318         LinearStream commandStream(buff.begin(), buff.size());
319 
320         DispatchFlags dispatchFlags = DispatchFlagsHelper::createDefaultDispatchFlags();
321 
322         void *buffer = alignedMalloc(MemoryConstants::pageSize, MemoryConstants::pageSize64k);
323 
324         std::unique_ptr<MockGraphicsAllocation> allocation(new MockGraphicsAllocation(buffer, MemoryConstants::pageSize));
325         std::unique_ptr<IndirectHeap> heap(new IndirectHeap(allocation.get()));
326 
327         csr.flushTask(commandStream,
328                       0,
329                       *heap.get(),
330                       *heap.get(),
331                       *heap.get(),
332                       0,
333                       dispatchFlags,
334                       *mockDevice);
335 
336         HardwareParse hwParser;
337         hwParser.parseCommands<FamilyType>(csr.getCS(0));
338 
339         auto stateBaseAddressItor = find<STATE_BASE_ADDRESS *>(hwParser.cmdList.begin(), hwParser.cmdList.end());
340         EXPECT_NE(hwParser.cmdList.end(), stateBaseAddressItor);
341 
342         auto stateSipItor = find<STATE_SIP *>(hwParser.cmdList.begin(), hwParser.cmdList.end());
343         EXPECT_NE(hwParser.cmdList.end(), stateSipItor);
344 
345         auto stateSipAfterSBA = ++stateBaseAddressItor;
346         while ((stateSipAfterSBA != hwParser.cmdList.end()) && (*stateSipAfterSBA != *stateSipItor)) {
347             stateSipAfterSBA = ++stateBaseAddressItor;
348         }
349         EXPECT_EQ(*stateSipAfterSBA, *stateSipItor);
350 
351         alignedFree(buffer);
352     }
353 }
354 
HWCMDTEST_F(IGFX_GEN8_CORE,MidThreadPreemptionTests,WhenProgrammingPreemptionThenPreemptionProgrammedAfterVfeStateInCmdBuffer)355 HWCMDTEST_F(IGFX_GEN8_CORE, MidThreadPreemptionTests, WhenProgrammingPreemptionThenPreemptionProgrammedAfterVfeStateInCmdBuffer) {
356     using MEDIA_VFE_STATE = typename FamilyType::MEDIA_VFE_STATE;
357 
358     auto mockDevice = std::unique_ptr<MockDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
359 
360     if (mockDevice->getHardwareInfo().capabilityTable.defaultPreemptionMode == PreemptionMode::MidThread) {
361         mockDevice->setPreemptionMode(PreemptionMode::MidThread);
362 
363         auto &csr = mockDevice->getUltCommandStreamReceiver<FamilyType>();
364         csr.isPreambleSent = true;
365 
366         auto requiredSize = PreemptionHelper::getRequiredStateSipCmdSize<FamilyType>(*mockDevice, false);
367         StackVec<char, 4096> buff(requiredSize);
368         LinearStream commandStream(buff.begin(), buff.size());
369 
370         DispatchFlags dispatchFlags = DispatchFlagsHelper::createDefaultDispatchFlags();
371 
372         void *buffer = alignedMalloc(MemoryConstants::pageSize, MemoryConstants::pageSize64k);
373 
374         std::unique_ptr<MockGraphicsAllocation> allocation(new MockGraphicsAllocation(buffer, MemoryConstants::pageSize));
375         std::unique_ptr<IndirectHeap> heap(new IndirectHeap(allocation.get()));
376 
377         csr.flushTask(commandStream,
378                       0,
379                       *heap.get(),
380                       *heap.get(),
381                       *heap.get(),
382                       0,
383                       dispatchFlags,
384                       *mockDevice);
385 
386         auto hwDetails = GetPreemptionTestHwDetails<FamilyType>();
387 
388         HardwareParse hwParser;
389         hwParser.parseCommands<FamilyType>(csr.getCS(0));
390 
391         const uint32_t regAddress = hwDetails.regAddress;
392         auto itorPreemptionMode = findMmio<FamilyType>(hwParser.cmdList.begin(), hwParser.cmdList.end(), regAddress);
393         auto itorMediaVFEMode = find<MEDIA_VFE_STATE *>(hwParser.cmdList.begin(), hwParser.cmdList.end());
394 
395         itorMediaVFEMode++;
396         EXPECT_TRUE(itorMediaVFEMode == itorPreemptionMode);
397 
398         alignedFree(buffer);
399     }
400 }
401