1 /*
2  * Copyright (C) 2018-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #include "shared/source/command_stream/command_stream_receiver.h"
9 #include "shared/source/helpers/array_count.h"
10 #include "shared/source/helpers/basic_math.h"
11 #include "shared/source/helpers/engine_node_helper.h"
12 #include "shared/source/helpers/timestamp_packet.h"
13 #include "shared/source/memory_manager/internal_allocation_storage.h"
14 #include "shared/source/memory_manager/memory_manager.h"
15 #include "shared/source/os_interface/hw_info_config.h"
16 #include "shared/test/common/fixtures/memory_management_fixture.h"
17 #include "shared/test/common/helpers/debug_manager_state_restore.h"
18 #include "shared/test/common/helpers/unit_test_helper.h"
19 #include "shared/test/common/helpers/variable_backup.h"
20 #include "shared/test/common/libult/ult_command_stream_receiver.h"
21 #include "shared/test/common/mocks/mock_allocation_properties.h"
22 #include "shared/test/common/mocks/mock_csr.h"
23 #include "shared/test/common/mocks/mock_gmm_resource_info.h"
24 #include "shared/test/common/mocks/mock_graphics_allocation.h"
25 #include "shared/test/common/mocks/mock_memory_manager.h"
26 #include "shared/test/common/mocks/mock_os_context.h"
27 #include "shared/test/common/test_macros/test.h"
28 #include "shared/test/common/test_macros/test_checks_shared.h"
29 
30 #include "opencl/source/command_queue/command_queue_hw.h"
31 #include "opencl/source/event/event.h"
32 #include "opencl/source/event/user_event.h"
33 #include "opencl/source/helpers/cl_hw_helper.h"
34 #include "opencl/source/helpers/hardware_commands_helper.h"
35 #include "opencl/test/unit_test/command_queue/command_queue_fixture.h"
36 #include "opencl/test/unit_test/command_stream/command_stream_fixture.h"
37 #include "opencl/test/unit_test/fixtures/buffer_fixture.h"
38 #include "opencl/test/unit_test/fixtures/cl_device_fixture.h"
39 #include "opencl/test/unit_test/fixtures/context_fixture.h"
40 #include "opencl/test/unit_test/fixtures/dispatch_flags_fixture.h"
41 #include "opencl/test/unit_test/fixtures/image_fixture.h"
42 #include "opencl/test/unit_test/fixtures/multi_tile_fixture.h"
43 #include "opencl/test/unit_test/helpers/raii_hw_helper.h"
44 #include "opencl/test/unit_test/mocks/mock_command_queue.h"
45 #include "opencl/test/unit_test/mocks/mock_context.h"
46 #include "opencl/test/unit_test/mocks/mock_event.h"
47 #include "opencl/test/unit_test/mocks/mock_image.h"
48 #include "opencl/test/unit_test/mocks/mock_kernel.h"
49 #include "opencl/test/unit_test/mocks/mock_mdi.h"
50 #include "opencl/test/unit_test/mocks/mock_program.h"
51 
52 #include "gmock/gmock.h"
53 #include "gtest/gtest.h"
54 
55 using namespace NEO;
56 
57 struct CommandQueueMemoryDevice
58     : public MemoryManagementFixture,
59       public ClDeviceFixture {
60 
SetUpCommandQueueMemoryDevice61     void SetUp() override {
62         MemoryManagementFixture::SetUp();
63         ClDeviceFixture::SetUp();
64     }
65 
TearDownCommandQueueMemoryDevice66     void TearDown() override {
67         ClDeviceFixture::TearDown();
68         platformsImpl->clear();
69         MemoryManagementFixture::TearDown();
70     }
71 };
72 
73 struct CommandQueueTest
74     : public CommandQueueMemoryDevice,
75       public ContextFixture,
76       public CommandQueueFixture,
77       ::testing::TestWithParam<uint64_t /*cl_command_queue_properties*/> {
78 
79     using CommandQueueFixture::SetUp;
80     using ContextFixture::SetUp;
81 
CommandQueueTestCommandQueueTest82     CommandQueueTest() {
83     }
84 
SetUpCommandQueueTest85     void SetUp() override {
86         CommandQueueMemoryDevice::SetUp();
87         properties = GetParam();
88 
89         cl_device_id device = pClDevice;
90         ContextFixture::SetUp(1, &device);
91         CommandQueueFixture::SetUp(pContext, pClDevice, properties);
92     }
93 
TearDownCommandQueueTest94     void TearDown() override {
95         CommandQueueFixture::TearDown();
96         ContextFixture::TearDown();
97         CommandQueueMemoryDevice::TearDown();
98     }
99 
100     cl_command_queue_properties properties;
101     const HardwareInfo *pHwInfo = nullptr;
102 };
103 
TEST_P(CommandQueueTest,GivenNonFailingAllocationWhenCreatingCommandQueueThenCommandQueueIsCreated)104 TEST_P(CommandQueueTest, GivenNonFailingAllocationWhenCreatingCommandQueueThenCommandQueueIsCreated) {
105     InjectedFunction method = [this](size_t failureIndex) {
106         auto retVal = CL_INVALID_VALUE;
107         auto pCmdQ = CommandQueue::create(
108             pContext,
109             pClDevice,
110             nullptr,
111             false,
112             retVal);
113 
114         if (MemoryManagement::nonfailingAllocation == failureIndex) {
115             EXPECT_EQ(CL_SUCCESS, retVal);
116             EXPECT_NE(nullptr, pCmdQ);
117         } else {
118             EXPECT_EQ(CL_OUT_OF_HOST_MEMORY, retVal) << "for allocation " << failureIndex;
119             EXPECT_EQ(nullptr, pCmdQ);
120         }
121         delete pCmdQ;
122     };
123     injectFailures(method);
124 }
125 
126 INSTANTIATE_TEST_CASE_P(CommandQueue,
127                         CommandQueueTest,
128                         ::testing::ValuesIn(AllCommandQueueProperties));
129 
TEST(CommandQueue,WhenConstructingCommandQueueThenTaskLevelAndTaskCountAreZero)130 TEST(CommandQueue, WhenConstructingCommandQueueThenTaskLevelAndTaskCountAreZero) {
131     MockCommandQueue cmdQ(nullptr, nullptr, 0, false);
132     EXPECT_EQ(0u, cmdQ.taskLevel);
133     EXPECT_EQ(0u, cmdQ.taskCount);
134 }
135 
TEST(CommandQueue,WhenConstructingCommandQueueThenQueueFamilyIsNotSelected)136 TEST(CommandQueue, WhenConstructingCommandQueueThenQueueFamilyIsNotSelected) {
137     MockCommandQueue cmdQ(nullptr, nullptr, 0, false);
138     EXPECT_FALSE(cmdQ.isQueueFamilySelected());
139 }
140 
TEST(CommandQueue,givenEnableTimestampWaitWhenCheckIsTimestampWaitEnabledThenReturnProperValue)141 TEST(CommandQueue, givenEnableTimestampWaitWhenCheckIsTimestampWaitEnabledThenReturnProperValue) {
142     DebugManagerStateRestore restorer;
143     VariableBackup<UltHwConfig> backup(&ultHwConfig);
144     ultHwConfig.useWaitForTimestamps = true;
145     auto mockDevice = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
146     MockCommandQueue cmdQ(nullptr, mockDevice.get(), 0, false);
147 
148     {
149         DebugManager.flags.EnableTimestampWait.set(0);
150         EXPECT_FALSE(cmdQ.isWaitForTimestampsEnabled());
151     }
152 
153     {
154         DebugManager.flags.EnableTimestampWait.set(1);
155         EXPECT_EQ(cmdQ.isWaitForTimestampsEnabled(), cmdQ.getGpgpuCommandStreamReceiver().isUpdateTagFromWaitEnabled());
156     }
157 
158     {
159         DebugManager.flags.EnableTimestampWait.set(2);
160         EXPECT_EQ(cmdQ.isWaitForTimestampsEnabled(), cmdQ.getGpgpuCommandStreamReceiver().isDirectSubmissionEnabled());
161     }
162 
163     {
164         DebugManager.flags.EnableTimestampWait.set(3);
165         EXPECT_EQ(cmdQ.isWaitForTimestampsEnabled(), cmdQ.getGpgpuCommandStreamReceiver().isAnyDirectSubmissionEnabled());
166     }
167 
168     {
169         DebugManager.flags.EnableTimestampWait.set(4);
170         EXPECT_TRUE(cmdQ.isWaitForTimestampsEnabled());
171     }
172 }
173 
174 struct GetTagTest : public ClDeviceFixture,
175                     public CommandQueueFixture,
176                     public CommandStreamFixture,
177                     public ::testing::Test {
178 
179     using CommandQueueFixture::SetUp;
180 
SetUpGetTagTest181     void SetUp() override {
182         ClDeviceFixture::SetUp();
183         CommandQueueFixture::SetUp(nullptr, pClDevice, 0);
184         CommandStreamFixture::SetUp(pCmdQ);
185     }
186 
TearDownGetTagTest187     void TearDown() override {
188         CommandStreamFixture::TearDown();
189         CommandQueueFixture::TearDown();
190         ClDeviceFixture::TearDown();
191     }
192 };
193 
TEST_F(GetTagTest,GivenSetHwTagWhenGettingHwTagThenCorrectTagIsReturned)194 TEST_F(GetTagTest, GivenSetHwTagWhenGettingHwTagThenCorrectTagIsReturned) {
195     uint32_t tagValue = 0xdeadbeef;
196     *pTagMemory = tagValue;
197     EXPECT_EQ(tagValue, pCmdQ->getHwTag());
198 }
199 
TEST_F(GetTagTest,GivenInitialValueWhenGettingHwTagThenCorrectTagIsReturned)200 TEST_F(GetTagTest, GivenInitialValueWhenGettingHwTagThenCorrectTagIsReturned) {
201     MockContext context;
202     MockCommandQueue commandQueue(&context, pClDevice, 0, false);
203 
204     EXPECT_EQ(initialHardwareTag, commandQueue.getHwTag());
205 }
206 
TEST(CommandQueue,GivenUpdatedCompletionStampWhenGettingCompletionStampThenUpdatedValueIsReturned)207 TEST(CommandQueue, GivenUpdatedCompletionStampWhenGettingCompletionStampThenUpdatedValueIsReturned) {
208     MockContext context;
209 
210     MockCommandQueue cmdQ(&context, nullptr, 0, false);
211 
212     CompletionStamp cs = {
213         cmdQ.taskCount + 100,
214         cmdQ.taskLevel + 50,
215         5};
216     cmdQ.updateFromCompletionStamp(cs, nullptr);
217 
218     EXPECT_EQ(cs.taskLevel, cmdQ.taskLevel);
219     EXPECT_EQ(cs.taskCount, cmdQ.taskCount);
220     EXPECT_EQ(cs.flushStamp, cmdQ.flushStamp->peekStamp());
221 }
222 
TEST(CommandQueue,givenTimeStampWithTaskCountNotReadyStatusWhenupdateFromCompletionStampIsBeingCalledThenQueueTaskCountIsNotUpdated)223 TEST(CommandQueue, givenTimeStampWithTaskCountNotReadyStatusWhenupdateFromCompletionStampIsBeingCalledThenQueueTaskCountIsNotUpdated) {
224     MockContext context;
225 
226     MockCommandQueue cmdQ(&context, nullptr, 0, false);
227 
228     cmdQ.taskCount = 1u;
229 
230     CompletionStamp cs = {
231         CompletionStamp::notReady,
232         0,
233         0};
234     cmdQ.updateFromCompletionStamp(cs, nullptr);
235     EXPECT_EQ(1u, cmdQ.taskCount);
236 }
237 
TEST(CommandQueue,GivenOOQwhenUpdateFromCompletionStampWithTrueIsCalledThenTaskLevelIsUpdated)238 TEST(CommandQueue, GivenOOQwhenUpdateFromCompletionStampWithTrueIsCalledThenTaskLevelIsUpdated) {
239     MockContext context;
240     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, 0};
241 
242     MockCommandQueue cmdQ(&context, nullptr, props, false);
243     auto oldTL = cmdQ.taskLevel;
244 
245     CompletionStamp cs = {
246         cmdQ.taskCount + 100,
247         cmdQ.taskLevel + 50,
248         5};
249     cmdQ.updateFromCompletionStamp(cs, nullptr);
250 
251     EXPECT_NE(oldTL, cmdQ.taskLevel);
252     EXPECT_EQ(oldTL + 50, cmdQ.taskLevel);
253     EXPECT_EQ(cs.taskCount, cmdQ.taskCount);
254     EXPECT_EQ(cs.flushStamp, cmdQ.flushStamp->peekStamp());
255 }
256 
TEST(CommandQueue,givenDeviceWhenCreatingCommandQueueThenPickCsrFromDefaultEngine)257 TEST(CommandQueue, givenDeviceWhenCreatingCommandQueueThenPickCsrFromDefaultEngine) {
258     auto mockDevice = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
259     MockCommandQueue cmdQ(nullptr, mockDevice.get(), 0, false);
260 
261     auto defaultCsr = mockDevice->getDefaultEngine().commandStreamReceiver;
262     EXPECT_EQ(defaultCsr, &cmdQ.getGpgpuCommandStreamReceiver());
263 }
264 
265 struct CommandQueueWithBlitOperationsTests : public ::testing::TestWithParam<uint32_t> {};
266 
TEST(CommandQueue,givenDeviceNotSupportingBlitOperationsWhenQueueIsCreatedThenDontRegisterAnyBcsCsrs)267 TEST(CommandQueue, givenDeviceNotSupportingBlitOperationsWhenQueueIsCreatedThenDontRegisterAnyBcsCsrs) {
268     HardwareInfo hwInfo = *defaultHwInfo;
269     hwInfo.capabilityTable.blitterOperationsSupported = false;
270     auto mockDevice = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(&hwInfo));
271     MockCommandQueue cmdQ(nullptr, mockDevice.get(), 0, false);
272 
273     EXPECT_EQ(0u, cmdQ.countBcsEngines());
274 
275     auto defaultCsr = mockDevice->getDefaultEngine().commandStreamReceiver;
276     EXPECT_EQ(defaultCsr, &cmdQ.getGpgpuCommandStreamReceiver());
277 }
278 
TEST(CommandQueue,givenDeviceWithSubDevicesSupportingBlitOperationsWhenQueueIsCreatedThenBcsIsTakenFromFirstSubDevice)279 TEST(CommandQueue, givenDeviceWithSubDevicesSupportingBlitOperationsWhenQueueIsCreatedThenBcsIsTakenFromFirstSubDevice) {
280     DebugManagerStateRestore restorer;
281     VariableBackup<bool> mockDeviceFlagBackup{&MockDevice::createSingleDevice, false};
282     DebugManager.flags.CreateMultipleSubDevices.set(2);
283     DebugManager.flags.EnableBlitterForEnqueueOperations.set(1);
284     HardwareInfo hwInfo = *defaultHwInfo;
285     hwInfo.capabilityTable.blitterOperationsSupported = true;
286     REQUIRE_FULL_BLITTER_OR_SKIP(&hwInfo);
287 
288     auto device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(&hwInfo));
289     EXPECT_EQ(2u, device->getNumGenericSubDevices());
290     std::unique_ptr<OsContext> bcsOsContext;
291 
292     auto subDevice = device->getSubDevice(0);
293     auto &bcsEngine = subDevice->getEngine(aub_stream::EngineType::ENGINE_BCS, EngineUsage::Regular);
294 
295     MockCommandQueue cmdQ(nullptr, device.get(), 0, false);
296 
297     EXPECT_NE(nullptr, cmdQ.getBcsCommandStreamReceiver(aub_stream::EngineType::ENGINE_BCS));
298     EXPECT_EQ(bcsEngine.commandStreamReceiver, cmdQ.getBcsCommandStreamReceiver(aub_stream::EngineType::ENGINE_BCS));
299 }
300 
301 INSTANTIATE_TEST_CASE_P(uint32_t,
302                         CommandQueueWithBlitOperationsTests,
303                         ::testing::Values(CL_COMMAND_WRITE_BUFFER,
304                                           CL_COMMAND_WRITE_BUFFER_RECT,
305                                           CL_COMMAND_READ_BUFFER,
306                                           CL_COMMAND_READ_BUFFER_RECT,
307                                           CL_COMMAND_COPY_BUFFER,
308                                           CL_COMMAND_COPY_BUFFER_RECT,
309                                           CL_COMMAND_SVM_MEMCPY));
310 
TEST(CommandQueue,givenCmdQueueBlockedByReadyVirtualEventWhenUnblockingThenUpdateFlushTaskFromEvent)311 TEST(CommandQueue, givenCmdQueueBlockedByReadyVirtualEventWhenUnblockingThenUpdateFlushTaskFromEvent) {
312     auto mockDevice = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
313     auto context = new MockContext;
314     auto cmdQ = new MockCommandQueue(context, mockDevice.get(), 0, false);
315     auto userEvent = new Event(cmdQ, CL_COMMAND_NDRANGE_KERNEL, 0, 0);
316     userEvent->setStatus(CL_COMPLETE);
317     userEvent->flushStamp->setStamp(5);
318     userEvent->incRefInternal();
319 
320     FlushStamp expectedFlushStamp = 0;
321     EXPECT_EQ(expectedFlushStamp, cmdQ->flushStamp->peekStamp());
322     cmdQ->virtualEvent = userEvent;
323 
324     EXPECT_FALSE(cmdQ->isQueueBlocked());
325     EXPECT_EQ(userEvent->flushStamp->peekStamp(), cmdQ->flushStamp->peekStamp());
326     userEvent->decRefInternal();
327     cmdQ->decRefInternal();
328     context->decRefInternal();
329 }
330 
TEST(CommandQueue,givenCmdQueueBlockedByAbortedVirtualEventWhenUnblockingThenUpdateFlushTaskFromEvent)331 TEST(CommandQueue, givenCmdQueueBlockedByAbortedVirtualEventWhenUnblockingThenUpdateFlushTaskFromEvent) {
332     auto context = new MockContext;
333     auto mockDevice = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
334     auto cmdQ = new MockCommandQueue(context, mockDevice.get(), 0, false);
335 
336     auto userEvent = new Event(cmdQ, CL_COMMAND_NDRANGE_KERNEL, 0, 0);
337     userEvent->setStatus(-1);
338     userEvent->flushStamp->setStamp(5);
339 
340     FlushStamp expectedFlushStamp = 0;
341 
342     EXPECT_EQ(expectedFlushStamp, cmdQ->flushStamp->peekStamp());
343     userEvent->incRefInternal();
344     cmdQ->virtualEvent = userEvent;
345 
346     EXPECT_FALSE(cmdQ->isQueueBlocked());
347     EXPECT_EQ(expectedFlushStamp, cmdQ->flushStamp->peekStamp());
348     userEvent->decRefInternal();
349     cmdQ->decRefInternal();
350     context->decRefInternal();
351 }
352 
353 struct CommandQueueCommandStreamTest : public CommandQueueMemoryDevice,
354                                        public ::testing::Test {
SetUpCommandQueueCommandStreamTest355     void SetUp() override {
356         CommandQueueMemoryDevice::SetUp();
357         context.reset(new MockContext(pClDevice));
358     }
359 
TearDownCommandQueueCommandStreamTest360     void TearDown() override {
361         context.reset();
362         CommandQueueMemoryDevice::TearDown();
363     }
364     std::unique_ptr<MockContext> context;
365 };
366 
HWTEST_F(CommandQueueCommandStreamTest,givenCommandQueueThatWaitsOnAbortedUserEventWhenIsQueueBlockedIsCalledThenTaskLevelAlignsToCsr)367 HWTEST_F(CommandQueueCommandStreamTest, givenCommandQueueThatWaitsOnAbortedUserEventWhenIsQueueBlockedIsCalledThenTaskLevelAlignsToCsr) {
368     MockContext context;
369     auto mockDevice = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
370 
371     MockCommandQueue cmdQ(&context, mockDevice.get(), 0, false);
372     auto &commandStreamReceiver = mockDevice->getUltCommandStreamReceiver<FamilyType>();
373     commandStreamReceiver.taskLevel = 100u;
374 
375     Event userEvent(&cmdQ, CL_COMMAND_NDRANGE_KERNEL, 0, 0);
376     userEvent.setStatus(-1);
377     userEvent.incRefInternal();
378     cmdQ.virtualEvent = &userEvent;
379 
380     EXPECT_FALSE(cmdQ.isQueueBlocked());
381     EXPECT_EQ(100u, cmdQ.taskLevel);
382 }
383 
HWTEST_F(CommandQueueCommandStreamTest,WhenCheckIsTextureCacheFlushNeededThenReturnProperValue)384 HWTEST_F(CommandQueueCommandStreamTest, WhenCheckIsTextureCacheFlushNeededThenReturnProperValue) {
385     MockContext context;
386     auto mockDevice = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
387     MockCommandQueue cmdQ(&context, mockDevice.get(), 0, false);
388     auto &commandStreamReceiver = mockDevice->getUltCommandStreamReceiver<FamilyType>();
389 
390     EXPECT_FALSE(cmdQ.isTextureCacheFlushNeeded(CL_COMMAND_COPY_BUFFER_RECT));
391 
392     for (auto i = CL_COMMAND_NDRANGE_KERNEL; i < CL_COMMAND_RELEASE_GL_OBJECTS; i++) {
393         if (i == CL_COMMAND_COPY_IMAGE) {
394             commandStreamReceiver.directSubmissionAvailable = true;
395             EXPECT_TRUE(cmdQ.isTextureCacheFlushNeeded(i));
396             commandStreamReceiver.directSubmissionAvailable = false;
397             EXPECT_FALSE(cmdQ.isTextureCacheFlushNeeded(i));
398         } else {
399             commandStreamReceiver.directSubmissionAvailable = true;
400             EXPECT_FALSE(cmdQ.isTextureCacheFlushNeeded(i));
401             commandStreamReceiver.directSubmissionAvailable = false;
402             EXPECT_FALSE(cmdQ.isTextureCacheFlushNeeded(i));
403         }
404     }
405 }
406 
TEST_F(CommandQueueCommandStreamTest,GivenValidCommandQueueWhenGettingCommandStreamThenValidObjectIsReturned)407 TEST_F(CommandQueueCommandStreamTest, GivenValidCommandQueueWhenGettingCommandStreamThenValidObjectIsReturned) {
408     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
409     MockCommandQueue commandQueue(context.get(), pClDevice, props, false);
410 
411     auto &cs = commandQueue.getCS(1024);
412     EXPECT_NE(nullptr, &cs);
413 }
414 
TEST_F(CommandQueueCommandStreamTest,GivenValidCommandStreamWhenGettingGraphicsAllocationThenMaxAvailableSpaceAndUnderlyingBufferSizeAreCorrect)415 TEST_F(CommandQueueCommandStreamTest, GivenValidCommandStreamWhenGettingGraphicsAllocationThenMaxAvailableSpaceAndUnderlyingBufferSizeAreCorrect) {
416     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
417     MockCommandQueue commandQueue(context.get(), pClDevice, props, false);
418     size_t minSizeRequested = 20;
419 
420     auto &cs = commandQueue.getCS(minSizeRequested);
421     ASSERT_NE(nullptr, &cs);
422 
423     auto *allocation = cs.getGraphicsAllocation();
424     ASSERT_NE(nullptr, &allocation);
425     size_t expectedCsSize = alignUp(minSizeRequested + CSRequirements::minCommandQueueCommandStreamSize + CSRequirements::csOverfetchSize, MemoryConstants::pageSize64k) - CSRequirements::minCommandQueueCommandStreamSize - CSRequirements::csOverfetchSize;
426     EXPECT_EQ(expectedCsSize, cs.getMaxAvailableSpace());
427 
428     size_t expectedTotalSize = alignUp(minSizeRequested + CSRequirements::minCommandQueueCommandStreamSize + CSRequirements::csOverfetchSize, MemoryConstants::pageSize64k);
429     EXPECT_EQ(expectedTotalSize, allocation->getUnderlyingBufferSize());
430 }
431 
TEST_F(CommandQueueCommandStreamTest,GivenRequiredSizeWhenGettingCommandStreamThenMaxAvailableSpaceIsEqualOrGreaterThanRequiredSize)432 TEST_F(CommandQueueCommandStreamTest, GivenRequiredSizeWhenGettingCommandStreamThenMaxAvailableSpaceIsEqualOrGreaterThanRequiredSize) {
433     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
434     MockCommandQueue commandQueue(context.get(), pClDevice, props, false);
435 
436     size_t requiredSize = 16384;
437     const auto &commandStream = commandQueue.getCS(requiredSize);
438     ASSERT_NE(nullptr, &commandStream);
439     EXPECT_GE(commandStream.getMaxAvailableSpace(), requiredSize);
440 }
441 
TEST_F(CommandQueueCommandStreamTest,WhenGettingCommandStreamWithNewSizeThenMaxAvailableSpaceIsEqualOrGreaterThanNewSize)442 TEST_F(CommandQueueCommandStreamTest, WhenGettingCommandStreamWithNewSizeThenMaxAvailableSpaceIsEqualOrGreaterThanNewSize) {
443     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
444     MockCommandQueue commandQueue(context.get(), pClDevice, props, false);
445 
446     auto &commandStreamInitial = commandQueue.getCS(1024);
447     size_t requiredSize = commandStreamInitial.getMaxAvailableSpace() + 42;
448 
449     const auto &commandStream = commandQueue.getCS(requiredSize);
450     ASSERT_NE(nullptr, &commandStream);
451     EXPECT_GE(commandStream.getMaxAvailableSpace(), requiredSize);
452 }
453 
TEST_F(CommandQueueCommandStreamTest,givenCommandStreamReceiverWithReusableAllocationsWhenAskedForCommandStreamThenReturnsAllocationFromReusablePool)454 TEST_F(CommandQueueCommandStreamTest, givenCommandStreamReceiverWithReusableAllocationsWhenAskedForCommandStreamThenReturnsAllocationFromReusablePool) {
455     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
456     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
457 
458     auto memoryManager = pDevice->getMemoryManager();
459     size_t requiredSize = alignUp(100 + CSRequirements::minCommandQueueCommandStreamSize + CSRequirements::csOverfetchSize, MemoryConstants::pageSize64k);
460     auto allocation = memoryManager->allocateGraphicsMemoryWithProperties({pDevice->getRootDeviceIndex(), requiredSize, GraphicsAllocation::AllocationType::COMMAND_BUFFER, pDevice->getDeviceBitfield()});
461     auto &commandStreamReceiver = cmdQ.getGpgpuCommandStreamReceiver();
462     commandStreamReceiver.getInternalAllocationStorage()->storeAllocation(std::unique_ptr<GraphicsAllocation>(allocation), REUSABLE_ALLOCATION);
463 
464     EXPECT_FALSE(commandStreamReceiver.getAllocationsForReuse().peekIsEmpty());
465     EXPECT_TRUE(commandStreamReceiver.getAllocationsForReuse().peekContains(*allocation));
466 
467     const auto &indirectHeap = cmdQ.getCS(100);
468 
469     EXPECT_EQ(indirectHeap.getGraphicsAllocation(), allocation);
470 
471     EXPECT_TRUE(commandStreamReceiver.getAllocationsForReuse().peekIsEmpty());
472 }
473 
TEST_F(CommandQueueCommandStreamTest,givenCommandQueueWhenItIsDestroyedThenCommandStreamIsPutOnTheReusabeList)474 TEST_F(CommandQueueCommandStreamTest, givenCommandQueueWhenItIsDestroyedThenCommandStreamIsPutOnTheReusabeList) {
475     auto cmdQ = new MockCommandQueue(context.get(), pClDevice, 0, false);
476     const auto &commandStream = cmdQ->getCS(100);
477     auto graphicsAllocation = commandStream.getGraphicsAllocation();
478     EXPECT_TRUE(pDevice->getDefaultEngine().commandStreamReceiver->getAllocationsForReuse().peekIsEmpty());
479 
480     //now destroy command queue, heap should go to reusable list
481     delete cmdQ;
482     EXPECT_FALSE(pDevice->getDefaultEngine().commandStreamReceiver->getAllocationsForReuse().peekIsEmpty());
483     EXPECT_TRUE(pDevice->getDefaultEngine().commandStreamReceiver->getAllocationsForReuse().peekContains(*graphicsAllocation));
484 }
485 
TEST_F(CommandQueueCommandStreamTest,WhenAskedForNewCommandStreamThenOldHeapIsStoredForReuse)486 TEST_F(CommandQueueCommandStreamTest, WhenAskedForNewCommandStreamThenOldHeapIsStoredForReuse) {
487     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
488     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
489 
490     EXPECT_TRUE(pDevice->getDefaultEngine().commandStreamReceiver->getAllocationsForReuse().peekIsEmpty());
491 
492     const auto &indirectHeap = cmdQ.getCS(100);
493 
494     EXPECT_TRUE(pDevice->getDefaultEngine().commandStreamReceiver->getAllocationsForReuse().peekIsEmpty());
495 
496     auto graphicsAllocation = indirectHeap.getGraphicsAllocation();
497 
498     cmdQ.getCS(indirectHeap.getAvailableSpace() + 100);
499 
500     EXPECT_FALSE(pDevice->getDefaultEngine().commandStreamReceiver->getAllocationsForReuse().peekIsEmpty());
501 
502     EXPECT_TRUE(pDevice->getDefaultEngine().commandStreamReceiver->getAllocationsForReuse().peekContains(*graphicsAllocation));
503 }
504 
TEST_F(CommandQueueCommandStreamTest,givenCommandQueueWhenGetCSIsCalledThenCommandStreamAllocationTypeShouldBeSetToCommandBuffer)505 TEST_F(CommandQueueCommandStreamTest, givenCommandQueueWhenGetCSIsCalledThenCommandStreamAllocationTypeShouldBeSetToCommandBuffer) {
506     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
507     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
508 
509     const auto &commandStream = cmdQ.getCS(100);
510     auto commandStreamAllocation = commandStream.getGraphicsAllocation();
511     ASSERT_NE(nullptr, commandStreamAllocation);
512 
513     EXPECT_EQ(GraphicsAllocation::AllocationType::COMMAND_BUFFER, commandStreamAllocation->getAllocationType());
514 }
515 
HWTEST_F(CommandQueueCommandStreamTest,givenMultiDispatchInfoWithSingleKernelWithFlushAllocationsDisabledWhenEstimatingNodesCountThenItEqualsMultiDispatchInfoSize)516 HWTEST_F(CommandQueueCommandStreamTest, givenMultiDispatchInfoWithSingleKernelWithFlushAllocationsDisabledWhenEstimatingNodesCountThenItEqualsMultiDispatchInfoSize) {
517     DebugManagerStateRestore dbgRestore;
518     DebugManager.flags.EnableCacheFlushAfterWalker.set(0);
519 
520     MockCommandQueueHw<FamilyType> cmdQ(context.get(), pClDevice, nullptr);
521     pDevice->getUltCommandStreamReceiver<FamilyType>().multiOsContextCapable = true;
522     MockKernelWithInternals mockKernelWithInternals(*pClDevice, context.get());
523 
524     mockKernelWithInternals.mockKernel->kernelArgRequiresCacheFlush.resize(1);
525     MockGraphicsAllocation cacheRequiringAllocation;
526     mockKernelWithInternals.mockKernel->kernelArgRequiresCacheFlush[0] = &cacheRequiringAllocation;
527 
528     MockMultiDispatchInfo multiDispatchInfo(pClDevice, std::vector<Kernel *>({mockKernelWithInternals.mockKernel}));
529 
530     size_t estimatedNodesCount = cmdQ.estimateTimestampPacketNodesCount(multiDispatchInfo);
531     EXPECT_EQ(estimatedNodesCount, multiDispatchInfo.size());
532 }
533 
HWTEST_F(CommandQueueCommandStreamTest,givenMultiDispatchInfoWithSingleKernelWithFlushAllocationsEnabledWhenEstimatingNodesCountThenItEqualsMultiDispatchInfoSizePlusOne)534 HWTEST_F(CommandQueueCommandStreamTest, givenMultiDispatchInfoWithSingleKernelWithFlushAllocationsEnabledWhenEstimatingNodesCountThenItEqualsMultiDispatchInfoSizePlusOne) {
535     DebugManagerStateRestore dbgRestore;
536     DebugManager.flags.EnableCacheFlushAfterWalker.set(1);
537 
538     MockCommandQueueHw<FamilyType> cmdQ(context.get(), pClDevice, nullptr);
539     MockKernelWithInternals mockKernelWithInternals(*pClDevice, context.get());
540 
541     mockKernelWithInternals.mockKernel->kernelArgRequiresCacheFlush.resize(1);
542     MockGraphicsAllocation cacheRequiringAllocation;
543     mockKernelWithInternals.mockKernel->kernelArgRequiresCacheFlush[0] = &cacheRequiringAllocation;
544 
545     MockMultiDispatchInfo multiDispatchInfo(pClDevice, std::vector<Kernel *>({mockKernelWithInternals.mockKernel}));
546 
547     size_t estimatedNodesCount = cmdQ.estimateTimestampPacketNodesCount(multiDispatchInfo);
548     EXPECT_EQ(estimatedNodesCount, multiDispatchInfo.size() + 1);
549 }
550 
551 struct CommandQueueIndirectHeapTest : public CommandQueueMemoryDevice,
552                                       public ::testing::TestWithParam<IndirectHeap::Type> {
SetUpCommandQueueIndirectHeapTest553     void SetUp() override {
554         CommandQueueMemoryDevice::SetUp();
555         context.reset(new MockContext(pClDevice));
556     }
557 
TearDownCommandQueueIndirectHeapTest558     void TearDown() override {
559         context.reset();
560         CommandQueueMemoryDevice::TearDown();
561     }
562     std::unique_ptr<MockContext> context;
563 };
564 
TEST_P(CommandQueueIndirectHeapTest,WhenGettingIndirectHeapThenValidObjectIsReturned)565 TEST_P(CommandQueueIndirectHeapTest, WhenGettingIndirectHeapThenValidObjectIsReturned) {
566     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
567     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
568 
569     auto &indirectHeap = cmdQ.getIndirectHeap(this->GetParam(), 8192);
570     EXPECT_NE(nullptr, &indirectHeap);
571 }
572 
HWTEST_P(CommandQueueIndirectHeapTest,givenIndirectObjectHeapWhenItIsQueriedForInternalAllocationThenTrueIsReturned)573 HWTEST_P(CommandQueueIndirectHeapTest, givenIndirectObjectHeapWhenItIsQueriedForInternalAllocationThenTrueIsReturned) {
574     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
575     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
576     auto &commandStreamReceiver = pClDevice->getUltCommandStreamReceiver<FamilyType>();
577 
578     auto &indirectHeap = cmdQ.getIndirectHeap(this->GetParam(), 8192);
579     if (this->GetParam() == IndirectHeap::INDIRECT_OBJECT && commandStreamReceiver.canUse4GbHeaps) {
580         EXPECT_TRUE(indirectHeap.getGraphicsAllocation()->is32BitAllocation());
581     } else {
582         EXPECT_FALSE(indirectHeap.getGraphicsAllocation()->is32BitAllocation());
583     }
584 }
585 
HWTEST_P(CommandQueueIndirectHeapTest,GivenIndirectHeapWhenGettingAvailableSpaceThenCorrectSizeIsReturned)586 HWTEST_P(CommandQueueIndirectHeapTest, GivenIndirectHeapWhenGettingAvailableSpaceThenCorrectSizeIsReturned) {
587     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
588     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
589 
590     auto &indirectHeap = cmdQ.getIndirectHeap(this->GetParam(), sizeof(uint32_t));
591     if (this->GetParam() == IndirectHeap::SURFACE_STATE) {
592         size_t expectedSshUse = cmdQ.getGpgpuCommandStreamReceiver().defaultSshSize - MemoryConstants::pageSize - UnitTestHelper<FamilyType>::getDefaultSshUsage();
593         EXPECT_EQ(expectedSshUse, indirectHeap.getAvailableSpace());
594     } else {
595         EXPECT_EQ(64 * KB, indirectHeap.getAvailableSpace());
596     }
597 }
598 
TEST_P(CommandQueueIndirectHeapTest,GivenRequiredSizeWhenGettingIndirectHeapThenIndirectHeapHasRequiredSize)599 TEST_P(CommandQueueIndirectHeapTest, GivenRequiredSizeWhenGettingIndirectHeapThenIndirectHeapHasRequiredSize) {
600     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
601     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
602 
603     size_t requiredSize = 16384;
604     const auto &indirectHeap = cmdQ.getIndirectHeap(this->GetParam(), requiredSize);
605     ASSERT_NE(nullptr, &indirectHeap);
606     EXPECT_GE(indirectHeap.getMaxAvailableSpace(), requiredSize);
607 }
608 
TEST_P(CommandQueueIndirectHeapTest,WhenGettingIndirectHeapWithNewSizeThenMaxAvailableSpaceIsEqualOrGreaterThanNewSize)609 TEST_P(CommandQueueIndirectHeapTest, WhenGettingIndirectHeapWithNewSizeThenMaxAvailableSpaceIsEqualOrGreaterThanNewSize) {
610     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
611     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
612 
613     auto &indirectHeapInitial = cmdQ.getIndirectHeap(this->GetParam(), 10);
614     size_t requiredSize = indirectHeapInitial.getMaxAvailableSpace() + 42;
615 
616     const auto &indirectHeap = cmdQ.getIndirectHeap(this->GetParam(), requiredSize);
617     ASSERT_NE(nullptr, &indirectHeap);
618     if (this->GetParam() == IndirectHeap::SURFACE_STATE) {
619         //no matter what SSH is always capped
620         EXPECT_EQ(cmdQ.getGpgpuCommandStreamReceiver().defaultSshSize - MemoryConstants::pageSize,
621                   indirectHeap.getMaxAvailableSpace());
622     } else {
623         EXPECT_LE(requiredSize, indirectHeap.getMaxAvailableSpace());
624     }
625 }
626 
TEST_P(CommandQueueIndirectHeapTest,WhenGettingIndirectHeapThenSizeIsAlignedToCacheLine)627 TEST_P(CommandQueueIndirectHeapTest, WhenGettingIndirectHeapThenSizeIsAlignedToCacheLine) {
628     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
629     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
630     size_t minHeapSize = 64 * KB;
631 
632     auto &indirectHeapInitial = cmdQ.getIndirectHeap(this->GetParam(), 2 * minHeapSize + 1);
633 
634     EXPECT_TRUE(isAligned<MemoryConstants::cacheLineSize>(indirectHeapInitial.getAvailableSpace()));
635 
636     indirectHeapInitial.getSpace(indirectHeapInitial.getAvailableSpace()); // use whole space to force obtain reusable
637 
638     const auto &indirectHeap = cmdQ.getIndirectHeap(this->GetParam(), minHeapSize + 1);
639 
640     ASSERT_NE(nullptr, &indirectHeap);
641     EXPECT_TRUE(isAligned<MemoryConstants::cacheLineSize>(indirectHeap.getAvailableSpace()));
642 }
643 
HWTEST_P(CommandQueueIndirectHeapTest,givenCommandStreamReceiverWithReusableAllocationsWhenAskedForHeapAllocationThenAllocationFromReusablePoolIsReturned)644 HWTEST_P(CommandQueueIndirectHeapTest, givenCommandStreamReceiverWithReusableAllocationsWhenAskedForHeapAllocationThenAllocationFromReusablePoolIsReturned) {
645     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
646     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
647 
648     auto memoryManager = pDevice->getMemoryManager();
649 
650     auto allocationSize = defaultHeapSize * 2;
651 
652     GraphicsAllocation *allocation = nullptr;
653 
654     auto &commandStreamReceiver = pClDevice->getUltCommandStreamReceiver<FamilyType>();
655     auto allocationType = GraphicsAllocation::AllocationType::LINEAR_STREAM;
656     if (this->GetParam() == IndirectHeap::INDIRECT_OBJECT && commandStreamReceiver.canUse4GbHeaps) {
657         allocationType = GraphicsAllocation::AllocationType::INTERNAL_HEAP;
658     }
659     allocation = memoryManager->allocateGraphicsMemoryWithProperties({pDevice->getRootDeviceIndex(), allocationSize, allocationType, pDevice->getDeviceBitfield()});
660     if (this->GetParam() == IndirectHeap::SURFACE_STATE) {
661         allocation->setSize(commandStreamReceiver.defaultSshSize * 2);
662     }
663 
664     commandStreamReceiver.getInternalAllocationStorage()->storeAllocation(std::unique_ptr<GraphicsAllocation>(allocation), REUSABLE_ALLOCATION);
665 
666     EXPECT_FALSE(commandStreamReceiver.getAllocationsForReuse().peekIsEmpty());
667     EXPECT_TRUE(commandStreamReceiver.getAllocationsForReuse().peekContains(*allocation));
668 
669     const auto &indirectHeap = cmdQ.getIndirectHeap(this->GetParam(), 100);
670 
671     EXPECT_EQ(indirectHeap.getGraphicsAllocation(), allocation);
672 
673     // if we obtain heap from reusable pool, we need to keep the size of allocation
674     // surface state heap is an exception, it is capped at (max_ssh_size_for_HW - page_size)
675     if (this->GetParam() == IndirectHeap::SURFACE_STATE) {
676         EXPECT_EQ(commandStreamReceiver.defaultSshSize - MemoryConstants::pageSize, indirectHeap.getMaxAvailableSpace());
677     } else {
678         EXPECT_EQ(allocationSize, indirectHeap.getMaxAvailableSpace());
679     }
680 
681     EXPECT_TRUE(commandStreamReceiver.getAllocationsForReuse().peekIsEmpty());
682 }
683 
HWTEST_P(CommandQueueIndirectHeapTest,WhenAskedForNewHeapThenOldHeapIsStoredForReuse)684 HWTEST_P(CommandQueueIndirectHeapTest, WhenAskedForNewHeapThenOldHeapIsStoredForReuse) {
685     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
686     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
687 
688     auto &commandStreamReceiver = pDevice->getUltCommandStreamReceiver<FamilyType>();
689     EXPECT_TRUE(commandStreamReceiver.getAllocationsForReuse().peekIsEmpty());
690     *commandStreamReceiver.getTagAddress() = 1u;
691     commandStreamReceiver.taskCount = 2u;
692 
693     const auto &indirectHeap = cmdQ.getIndirectHeap(this->GetParam(), 100);
694     auto heapSize = indirectHeap.getAvailableSpace();
695 
696     auto graphicsAllocation = indirectHeap.getGraphicsAllocation();
697 
698     // Request a larger heap than the first.
699     cmdQ.getIndirectHeap(this->GetParam(), heapSize + 6000);
700 
701     EXPECT_FALSE(commandStreamReceiver.getAllocationsForReuse().peekIsEmpty());
702 
703     EXPECT_TRUE(commandStreamReceiver.getAllocationsForReuse().peekContains(*graphicsAllocation));
704     *commandStreamReceiver.getTagAddress() = 2u;
705 }
706 
TEST_P(CommandQueueIndirectHeapTest,GivenCommandQueueWithoutHeapAllocationWhenAskedForNewHeapThenNewAllocationIsAcquiredWithoutStoring)707 TEST_P(CommandQueueIndirectHeapTest, GivenCommandQueueWithoutHeapAllocationWhenAskedForNewHeapThenNewAllocationIsAcquiredWithoutStoring) {
708     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
709     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
710 
711     auto memoryManager = pDevice->getMemoryManager();
712     auto &csr = pDevice->getUltCommandStreamReceiver<DEFAULT_TEST_FAMILY_NAME>();
713     EXPECT_TRUE(pDevice->getDefaultEngine().commandStreamReceiver->getAllocationsForReuse().peekIsEmpty());
714 
715     const auto &indirectHeap = cmdQ.getIndirectHeap(this->GetParam(), 100);
716     auto heapSize = indirectHeap.getAvailableSpace();
717 
718     auto graphicsAllocation = indirectHeap.getGraphicsAllocation();
719 
720     csr.indirectHeap[this->GetParam()]->replaceGraphicsAllocation(nullptr);
721     csr.indirectHeap[this->GetParam()]->replaceBuffer(nullptr, 0);
722 
723     // Request a larger heap than the first.
724     cmdQ.getIndirectHeap(this->GetParam(), heapSize + 6000);
725 
726     EXPECT_NE(graphicsAllocation, indirectHeap.getGraphicsAllocation());
727     memoryManager->freeGraphicsMemory(graphicsAllocation);
728 }
729 
TEST_P(CommandQueueIndirectHeapTest,givenCommandQueueWithResourceCachingActiveWhenQueueISDestroyedThenIndirectHeapIsNotOnReuseList)730 TEST_P(CommandQueueIndirectHeapTest, givenCommandQueueWithResourceCachingActiveWhenQueueISDestroyedThenIndirectHeapIsNotOnReuseList) {
731     auto cmdQ = new MockCommandQueue(context.get(), pClDevice, 0, false);
732     cmdQ->getIndirectHeap(this->GetParam(), 100);
733     EXPECT_TRUE(pDevice->getDefaultEngine().commandStreamReceiver->getAllocationsForReuse().peekIsEmpty());
734 
735     //now destroy command queue, heap should go to reusable list
736     delete cmdQ;
737     EXPECT_TRUE(pDevice->getDefaultEngine().commandStreamReceiver->getAllocationsForReuse().peekIsEmpty());
738 }
739 
TEST_P(CommandQueueIndirectHeapTest,GivenCommandQueueWithHeapAllocatedWhenIndirectHeapIsReleasedThenHeapAllocationAndHeapBufferIsSetToNullptr)740 TEST_P(CommandQueueIndirectHeapTest, GivenCommandQueueWithHeapAllocatedWhenIndirectHeapIsReleasedThenHeapAllocationAndHeapBufferIsSetToNullptr) {
741     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
742     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
743 
744     EXPECT_TRUE(pDevice->getDefaultEngine().commandStreamReceiver->getAllocationsForReuse().peekIsEmpty());
745 
746     const auto &indirectHeap = cmdQ.getIndirectHeap(this->GetParam(), 100);
747     auto heapSize = indirectHeap.getMaxAvailableSpace();
748 
749     EXPECT_NE(0u, heapSize);
750 
751     auto graphicsAllocation = indirectHeap.getGraphicsAllocation();
752     EXPECT_NE(nullptr, graphicsAllocation);
753 
754     cmdQ.releaseIndirectHeap(this->GetParam());
755     auto &csr = pDevice->getUltCommandStreamReceiver<DEFAULT_TEST_FAMILY_NAME>();
756 
757     EXPECT_EQ(nullptr, csr.indirectHeap[this->GetParam()]->getGraphicsAllocation());
758 
759     EXPECT_EQ(nullptr, indirectHeap.getCpuBase());
760     EXPECT_EQ(0u, indirectHeap.getMaxAvailableSpace());
761 }
762 
TEST_P(CommandQueueIndirectHeapTest,GivenCommandQueueWithoutHeapAllocatedWhenIndirectHeapIsReleasedThenIndirectHeapAllocationStaysNull)763 TEST_P(CommandQueueIndirectHeapTest, GivenCommandQueueWithoutHeapAllocatedWhenIndirectHeapIsReleasedThenIndirectHeapAllocationStaysNull) {
764     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
765     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
766 
767     cmdQ.releaseIndirectHeap(this->GetParam());
768     auto &csr = pDevice->getUltCommandStreamReceiver<DEFAULT_TEST_FAMILY_NAME>();
769 
770     EXPECT_EQ(nullptr, csr.indirectHeap[this->GetParam()]);
771 }
772 
TEST_P(CommandQueueIndirectHeapTest,GivenCommandQueueWithHeapWhenGraphicAllocationIsNullThenNothingOnReuseList)773 TEST_P(CommandQueueIndirectHeapTest, GivenCommandQueueWithHeapWhenGraphicAllocationIsNullThenNothingOnReuseList) {
774     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
775     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
776 
777     auto &ih = cmdQ.getIndirectHeap(this->GetParam(), 0u);
778     auto allocation = ih.getGraphicsAllocation();
779     EXPECT_NE(nullptr, allocation);
780     auto &csr = pDevice->getUltCommandStreamReceiver<DEFAULT_TEST_FAMILY_NAME>();
781 
782     csr.indirectHeap[this->GetParam()]->replaceGraphicsAllocation(nullptr);
783     csr.indirectHeap[this->GetParam()]->replaceBuffer(nullptr, 0);
784 
785     cmdQ.releaseIndirectHeap(this->GetParam());
786 
787     auto memoryManager = pDevice->getMemoryManager();
788     EXPECT_TRUE(pDevice->getDefaultEngine().commandStreamReceiver->getAllocationsForReuse().peekIsEmpty());
789 
790     memoryManager->freeGraphicsMemory(allocation);
791 }
792 
HWTEST_P(CommandQueueIndirectHeapTest,givenCommandQueueWhenGetIndirectHeapIsCalledThenIndirectHeapAllocationTypeShouldBeSetToInternalHeapForIohAndLinearStreamForOthers)793 HWTEST_P(CommandQueueIndirectHeapTest, givenCommandQueueWhenGetIndirectHeapIsCalledThenIndirectHeapAllocationTypeShouldBeSetToInternalHeapForIohAndLinearStreamForOthers) {
794     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
795     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
796     auto &commandStreamReceiver = pClDevice->getUltCommandStreamReceiver<FamilyType>();
797 
798     auto heapType = this->GetParam();
799 
800     bool requireInternalHeap = IndirectHeap::INDIRECT_OBJECT == heapType && commandStreamReceiver.canUse4GbHeaps;
801     const auto &indirectHeap = cmdQ.getIndirectHeap(heapType, 100);
802     auto indirectHeapAllocation = indirectHeap.getGraphicsAllocation();
803     ASSERT_NE(nullptr, indirectHeapAllocation);
804     auto expectedAllocationType = GraphicsAllocation::AllocationType::LINEAR_STREAM;
805     if (requireInternalHeap) {
806         expectedAllocationType = GraphicsAllocation::AllocationType::INTERNAL_HEAP;
807     }
808     EXPECT_EQ(expectedAllocationType, indirectHeapAllocation->getAllocationType());
809 }
810 
TEST_P(CommandQueueIndirectHeapTest,givenCommandQueueWhenGetHeapMemoryIsCalledThenHeapIsCreated)811 TEST_P(CommandQueueIndirectHeapTest, givenCommandQueueWhenGetHeapMemoryIsCalledThenHeapIsCreated) {
812     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
813     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
814 
815     IndirectHeap *indirectHeap = nullptr;
816     cmdQ.allocateHeapMemory(this->GetParam(), 100, indirectHeap);
817     EXPECT_NE(nullptr, indirectHeap);
818     EXPECT_NE(nullptr, indirectHeap->getGraphicsAllocation());
819 
820     pDevice->getMemoryManager()->freeGraphicsMemory(indirectHeap->getGraphicsAllocation());
821     delete indirectHeap;
822 }
823 
TEST_P(CommandQueueIndirectHeapTest,givenCommandQueueWhenGetHeapMemoryIsCalledWithAlreadyAllocatedHeapThenGraphicsAllocationIsCreated)824 TEST_P(CommandQueueIndirectHeapTest, givenCommandQueueWhenGetHeapMemoryIsCalledWithAlreadyAllocatedHeapThenGraphicsAllocationIsCreated) {
825     const cl_queue_properties props[3] = {CL_QUEUE_PROPERTIES, 0, 0};
826     MockCommandQueue cmdQ(context.get(), pClDevice, props, false);
827 
828     IndirectHeap heap(nullptr, size_t{100});
829 
830     IndirectHeap *indirectHeap = &heap;
831     cmdQ.allocateHeapMemory(this->GetParam(), 100, indirectHeap);
832     EXPECT_EQ(&heap, indirectHeap);
833     EXPECT_NE(nullptr, indirectHeap->getGraphicsAllocation());
834 
835     pDevice->getMemoryManager()->freeGraphicsMemory(indirectHeap->getGraphicsAllocation());
836 }
837 
838 INSTANTIATE_TEST_CASE_P(
839     Device,
840     CommandQueueIndirectHeapTest,
841     testing::Values(
842         IndirectHeap::DYNAMIC_STATE,
843         IndirectHeap::INDIRECT_OBJECT,
844         IndirectHeap::SURFACE_STATE));
845 
846 using CommandQueueTests = ::testing::Test;
HWTEST_F(CommandQueueTests,givenMultipleCommandQueuesWhenMarkerIsEmittedThenGraphicsAllocationIsReused)847 HWTEST_F(CommandQueueTests, givenMultipleCommandQueuesWhenMarkerIsEmittedThenGraphicsAllocationIsReused) {
848     auto device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
849     MockContext context(device.get());
850     std::unique_ptr<CommandQueue> commandQ(new MockCommandQueue(&context, device.get(), 0, false));
851     *device->getDefaultEngine().commandStreamReceiver->getTagAddress() = 0;
852     commandQ->enqueueMarkerWithWaitList(0, nullptr, nullptr);
853     commandQ->enqueueMarkerWithWaitList(0, nullptr, nullptr);
854 
855     auto commandStreamGraphicsAllocation = commandQ->getCS(0).getGraphicsAllocation();
856     commandQ.reset(new MockCommandQueue(&context, device.get(), 0, false));
857     commandQ->enqueueMarkerWithWaitList(0, nullptr, nullptr);
858     commandQ->enqueueMarkerWithWaitList(0, nullptr, nullptr);
859     auto commandStreamGraphicsAllocation2 = commandQ->getCS(0).getGraphicsAllocation();
860     EXPECT_EQ(commandStreamGraphicsAllocation, commandStreamGraphicsAllocation2);
861 }
862 
HWTEST_F(CommandQueueTests,givenEngineUsageHintSetWithInvalidValueWhenCreatingCommandQueueThenReturnSuccess)863 HWTEST_F(CommandQueueTests, givenEngineUsageHintSetWithInvalidValueWhenCreatingCommandQueueThenReturnSuccess) {
864     DebugManagerStateRestore restore;
865     DebugManager.flags.EngineUsageHint.set(static_cast<int32_t>(EngineUsage::EngineUsageCount));
866 
867     auto pDevice = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
868     MockContext context(pDevice.get());
869 
870     cl_int retVal = CL_SUCCESS;
871     cl_queue_properties propertiesCooperativeQueue[] = {CL_QUEUE_FAMILY_INTEL, 0, CL_QUEUE_INDEX_INTEL, 0, 0};
872 
873     auto pCmdQ = CommandQueue::create(
874         &context,
875         pDevice.get(),
876         propertiesCooperativeQueue,
877         false,
878         retVal);
879     EXPECT_EQ(CL_SUCCESS, retVal);
880     EXPECT_NE(nullptr, pCmdQ);
881     EXPECT_EQ(EngineUsage::Regular, pCmdQ->getGpgpuEngine().getEngineUsage());
882     delete pCmdQ;
883 }
884 
885 struct WaitForQueueCompletionTests : public ::testing::Test {
886     template <typename Family>
887     struct MyCmdQueue : public CommandQueueHw<Family> {
MyCmdQueueWaitForQueueCompletionTests::MyCmdQueue888         MyCmdQueue(Context *context, ClDevice *device) : CommandQueueHw<Family>(context, device, nullptr, false){};
waitUntilCompleteWaitForQueueCompletionTests::MyCmdQueue889         void waitUntilComplete(uint32_t gpgpuTaskCountToWait, Range<CopyEngineState> copyEnginesToWait, FlushStamp flushStampToWait, bool useQuickKmdSleep, bool cleanTemporaryAllocationList, bool skipWait) override {
890             requestedUseQuickKmdSleep = useQuickKmdSleep;
891             waitUntilCompleteCounter++;
892         }
isQueueBlockedWaitForQueueCompletionTests::MyCmdQueue893         bool isQueueBlocked() override {
894             return false;
895         }
896         bool requestedUseQuickKmdSleep = false;
897         uint32_t waitUntilCompleteCounter = 0;
898     };
899 
SetUpWaitForQueueCompletionTests900     void SetUp() override {
901         device = std::make_unique<MockClDevice>(MockClDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
902         context.reset(new MockContext(device.get()));
903     }
904 
905     std::unique_ptr<MockClDevice> device;
906     std::unique_ptr<MockContext> context;
907 };
908 
HWTEST_F(WaitForQueueCompletionTests,givenBlockingCallAndUnblockedQueueWhenEnqueuedThenCallWaitWithoutQuickKmdSleepRequest)909 HWTEST_F(WaitForQueueCompletionTests, givenBlockingCallAndUnblockedQueueWhenEnqueuedThenCallWaitWithoutQuickKmdSleepRequest) {
910     std::unique_ptr<MyCmdQueue<FamilyType>> cmdQ(new MyCmdQueue<FamilyType>(context.get(), device.get()));
911     uint32_t tmpPtr = 0;
912     auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create(context.get()));
913     cmdQ->enqueueReadBuffer(buffer.get(), CL_TRUE, 0, 1, &tmpPtr, nullptr, 0, nullptr, nullptr);
914     EXPECT_EQ(1u, cmdQ->waitUntilCompleteCounter);
915     EXPECT_FALSE(cmdQ->requestedUseQuickKmdSleep);
916 }
917 
HWTEST_F(WaitForQueueCompletionTests,givenBlockingCallAndBlockedQueueWhenEnqueuedThenCallWaitWithoutQuickKmdSleepRequest)918 HWTEST_F(WaitForQueueCompletionTests, givenBlockingCallAndBlockedQueueWhenEnqueuedThenCallWaitWithoutQuickKmdSleepRequest) {
919     std::unique_ptr<MyCmdQueue<FamilyType>> cmdQ(new MyCmdQueue<FamilyType>(context.get(), device.get()));
920     std::unique_ptr<Event> blockingEvent(new Event(cmdQ.get(), CL_COMMAND_NDRANGE_KERNEL, 0, 0));
921     cl_event clBlockingEvent = blockingEvent.get();
922     uint32_t tmpPtr = 0;
923     auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create(context.get()));
924     cmdQ->enqueueReadBuffer(buffer.get(), CL_TRUE, 0, 1, &tmpPtr, nullptr, 1, &clBlockingEvent, nullptr);
925     EXPECT_EQ(1u, cmdQ->waitUntilCompleteCounter);
926     EXPECT_FALSE(cmdQ->requestedUseQuickKmdSleep);
927 }
928 
HWTEST_F(WaitForQueueCompletionTests,whenFinishIsCalledThenCallWaitWithoutQuickKmdSleepRequest)929 HWTEST_F(WaitForQueueCompletionTests, whenFinishIsCalledThenCallWaitWithoutQuickKmdSleepRequest) {
930     std::unique_ptr<MyCmdQueue<FamilyType>> cmdQ(new MyCmdQueue<FamilyType>(context.get(), device.get()));
931     cmdQ->finish();
932     EXPECT_EQ(1u, cmdQ->waitUntilCompleteCounter);
933     EXPECT_FALSE(cmdQ->requestedUseQuickKmdSleep);
934 }
935 
936 template <class GfxFamily>
937 class CommandStreamReceiverHwMock : public CommandStreamReceiverHw<GfxFamily> {
938   public:
CommandStreamReceiverHwMock(ExecutionEnvironment & executionEnvironment,uint32_t rootDeviceIndex,const DeviceBitfield deviceBitfield)939     CommandStreamReceiverHwMock(ExecutionEnvironment &executionEnvironment,
940                                 uint32_t rootDeviceIndex,
941                                 const DeviceBitfield deviceBitfield)
942         : CommandStreamReceiverHw<GfxFamily>(executionEnvironment, rootDeviceIndex, deviceBitfield) {}
943     bool wiatForTaskCountCalled = false;
944 
waitForTaskCountWithKmdNotifyFallback(uint32_t taskCountToWait,FlushStamp flushStampToWait,bool useQuickKmdSleep,bool forcePowerSavingMode)945     void waitForTaskCountWithKmdNotifyFallback(uint32_t taskCountToWait, FlushStamp flushStampToWait, bool useQuickKmdSleep, bool forcePowerSavingMode) override {
946         return;
947     }
948 
waitForTaskCount(uint32_t requiredTaskCount)949     void waitForTaskCount(uint32_t requiredTaskCount) override {
950         wiatForTaskCountCalled = true;
951         return;
952     }
953 };
954 
955 struct WaitUntilCompletionTests : public ::testing::Test {
956     template <typename Family>
957     struct MyCmdQueue : public CommandQueueHw<Family> {
958       public:
959         using CommandQueue::gpgpuEngine;
960 
MyCmdQueueWaitUntilCompletionTests::MyCmdQueue961         MyCmdQueue(Context *context, ClDevice *device) : CommandQueueHw<Family>(context, device, nullptr, false){};
962     };
963 
SetUpWaitUntilCompletionTests964     void SetUp() override {
965         device = std::make_unique<MockClDevice>(MockClDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
966         context.reset(new MockContext(device.get()));
967     }
968 
969     std::unique_ptr<MockClDevice> device;
970     std::unique_ptr<MockContext> context;
971 };
972 
HWTEST_F(WaitUntilCompletionTests,givenCommandQueueAndCleanTemporaryAllocationListWhenWaitUntilCompleteThenWaitForTaskCountIsCalled)973 HWTEST_F(WaitUntilCompletionTests, givenCommandQueueAndCleanTemporaryAllocationListWhenWaitUntilCompleteThenWaitForTaskCountIsCalled) {
974     std::unique_ptr<CommandStreamReceiverHwMock<FamilyType>> cmdStream(new CommandStreamReceiverHwMock<FamilyType>(*device->getExecutionEnvironment(), device->getRootDeviceIndex(), device->getDeviceBitfield()));
975     cmdStream->initializeTagAllocation();
976     std::unique_ptr<MyCmdQueue<FamilyType>> cmdQ(new MyCmdQueue<FamilyType>(context.get(), device.get()));
977     CommandStreamReceiver *oldCommandStreamReceiver = cmdQ->gpgpuEngine->commandStreamReceiver;
978 
979     cmdQ->gpgpuEngine->commandStreamReceiver = cmdStream.get();
980     uint32_t taskCount = 0u;
981     StackVec<CopyEngineState, bcsInfoMaskSize> activeBcsStates{};
982     cmdQ->waitUntilComplete(taskCount, activeBcsStates, cmdQ->flushStamp->peekStamp(), false, false, false);
983 
984     auto cmdStreamPtr = &device->getGpgpuCommandStreamReceiver();
985 
986     EXPECT_TRUE(static_cast<CommandStreamReceiverHwMock<FamilyType> *>(cmdStreamPtr)->wiatForTaskCountCalled);
987 
988     cmdQ->gpgpuEngine->commandStreamReceiver = oldCommandStreamReceiver;
989 }
990 
TEST(CommandQueue,givenEnqueueAcquireSharedObjectsWhenNoObjectsThenReturnSuccess)991 TEST(CommandQueue, givenEnqueueAcquireSharedObjectsWhenNoObjectsThenReturnSuccess) {
992     MockContext context;
993     MockCommandQueue cmdQ(&context, nullptr, 0, false);
994 
995     cl_uint numObjects = 0;
996     cl_mem *memObjects = nullptr;
997 
998     cl_int result = cmdQ.enqueueAcquireSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0);
999     EXPECT_EQ(result, CL_SUCCESS);
1000 }
1001 
1002 class MockSharingHandler : public SharingHandler {
1003   public:
synchronizeObject(UpdateData & updateData)1004     void synchronizeObject(UpdateData &updateData) override {
1005         updateData.synchronizationStatus = ACQUIRE_SUCCESFUL;
1006     }
1007 };
1008 
TEST(CommandQueue,givenEnqueuesForSharedObjectsWithImageWhenUsingSharingHandlerThenReturnSuccess)1009 TEST(CommandQueue, givenEnqueuesForSharedObjectsWithImageWhenUsingSharingHandlerThenReturnSuccess) {
1010     MockContext context;
1011     MockCommandQueue cmdQ(&context, context.getDevice(0), 0, false);
1012     MockSharingHandler *mockSharingHandler = new MockSharingHandler;
1013 
1014     auto image = std::unique_ptr<Image>(ImageHelper<Image2dDefaults>::create(&context));
1015     image->setSharingHandler(mockSharingHandler);
1016 
1017     cl_mem memObject = image.get();
1018     cl_uint numObjects = 1;
1019     cl_mem *memObjects = &memObject;
1020 
1021     cl_int result = cmdQ.enqueueAcquireSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0);
1022     EXPECT_EQ(result, CL_SUCCESS);
1023 
1024     result = cmdQ.enqueueReleaseSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0);
1025     EXPECT_EQ(result, CL_SUCCESS);
1026 }
1027 
TEST(CommandQueue,givenEnqueuesForSharedObjectsWithImageWhenUsingSharingHandlerWithEventThenReturnSuccess)1028 TEST(CommandQueue, givenEnqueuesForSharedObjectsWithImageWhenUsingSharingHandlerWithEventThenReturnSuccess) {
1029     auto mockDevice = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(nullptr));
1030     MockContext context;
1031     MockCommandQueue cmdQ(&context, mockDevice.get(), 0, false);
1032     MockSharingHandler *mockSharingHandler = new MockSharingHandler;
1033 
1034     auto image = std::unique_ptr<Image>(ImageHelper<Image2dDefaults>::create(&context));
1035     image->setSharingHandler(mockSharingHandler);
1036 
1037     cl_mem memObject = image.get();
1038     cl_uint numObjects = 1;
1039     cl_mem *memObjects = &memObject;
1040 
1041     Event *eventAcquire = new Event(&cmdQ, CL_COMMAND_NDRANGE_KERNEL, 1, 5);
1042     cl_event clEventAquire = eventAcquire;
1043     cl_int result = cmdQ.enqueueAcquireSharedObjects(numObjects, memObjects, 0, nullptr, &clEventAquire, 0);
1044     EXPECT_EQ(result, CL_SUCCESS);
1045     ASSERT_NE(clEventAquire, nullptr);
1046     eventAcquire->release();
1047 
1048     Event *eventRelease = new Event(&cmdQ, CL_COMMAND_NDRANGE_KERNEL, 1, 5);
1049     cl_event clEventRelease = eventRelease;
1050     result = cmdQ.enqueueReleaseSharedObjects(numObjects, memObjects, 0, nullptr, &clEventRelease, 0);
1051     EXPECT_EQ(result, CL_SUCCESS);
1052     ASSERT_NE(clEventRelease, nullptr);
1053     eventRelease->release();
1054 }
1055 
TEST(CommandQueue,givenEnqueueAcquireSharedObjectsWhenIncorrectArgumentsThenReturnProperError)1056 TEST(CommandQueue, givenEnqueueAcquireSharedObjectsWhenIncorrectArgumentsThenReturnProperError) {
1057     MockContext context;
1058     MockCommandQueue cmdQ(&context, nullptr, 0, false);
1059 
1060     cl_uint numObjects = 1;
1061     cl_mem *memObjects = nullptr;
1062 
1063     cl_int result = cmdQ.enqueueAcquireSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0);
1064     EXPECT_EQ(result, CL_INVALID_VALUE);
1065 
1066     numObjects = 0;
1067     memObjects = (cl_mem *)1;
1068 
1069     result = cmdQ.enqueueAcquireSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0);
1070     EXPECT_EQ(result, CL_INVALID_VALUE);
1071 
1072     numObjects = 0;
1073     memObjects = (cl_mem *)1;
1074 
1075     result = cmdQ.enqueueAcquireSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0);
1076     EXPECT_EQ(result, CL_INVALID_VALUE);
1077 
1078     cl_mem memObject = nullptr;
1079 
1080     numObjects = 1;
1081     memObjects = &memObject;
1082 
1083     result = cmdQ.enqueueAcquireSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0);
1084     EXPECT_EQ(result, CL_INVALID_MEM_OBJECT);
1085 
1086     auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create(&context));
1087     memObject = buffer.get();
1088 
1089     numObjects = 1;
1090     memObjects = &memObject;
1091 
1092     result = cmdQ.enqueueAcquireSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0);
1093     EXPECT_EQ(result, CL_INVALID_MEM_OBJECT);
1094 }
1095 
TEST(CommandQueue,givenEnqueueReleaseSharedObjectsWhenNoObjectsThenReturnSuccess)1096 TEST(CommandQueue, givenEnqueueReleaseSharedObjectsWhenNoObjectsThenReturnSuccess) {
1097     MockContext context;
1098     MockCommandQueue cmdQ(&context, nullptr, 0, false);
1099 
1100     cl_uint numObjects = 0;
1101     cl_mem *memObjects = nullptr;
1102 
1103     cl_int result = cmdQ.enqueueReleaseSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0);
1104     EXPECT_EQ(result, CL_SUCCESS);
1105 }
1106 
TEST(CommandQueue,givenEnqueueReleaseSharedObjectsWhenIncorrectArgumentsThenReturnProperError)1107 TEST(CommandQueue, givenEnqueueReleaseSharedObjectsWhenIncorrectArgumentsThenReturnProperError) {
1108     MockContext context;
1109     MockCommandQueue cmdQ(&context, nullptr, 0, false);
1110 
1111     cl_uint numObjects = 1;
1112     cl_mem *memObjects = nullptr;
1113 
1114     cl_int result = cmdQ.enqueueReleaseSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0);
1115     EXPECT_EQ(result, CL_INVALID_VALUE);
1116 
1117     numObjects = 0;
1118     memObjects = (cl_mem *)1;
1119 
1120     result = cmdQ.enqueueReleaseSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0);
1121     EXPECT_EQ(result, CL_INVALID_VALUE);
1122 
1123     numObjects = 0;
1124     memObjects = (cl_mem *)1;
1125 
1126     result = cmdQ.enqueueReleaseSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0);
1127     EXPECT_EQ(result, CL_INVALID_VALUE);
1128 
1129     cl_mem memObject = nullptr;
1130 
1131     numObjects = 1;
1132     memObjects = &memObject;
1133 
1134     result = cmdQ.enqueueReleaseSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0);
1135     EXPECT_EQ(result, CL_INVALID_MEM_OBJECT);
1136 
1137     auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create(&context));
1138     memObject = buffer.get();
1139 
1140     numObjects = 1;
1141     memObjects = &memObject;
1142 
1143     result = cmdQ.enqueueReleaseSharedObjects(numObjects, memObjects, 0, nullptr, nullptr, 0);
1144     EXPECT_EQ(result, CL_INVALID_MEM_OBJECT);
1145 }
1146 
TEST(CommandQueue,givenEnqueueAcquireSharedObjectsCallWhenAcquireFailsThenCorrectErrorIsReturned)1147 TEST(CommandQueue, givenEnqueueAcquireSharedObjectsCallWhenAcquireFailsThenCorrectErrorIsReturned) {
1148     const auto rootDeviceIndex = 1u;
1149     class MockSharingHandler : public SharingHandler {
1150         int validateUpdateData(UpdateData &data) override {
1151             EXPECT_EQ(1u, data.rootDeviceIndex);
1152             return CL_INVALID_MEM_OBJECT;
1153         }
1154     };
1155 
1156     UltClDeviceFactory deviceFactory{2, 0};
1157     MockContext context(deviceFactory.rootDevices[rootDeviceIndex]);
1158     MockCommandQueue cmdQ(&context, context.getDevice(0), 0, false);
1159     auto buffer = std::unique_ptr<Buffer>(BufferHelper<>::create(&context));
1160 
1161     MockSharingHandler *handler = new MockSharingHandler;
1162     buffer->setSharingHandler(handler);
1163     cl_mem memObject = buffer.get();
1164     auto retVal = cmdQ.enqueueAcquireSharedObjects(1, &memObject, 0, nullptr, nullptr, 0);
1165     EXPECT_EQ(CL_INVALID_MEM_OBJECT, retVal);
1166     buffer->setSharingHandler(nullptr);
1167 }
1168 
HWTEST_F(CommandQueueCommandStreamTest,givenDebugKernelWhenSetupDebugSurfaceIsCalledThenSurfaceStateIsCorrectlySet)1169 HWTEST_F(CommandQueueCommandStreamTest, givenDebugKernelWhenSetupDebugSurfaceIsCalledThenSurfaceStateIsCorrectlySet) {
1170     using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
1171     MockProgram program(toClDeviceVector(*pClDevice));
1172     program.enableKernelDebug();
1173     std::unique_ptr<MockDebugKernel> kernel(MockKernel::create<MockDebugKernel>(*pDevice, &program));
1174     MockCommandQueue cmdQ(context.get(), pClDevice, 0, false);
1175 
1176     const auto &systemThreadSurfaceAddress = kernel->getAllocatedKernelInfo()->kernelDescriptor.payloadMappings.implicitArgs.systemThreadSurfaceAddress.bindful;
1177     kernel->setSshLocal(nullptr, sizeof(RENDER_SURFACE_STATE) + systemThreadSurfaceAddress);
1178     auto &commandStreamReceiver = cmdQ.getGpgpuCommandStreamReceiver();
1179 
1180     cmdQ.getGpgpuCommandStreamReceiver().allocateDebugSurface(SipKernel::maxDbgSurfaceSize);
1181     cmdQ.setupDebugSurface(kernel.get());
1182 
1183     auto debugSurface = commandStreamReceiver.getDebugSurfaceAllocation();
1184     ASSERT_NE(nullptr, debugSurface);
1185     RENDER_SURFACE_STATE *surfaceState = (RENDER_SURFACE_STATE *)kernel->getSurfaceStateHeap();
1186     EXPECT_EQ(debugSurface->getGpuAddress(), surfaceState->getSurfaceBaseAddress());
1187 }
1188 
HWTEST_F(CommandQueueCommandStreamTest,givenCsrWithDebugSurfaceAllocatedWhenSetupDebugSurfaceIsCalledThenDebugSurfaceIsReused)1189 HWTEST_F(CommandQueueCommandStreamTest, givenCsrWithDebugSurfaceAllocatedWhenSetupDebugSurfaceIsCalledThenDebugSurfaceIsReused) {
1190     using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
1191     MockProgram program(toClDeviceVector(*pClDevice));
1192     program.enableKernelDebug();
1193     std::unique_ptr<MockDebugKernel> kernel(MockKernel::create<MockDebugKernel>(*pDevice, &program));
1194     MockCommandQueue cmdQ(context.get(), pClDevice, 0, false);
1195 
1196     const auto &systemThreadSurfaceAddress = kernel->getAllocatedKernelInfo()->kernelDescriptor.payloadMappings.implicitArgs.systemThreadSurfaceAddress.bindful;
1197     kernel->setSshLocal(nullptr, sizeof(RENDER_SURFACE_STATE) + systemThreadSurfaceAddress);
1198     auto &commandStreamReceiver = cmdQ.getGpgpuCommandStreamReceiver();
1199     commandStreamReceiver.allocateDebugSurface(SipKernel::maxDbgSurfaceSize);
1200     auto debugSurface = commandStreamReceiver.getDebugSurfaceAllocation();
1201     ASSERT_NE(nullptr, debugSurface);
1202 
1203     cmdQ.setupDebugSurface(kernel.get());
1204 
1205     EXPECT_EQ(debugSurface, commandStreamReceiver.getDebugSurfaceAllocation());
1206     RENDER_SURFACE_STATE *surfaceState = (RENDER_SURFACE_STATE *)kernel->getSurfaceStateHeap();
1207     EXPECT_EQ(debugSurface->getGpuAddress(), surfaceState->getSurfaceBaseAddress());
1208 }
1209 
1210 struct MockTimestampPacketContainer : TimestampPacketContainer {
MockTimestampPacketContainerMockTimestampPacketContainer1211     MockTimestampPacketContainer(Context &context) : context(context) {
1212     }
~MockTimestampPacketContainerMockTimestampPacketContainer1213     ~MockTimestampPacketContainer() override {
1214         EXPECT_EQ(1, context.getRefInternalCount());
1215     }
1216     Context &context;
1217 };
1218 
TEST(CommandQueueDestructorTest,whenCommandQueueIsDestroyedThenDestroysTimestampPacketContainerBeforeReleasingContext)1219 TEST(CommandQueueDestructorTest, whenCommandQueueIsDestroyedThenDestroysTimestampPacketContainerBeforeReleasingContext) {
1220     auto context = new MockContext;
1221     EXPECT_EQ(1, context->getRefInternalCount());
1222     MockCommandQueue queue(context, context->getDevice(0), nullptr, false);
1223     queue.timestampPacketContainer.reset(new MockTimestampPacketContainer(*context));
1224     EXPECT_EQ(2, context->getRefInternalCount());
1225     context->release();
1226     EXPECT_EQ(1, context->getRefInternalCount());
1227 }
1228 
TEST(CommandQueuePropertiesTests,whenGetEngineIsCalledThenQueueEngineIsReturned)1229 TEST(CommandQueuePropertiesTests, whenGetEngineIsCalledThenQueueEngineIsReturned) {
1230     MockCommandQueue queue;
1231     EngineControl engineControl;
1232     queue.gpgpuEngine = &engineControl;
1233     EXPECT_EQ(queue.gpgpuEngine, &queue.getGpgpuEngine());
1234 }
1235 
TEST(CommandQueue,GivenCommandQueueWhenEnqueueResourceBarrierCalledThenSuccessReturned)1236 TEST(CommandQueue, GivenCommandQueueWhenEnqueueResourceBarrierCalledThenSuccessReturned) {
1237     MockContext context;
1238     MockCommandQueue cmdQ(&context, nullptr, 0, false);
1239 
1240     cl_int result = cmdQ.enqueueResourceBarrier(
1241         nullptr,
1242         0,
1243         nullptr,
1244         nullptr);
1245     EXPECT_EQ(CL_SUCCESS, result);
1246 }
1247 
TEST(CommandQueue,GivenCommandQueueWhenCheckingIfIsCacheFlushCommandCalledThenFalseReturned)1248 TEST(CommandQueue, GivenCommandQueueWhenCheckingIfIsCacheFlushCommandCalledThenFalseReturned) {
1249     MockContext context;
1250     MockCommandQueue cmdQ(&context, nullptr, 0, false);
1251 
1252     bool isCommandCacheFlush = cmdQ.isCacheFlushCommand(0u);
1253     EXPECT_FALSE(isCommandCacheFlush);
1254 }
1255 
TEST(CommandQueue,givenBlitterOperationsSupportedWhenCreatingQueueThenTimestampPacketIsCreated)1256 TEST(CommandQueue, givenBlitterOperationsSupportedWhenCreatingQueueThenTimestampPacketIsCreated) {
1257     DebugManagerStateRestore restore;
1258     DebugManager.flags.EnableTimestampPacket.set(0);
1259 
1260     MockContext context{};
1261     HardwareInfo *hwInfo = context.getDevice(0)->getRootDeviceEnvironment().getMutableHardwareInfo();
1262     if (!HwInfoConfig::get(defaultHwInfo->platform.eProductFamily)->isBlitterFullySupported(*defaultHwInfo.get())) {
1263         GTEST_SKIP();
1264     }
1265 
1266     hwInfo->capabilityTable.blitterOperationsSupported = true;
1267     MockCommandQueue cmdQ(&context, context.getDevice(0), 0, false);
1268     EXPECT_NE(nullptr, cmdQ.timestampPacketContainer);
1269 }
1270 
TEST(CommandQueue,givenCopyOnlyQueueWhenCallingBlitEnqueueAllowedThenReturnTrue)1271 TEST(CommandQueue, givenCopyOnlyQueueWhenCallingBlitEnqueueAllowedThenReturnTrue) {
1272     MockContext context{};
1273     HardwareInfo *hwInfo = context.getDevice(0)->getRootDeviceEnvironment().getMutableHardwareInfo();
1274     MockCommandQueue queue(&context, context.getDevice(0), 0, false);
1275     if (queue.countBcsEngines() == 0) {
1276         queue.bcsEngines[0] = &context.getDevice(0)->getDefaultEngine();
1277     }
1278     hwInfo->capabilityTable.blitterOperationsSupported = false;
1279 
1280     MultiGraphicsAllocation multiAlloc{1};
1281     MockGraphicsAllocation alloc{};
1282     multiAlloc.addAllocation(&alloc);
1283     alloc.memoryPool = MemoryPool::System4KBPages;
1284     CsrSelectionArgs selectionArgs{CL_COMMAND_READ_BUFFER, &multiAlloc, &multiAlloc, 0u, nullptr};
1285 
1286     queue.isCopyOnly = false;
1287     EXPECT_EQ(queue.getGpgpuCommandStreamReceiver().peekTimestampPacketWriteEnabled(),
1288               queue.blitEnqueueAllowed(selectionArgs));
1289 
1290     queue.isCopyOnly = true;
1291     EXPECT_TRUE(queue.blitEnqueueAllowed(selectionArgs));
1292 }
1293 
TEST(CommandQueue,givenSimpleClCommandWhenCallingBlitEnqueueAllowedThenReturnCorrectValue)1294 TEST(CommandQueue, givenSimpleClCommandWhenCallingBlitEnqueueAllowedThenReturnCorrectValue) {
1295     MockContext context{};
1296 
1297     MockCommandQueue queue(&context, context.getDevice(0), 0, false);
1298     if (queue.countBcsEngines() == 0) {
1299         queue.bcsEngines[0] = &context.getDevice(0)->getDefaultEngine();
1300     }
1301 
1302     MultiGraphicsAllocation multiAlloc{1};
1303     MockGraphicsAllocation alloc{};
1304     multiAlloc.addAllocation(&alloc);
1305     alloc.memoryPool = MemoryPool::System4KBPages;
1306 
1307     for (cl_command_type cmdType : {CL_COMMAND_READ_BUFFER, CL_COMMAND_READ_BUFFER_RECT,
1308                                     CL_COMMAND_WRITE_BUFFER, CL_COMMAND_WRITE_BUFFER_RECT,
1309                                     CL_COMMAND_COPY_BUFFER, CL_COMMAND_COPY_BUFFER_RECT,
1310                                     CL_COMMAND_SVM_MAP, CL_COMMAND_SVM_UNMAP,
1311                                     CL_COMMAND_SVM_MEMCPY}) {
1312         CsrSelectionArgs args{cmdType, &multiAlloc, &multiAlloc, 0u, nullptr};
1313 
1314         bool expectedValue = queue.getGpgpuCommandStreamReceiver().peekTimestampPacketWriteEnabled();
1315         if (cmdType == CL_COMMAND_COPY_IMAGE_TO_BUFFER) {
1316             expectedValue = false;
1317         }
1318 
1319         EXPECT_EQ(expectedValue, queue.blitEnqueueAllowed(args));
1320     }
1321 }
1322 
TEST(CommandQueue,givenImageTransferClCommandWhenCallingBlitEnqueueAllowedThenReturnCorrectValue)1323 TEST(CommandQueue, givenImageTransferClCommandWhenCallingBlitEnqueueAllowedThenReturnCorrectValue) {
1324     DebugManagerStateRestore restore{};
1325     DebugManager.flags.EnableBlitterForEnqueueOperations.set(1);
1326     DebugManager.flags.EnableBlitterForEnqueueImageOperations.set(1);
1327 
1328     MockContext context{};
1329     MockCommandQueue queue(&context, context.getDevice(0), 0, false);
1330     if (queue.countBcsEngines() == 0) {
1331         queue.bcsEngines[0] = &context.getDevice(0)->getDefaultEngine();
1332     }
1333 
1334     MockImageBase image{};
1335     auto alloc = static_cast<MockGraphicsAllocation *>(image.getGraphicsAllocation(0));
1336     alloc->memoryPool = MemoryPool::System4KBPages;
1337 
1338     size_t origin[3] = {0, 0, 0};
1339     size_t region[3] = {1, 1, 1};
1340     {
1341         CsrSelectionArgs args{CL_COMMAND_READ_IMAGE, &image, {}, 0u, region, origin, nullptr};
1342         EXPECT_TRUE(queue.blitEnqueueAllowed(args));
1343     }
1344     {
1345         CsrSelectionArgs args{CL_COMMAND_WRITE_IMAGE, {}, &image, 0u, region, nullptr, origin};
1346         EXPECT_TRUE(queue.blitEnqueueAllowed(args));
1347     }
1348     {
1349         CsrSelectionArgs args{CL_COMMAND_COPY_IMAGE, &image, &image, 0u, region, origin, origin};
1350         EXPECT_TRUE(queue.blitEnqueueAllowed(args));
1351     }
1352 }
1353 
TEST(CommandQueue,givenImageToBufferClCommandWhenCallingBlitEnqueueAllowedThenReturnCorrectValue)1354 TEST(CommandQueue, givenImageToBufferClCommandWhenCallingBlitEnqueueAllowedThenReturnCorrectValue) {
1355     MockContext context{};
1356     MockCommandQueue queue(&context, context.getDevice(0), 0, false);
1357     if (queue.countBcsEngines() == 0) {
1358         queue.bcsEngines[0] = &context.getDevice(0)->getDefaultEngine();
1359     }
1360 
1361     MultiGraphicsAllocation multiAlloc{1};
1362     MockGraphicsAllocation alloc{};
1363     multiAlloc.addAllocation(&alloc);
1364     alloc.memoryPool = MemoryPool::System4KBPages;
1365 
1366     CsrSelectionArgs args{CL_COMMAND_COPY_IMAGE_TO_BUFFER, &multiAlloc, &multiAlloc, 0u, nullptr};
1367     EXPECT_FALSE(queue.blitEnqueueAllowed(args));
1368 }
1369 
1370 template <bool blitter, bool selectBlitterWithQueueFamilies>
1371 struct CsrSelectionCommandQueueTests : ::testing::Test {
SetUpCsrSelectionCommandQueueTests1372     void SetUp() override {
1373         HardwareInfo hwInfo = *::defaultHwInfo;
1374         hwInfo.capabilityTable.blitterOperationsSupported = blitter;
1375         if (blitter) {
1376             REQUIRE_FULL_BLITTER_OR_SKIP(&hwInfo);
1377         }
1378 
1379         device = MockDevice::createWithNewExecutionEnvironment<MockDevice>(&hwInfo);
1380         clDevice = std::make_unique<MockClDevice>(device);
1381         context = std::make_unique<MockContext>(clDevice.get());
1382 
1383         cl_command_queue_properties queueProperties[5] = {};
1384         if (selectBlitterWithQueueFamilies) {
1385             queueProperties[0] = CL_QUEUE_FAMILY_INTEL;
1386             queueProperties[1] = device->getEngineGroupIndexFromEngineGroupType(EngineGroupType::Copy);
1387             queueProperties[2] = CL_QUEUE_INDEX_INTEL;
1388             queueProperties[3] = 0;
1389         }
1390 
1391         queue = std::make_unique<MockCommandQueue>(context.get(), clDevice.get(), queueProperties, false);
1392     }
1393 
1394     MockDevice *device;
1395     std::unique_ptr<MockClDevice> clDevice;
1396     std::unique_ptr<MockContext> context;
1397     std::unique_ptr<MockCommandQueue> queue;
1398 };
1399 
1400 using CsrSelectionCommandQueueWithoutBlitterTests = CsrSelectionCommandQueueTests<false, false>;
1401 using CsrSelectionCommandQueueWithBlitterTests = CsrSelectionCommandQueueTests<true, false>;
1402 using CsrSelectionCommandQueueWithQueueFamiliesBlitterTests = CsrSelectionCommandQueueTests<true, true>;
1403 
TEST_F(CsrSelectionCommandQueueWithoutBlitterTests,givenBlitterNotPresentWhenSelectingBlitterThenReturnGpgpuCsr)1404 TEST_F(CsrSelectionCommandQueueWithoutBlitterTests, givenBlitterNotPresentWhenSelectingBlitterThenReturnGpgpuCsr) {
1405     DebugManagerStateRestore restore{};
1406     DebugManager.flags.EnableBlitterForEnqueueOperations.set(1);
1407 
1408     BuiltinOpParams builtinOpParams{};
1409     MockGraphicsAllocation srcGraphicsAllocation{};
1410     MockGraphicsAllocation dstGraphicsAllocation{};
1411     MockBuffer srcMemObj{srcGraphicsAllocation};
1412     MockBuffer dstMemObj{dstGraphicsAllocation};
1413     builtinOpParams.srcMemObj = &srcMemObj;
1414     builtinOpParams.dstMemObj = &dstMemObj;
1415 
1416     {
1417         srcGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1418         dstGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1419         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1420         EXPECT_EQ(&queue->getGpgpuCommandStreamReceiver(), &queue->selectCsrForBuiltinOperation(args));
1421     }
1422     {
1423         srcGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1424         dstGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1425         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1426         EXPECT_EQ(&queue->getGpgpuCommandStreamReceiver(), &queue->selectCsrForBuiltinOperation(args));
1427     }
1428     {
1429         srcGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1430         dstGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1431         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1432         EXPECT_EQ(&queue->getGpgpuCommandStreamReceiver(), &queue->selectCsrForBuiltinOperation(args));
1433     }
1434     {
1435         srcGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1436         dstGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1437         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1438         EXPECT_EQ(&queue->getGpgpuCommandStreamReceiver(), &queue->selectCsrForBuiltinOperation(args));
1439     }
1440 }
1441 
TEST_F(CsrSelectionCommandQueueWithBlitterTests,givenBlitterPresentButDisabledWithDebugFlagWhenSelectingBlitterThenReturnGpgpuCsr)1442 TEST_F(CsrSelectionCommandQueueWithBlitterTests, givenBlitterPresentButDisabledWithDebugFlagWhenSelectingBlitterThenReturnGpgpuCsr) {
1443     DebugManagerStateRestore restore{};
1444     DebugManager.flags.EnableBlitterForEnqueueOperations.set(0);
1445 
1446     BuiltinOpParams builtinOpParams{};
1447     MockGraphicsAllocation srcGraphicsAllocation{};
1448     MockGraphicsAllocation dstGraphicsAllocation{};
1449     MockBuffer srcMemObj{srcGraphicsAllocation};
1450     MockBuffer dstMemObj{dstGraphicsAllocation};
1451     builtinOpParams.srcMemObj = &srcMemObj;
1452     builtinOpParams.dstMemObj = &dstMemObj;
1453 
1454     {
1455         srcGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1456         dstGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1457         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1458         EXPECT_EQ(&queue->getGpgpuCommandStreamReceiver(), &queue->selectCsrForBuiltinOperation(args));
1459     }
1460     {
1461         srcGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1462         dstGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1463         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1464         EXPECT_EQ(&queue->getGpgpuCommandStreamReceiver(), &queue->selectCsrForBuiltinOperation(args));
1465     }
1466     {
1467         srcGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1468         dstGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1469         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1470         EXPECT_EQ(&queue->getGpgpuCommandStreamReceiver(), &queue->selectCsrForBuiltinOperation(args));
1471     }
1472     {
1473         srcGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1474         dstGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1475         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1476         EXPECT_EQ(&queue->getGpgpuCommandStreamReceiver(), &queue->selectCsrForBuiltinOperation(args));
1477     }
1478 }
1479 
TEST_F(CsrSelectionCommandQueueWithBlitterTests,givenBlitterPresentAndLocalToLocalCopyBufferCommandWhenSelectingBlitterThenReturnValueBasedOnDebugFlagAndHwPreference)1480 TEST_F(CsrSelectionCommandQueueWithBlitterTests, givenBlitterPresentAndLocalToLocalCopyBufferCommandWhenSelectingBlitterThenReturnValueBasedOnDebugFlagAndHwPreference) {
1481     DebugManagerStateRestore restore{};
1482     DebugManager.flags.EnableBlitterForEnqueueOperations.set(1);
1483 
1484     const bool hwPreference = ClHwHelper::get(::defaultHwInfo->platform.eRenderCoreFamily).preferBlitterForLocalToLocalTransfers();
1485     const auto &hwPreferenceCsr = hwPreference ? *queue->getBcsCommandStreamReceiver(aub_stream::ENGINE_BCS) : queue->getGpgpuCommandStreamReceiver();
1486 
1487     BuiltinOpParams builtinOpParams{};
1488     MockGraphicsAllocation srcGraphicsAllocation{};
1489     MockGraphicsAllocation dstGraphicsAllocation{};
1490     MockBuffer srcMemObj{srcGraphicsAllocation};
1491     MockBuffer dstMemObj{dstGraphicsAllocation};
1492     builtinOpParams.srcMemObj = &srcMemObj;
1493     builtinOpParams.dstMemObj = &dstMemObj;
1494 
1495     srcGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1496     dstGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1497     CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1498 
1499     DebugManager.flags.PreferCopyEngineForCopyBufferToBuffer.set(-1);
1500     EXPECT_EQ(&hwPreferenceCsr, &queue->selectCsrForBuiltinOperation(args));
1501     DebugManager.flags.PreferCopyEngineForCopyBufferToBuffer.set(0);
1502     EXPECT_EQ(&queue->getGpgpuCommandStreamReceiver(), &queue->selectCsrForBuiltinOperation(args));
1503     DebugManager.flags.PreferCopyEngineForCopyBufferToBuffer.set(1);
1504     EXPECT_EQ(queue->getBcsCommandStreamReceiver(aub_stream::ENGINE_BCS), &queue->selectCsrForBuiltinOperation(args));
1505 }
1506 
TEST_F(CsrSelectionCommandQueueWithBlitterTests,givenBlitterPresentAndNotLocalToLocalCopyBufferCommandWhenSelectingCsrThenUseBcsRegardlessOfDebugFlag)1507 TEST_F(CsrSelectionCommandQueueWithBlitterTests, givenBlitterPresentAndNotLocalToLocalCopyBufferCommandWhenSelectingCsrThenUseBcsRegardlessOfDebugFlag) {
1508     DebugManagerStateRestore restore{};
1509     DebugManager.flags.EnableBlitterForEnqueueOperations.set(1);
1510 
1511     const auto &bcsCsr = *queue->getBcsCommandStreamReceiver(aub_stream::ENGINE_BCS);
1512 
1513     BuiltinOpParams builtinOpParams{};
1514     MockGraphicsAllocation srcGraphicsAllocation{};
1515     MockGraphicsAllocation dstGraphicsAllocation{};
1516     MockBuffer srcMemObj{srcGraphicsAllocation};
1517     MockBuffer dstMemObj{dstGraphicsAllocation};
1518     builtinOpParams.srcMemObj = &srcMemObj;
1519     builtinOpParams.dstMemObj = &dstMemObj;
1520 
1521     {
1522         srcGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1523         dstGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1524         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1525         DebugManager.flags.PreferCopyEngineForCopyBufferToBuffer.set(-1);
1526         EXPECT_EQ(&bcsCsr, &queue->selectCsrForBuiltinOperation(args));
1527         DebugManager.flags.PreferCopyEngineForCopyBufferToBuffer.set(0);
1528         EXPECT_EQ(&bcsCsr, &queue->selectCsrForBuiltinOperation(args));
1529         DebugManager.flags.PreferCopyEngineForCopyBufferToBuffer.set(1);
1530         EXPECT_EQ(&bcsCsr, &queue->selectCsrForBuiltinOperation(args));
1531     }
1532     {
1533         srcGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1534         dstGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1535         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1536         DebugManager.flags.PreferCopyEngineForCopyBufferToBuffer.set(-1);
1537         EXPECT_EQ(&bcsCsr, &queue->selectCsrForBuiltinOperation(args));
1538         DebugManager.flags.PreferCopyEngineForCopyBufferToBuffer.set(0);
1539         EXPECT_EQ(&bcsCsr, &queue->selectCsrForBuiltinOperation(args));
1540         DebugManager.flags.PreferCopyEngineForCopyBufferToBuffer.set(1);
1541         EXPECT_EQ(&bcsCsr, &queue->selectCsrForBuiltinOperation(args));
1542     }
1543     {
1544         srcGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1545         dstGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1546         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1547         DebugManager.flags.PreferCopyEngineForCopyBufferToBuffer.set(-1);
1548         EXPECT_EQ(&bcsCsr, &queue->selectCsrForBuiltinOperation(args));
1549         DebugManager.flags.PreferCopyEngineForCopyBufferToBuffer.set(0);
1550         EXPECT_EQ(&bcsCsr, &queue->selectCsrForBuiltinOperation(args));
1551         DebugManager.flags.PreferCopyEngineForCopyBufferToBuffer.set(1);
1552         EXPECT_EQ(&bcsCsr, &queue->selectCsrForBuiltinOperation(args));
1553     }
1554 }
1555 
TEST_F(CsrSelectionCommandQueueWithBlitterTests,givenInvalidTransferDirectionWhenSelectingCsrThenThrowError)1556 TEST_F(CsrSelectionCommandQueueWithBlitterTests, givenInvalidTransferDirectionWhenSelectingCsrThenThrowError) {
1557     DebugManagerStateRestore restore{};
1558     DebugManager.flags.EnableBlitterForEnqueueOperations.set(1);
1559 
1560     BuiltinOpParams builtinOpParams{};
1561     MockGraphicsAllocation srcGraphicsAllocation{};
1562     MockGraphicsAllocation dstGraphicsAllocation{};
1563     MockBuffer srcMemObj{srcGraphicsAllocation};
1564     MockBuffer dstMemObj{dstGraphicsAllocation};
1565     builtinOpParams.srcMemObj = &srcMemObj;
1566     builtinOpParams.dstMemObj = &dstMemObj;
1567 
1568     CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1569     args.direction = static_cast<TransferDirection>(0xFF);
1570     EXPECT_ANY_THROW(queue->selectCsrForBuiltinOperation(args));
1571 }
1572 
TEST_F(CsrSelectionCommandQueueWithQueueFamiliesBlitterTests,givenBlitterSelectedWithQueueFamiliesWhenSelectingBlitterThenSelectBlitter)1573 TEST_F(CsrSelectionCommandQueueWithQueueFamiliesBlitterTests, givenBlitterSelectedWithQueueFamiliesWhenSelectingBlitterThenSelectBlitter) {
1574     DebugManagerStateRestore restore{};
1575 
1576     BuiltinOpParams builtinOpParams{};
1577     MockGraphicsAllocation srcGraphicsAllocation{};
1578     MockGraphicsAllocation dstGraphicsAllocation{};
1579     MockBuffer srcMemObj{srcGraphicsAllocation};
1580     MockBuffer dstMemObj{dstGraphicsAllocation};
1581     builtinOpParams.srcMemObj = &srcMemObj;
1582     builtinOpParams.dstMemObj = &dstMemObj;
1583 
1584     {
1585         srcGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1586         dstGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1587         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1588         EXPECT_EQ(queue->getBcsCommandStreamReceiver(aub_stream::ENGINE_BCS), &queue->selectCsrForBuiltinOperation(args));
1589     }
1590     {
1591         srcGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1592         dstGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1593         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1594         EXPECT_EQ(queue->getBcsCommandStreamReceiver(aub_stream::ENGINE_BCS), &queue->selectCsrForBuiltinOperation(args));
1595     }
1596     {
1597         srcGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1598         dstGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1599         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1600         EXPECT_EQ(queue->getBcsCommandStreamReceiver(aub_stream::ENGINE_BCS), &queue->selectCsrForBuiltinOperation(args));
1601     }
1602     {
1603         srcGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1604         dstGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1605         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1606         EXPECT_EQ(queue->getBcsCommandStreamReceiver(aub_stream::ENGINE_BCS), &queue->selectCsrForBuiltinOperation(args));
1607     }
1608 }
1609 
TEST_F(CsrSelectionCommandQueueWithQueueFamiliesBlitterTests,givenBlitterSelectedWithQueueFamiliesButDisabledWithDebugFlagWhenSelectingBlitterThenIgnoreDebugFlagAndSelectBlitter)1610 TEST_F(CsrSelectionCommandQueueWithQueueFamiliesBlitterTests, givenBlitterSelectedWithQueueFamiliesButDisabledWithDebugFlagWhenSelectingBlitterThenIgnoreDebugFlagAndSelectBlitter) {
1611     DebugManagerStateRestore restore{};
1612     DebugManager.flags.EnableBlitterForEnqueueOperations.set(0);
1613 
1614     BuiltinOpParams builtinOpParams{};
1615     MockGraphicsAllocation srcGraphicsAllocation{};
1616     MockGraphicsAllocation dstGraphicsAllocation{};
1617     MockBuffer srcMemObj{srcGraphicsAllocation};
1618     MockBuffer dstMemObj{dstGraphicsAllocation};
1619     builtinOpParams.srcMemObj = &srcMemObj;
1620     builtinOpParams.dstMemObj = &dstMemObj;
1621 
1622     {
1623         srcGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1624         dstGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1625         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1626         EXPECT_EQ(queue->getBcsCommandStreamReceiver(aub_stream::ENGINE_BCS), &queue->selectCsrForBuiltinOperation(args));
1627     }
1628     {
1629         srcGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1630         dstGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1631         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1632         EXPECT_EQ(queue->getBcsCommandStreamReceiver(aub_stream::ENGINE_BCS), &queue->selectCsrForBuiltinOperation(args));
1633     }
1634     {
1635         srcGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1636         dstGraphicsAllocation.memoryPool = MemoryPool::System4KBPages;
1637         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1638         EXPECT_EQ(queue->getBcsCommandStreamReceiver(aub_stream::ENGINE_BCS), &queue->selectCsrForBuiltinOperation(args));
1639     }
1640     {
1641         srcGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1642         dstGraphicsAllocation.memoryPool = MemoryPool::LocalMemory;
1643         CsrSelectionArgs args{CL_COMMAND_COPY_BUFFER, &srcMemObj, &dstMemObj, 0u, nullptr};
1644         EXPECT_EQ(queue->getBcsCommandStreamReceiver(aub_stream::ENGINE_BCS), &queue->selectCsrForBuiltinOperation(args));
1645     }
1646 }
1647 
TEST(CommandQueue,givenCopySizeAndOffsetWhenCallingBlitEnqueueImageAllowedThenReturnCorrectValue)1648 TEST(CommandQueue, givenCopySizeAndOffsetWhenCallingBlitEnqueueImageAllowedThenReturnCorrectValue) {
1649     DebugManagerStateRestore restorer;
1650     DebugManager.flags.EnableBlitterForEnqueueImageOperations.set(1);
1651     MockContext context{};
1652     MockCommandQueue queue(&context, context.getDevice(0), 0, false);
1653     MockImageBase image;
1654     image.imageDesc.num_mip_levels = 1;
1655 
1656     auto maxBlitWidth = static_cast<size_t>(BlitterConstants::maxBlitWidth);
1657     auto maxBlitHeight = static_cast<size_t>(BlitterConstants::maxBlitHeight);
1658 
1659     std::tuple<size_t, size_t, size_t, size_t, bool> testParams[]{
1660         {1, 1, 0, 0, true},
1661         {maxBlitWidth, maxBlitHeight, 0, 0, true},
1662         {maxBlitWidth + 1, maxBlitHeight, 0, 0, false},
1663         {maxBlitWidth, maxBlitHeight + 1, 0, 0, false},
1664         {maxBlitWidth, maxBlitHeight, 1, 0, false},
1665         {maxBlitWidth, maxBlitHeight, 0, 1, false},
1666         {maxBlitWidth - 1, maxBlitHeight - 1, 1, 1, true}};
1667 
1668     for (auto &[regionX, regionY, originX, originY, expectedResult] : testParams) {
1669         size_t region[3] = {regionX, regionY, 0};
1670         size_t origin[3] = {originX, originY, 0};
1671         EXPECT_EQ(expectedResult, queue.blitEnqueueImageAllowed(origin, region, image));
1672     }
1673 }
1674 
TEST(CommandQueue,givenMipMappedImageWhenCallingBlitEnqueueImageAllowedThenCorrectResultIsReturned)1675 TEST(CommandQueue, givenMipMappedImageWhenCallingBlitEnqueueImageAllowedThenCorrectResultIsReturned) {
1676     DebugManagerStateRestore restorer;
1677     DebugManager.flags.EnableBlitterForEnqueueImageOperations.set(1);
1678     MockContext context{};
1679     MockCommandQueue queue(&context, context.getDevice(0), 0, false);
1680 
1681     size_t correctRegion[3] = {10u, 10u, 0};
1682     size_t correctOrigin[3] = {1u, 1u, 0};
1683     MockImageBase image;
1684 
1685     image.imageDesc.num_mip_levels = 1;
1686     EXPECT_TRUE(queue.blitEnqueueImageAllowed(correctOrigin, correctRegion, image));
1687 
1688     image.imageDesc.num_mip_levels = 2;
1689     EXPECT_FALSE(queue.blitEnqueueImageAllowed(correctOrigin, correctRegion, image));
1690 }
1691 
TEST(CommandQueue,givenImageWithDifferentImageTypesWhenCallingBlitEnqueueImageAllowedThenCorrectResultIsReturned)1692 TEST(CommandQueue, givenImageWithDifferentImageTypesWhenCallingBlitEnqueueImageAllowedThenCorrectResultIsReturned) {
1693     DebugManagerStateRestore restorer;
1694     DebugManager.flags.EnableBlitterForEnqueueImageOperations.set(1);
1695     MockContext context{};
1696     MockCommandQueue queue(&context, context.getDevice(0), 0, false);
1697 
1698     size_t correctRegion[3] = {10u, 10u, 0};
1699     size_t correctOrigin[3] = {1u, 1u, 0};
1700     MockImageBase image;
1701 
1702     int imageTypes[] = {CL_MEM_OBJECT_IMAGE1D, CL_MEM_OBJECT_IMAGE1D_ARRAY, CL_MEM_OBJECT_IMAGE2D, CL_MEM_OBJECT_IMAGE2D_ARRAY, CL_MEM_OBJECT_IMAGE3D};
1703 
1704     for (auto imageType : imageTypes) {
1705         image.imageDesc.image_type = imageType;
1706         EXPECT_TRUE(queue.blitEnqueueImageAllowed(correctOrigin, correctRegion, image));
1707     }
1708 }
1709 
TEST(CommandQueue,given64KBTileWith3DImageTypeWhenCallingBlitEnqueueImageAllowedThenCorrectResultIsReturned)1710 TEST(CommandQueue, given64KBTileWith3DImageTypeWhenCallingBlitEnqueueImageAllowedThenCorrectResultIsReturned) {
1711     DebugManagerStateRestore restorer;
1712     MockContext context{};
1713     MockCommandQueue queue(&context, context.getDevice(0), 0, false);
1714     const auto &hwInfo = *defaultHwInfo;
1715     const auto &hwInfoConfig = HwInfoConfig::get(hwInfo.platform.eProductFamily);
1716 
1717     size_t correctRegion[3] = {10u, 10u, 0};
1718     size_t correctOrigin[3] = {1u, 1u, 0};
1719     std::array<std::unique_ptr<Image>, 5> images = {
1720         std::unique_ptr<Image>(ImageHelper<Image1dDefaults>::create(&context)),
1721         std::unique_ptr<Image>(ImageHelper<Image1dArrayDefaults>::create(&context)),
1722         std::unique_ptr<Image>(ImageHelper<Image2dDefaults>::create(&context)),
1723         std::unique_ptr<Image>(ImageHelper<Image2dArrayDefaults>::create(&context)),
1724         std::unique_ptr<Image>(ImageHelper<Image3dDefaults>::create(&context))};
1725 
1726     for (auto blitterEnabled : {0, 1}) {
1727         DebugManager.flags.EnableBlitterForEnqueueImageOperations.set(blitterEnabled);
1728         for (auto isTile64 : {0, 1}) {
1729             for (const auto &image : images) {
1730                 auto imageType = image->getImageDesc().image_type;
1731                 auto gfxAllocation = image->getGraphicsAllocation(context.getDevice(0)->getRootDeviceIndex());
1732                 auto mockGmmResourceInfo = reinterpret_cast<MockGmmResourceInfo *>(gfxAllocation->getDefaultGmm()->gmmResourceInfo.get());
1733                 mockGmmResourceInfo->getResourceFlags()->Info.Tile64 = isTile64;
1734 
1735                 if (isTile64 && (imageType == CL_MEM_OBJECT_IMAGE3D)) {
1736                     auto supportExpected = hwInfoConfig->isTile64With3DSurfaceOnBCSSupported(hwInfo) && blitterEnabled;
1737                     EXPECT_EQ(supportExpected, queue.blitEnqueueImageAllowed(correctOrigin, correctRegion, *image));
1738                 } else {
1739                     EXPECT_EQ(blitterEnabled, queue.blitEnqueueImageAllowed(correctOrigin, correctRegion, *image));
1740                 }
1741             }
1742         }
1743     }
1744 }
1745 
TEST(CommandQueue,givenSupportForOperationWhenValidatingSupportThenReturnSuccess)1746 TEST(CommandQueue, givenSupportForOperationWhenValidatingSupportThenReturnSuccess) {
1747     MockCommandQueue queue{};
1748 
1749     queue.queueCapabilities = CL_QUEUE_CAPABILITY_MAP_BUFFER_INTEL;
1750     EXPECT_FALSE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, 0, nullptr, nullptr));
1751 
1752     queue.queueCapabilities |= CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL;
1753     EXPECT_TRUE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, 0, nullptr, nullptr));
1754 }
1755 
TEST(CommandQueue,givenSupportForWaitListAndWaitListPassedWhenValidatingSupportThenReturnSuccess)1756 TEST(CommandQueue, givenSupportForWaitListAndWaitListPassedWhenValidatingSupportThenReturnSuccess) {
1757     MockContext context{};
1758     MockCommandQueue queue{context};
1759 
1760     MockEvent<Event> events[] = {
1761         {&queue, CL_COMMAND_READ_BUFFER, 0, 0},
1762         {&queue, CL_COMMAND_READ_BUFFER, 0, 0},
1763         {&queue, CL_COMMAND_READ_BUFFER, 0, 0},
1764     };
1765     MockEvent<UserEvent> userEvent{&context};
1766     const cl_event waitList[] = {events, events + 1, events + 2, &userEvent};
1767     const cl_uint waitListSize = static_cast<cl_uint>(arrayCount(waitList));
1768 
1769     queue.queueCapabilities = CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL;
1770     EXPECT_TRUE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, 0, nullptr, nullptr));
1771     EXPECT_FALSE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, waitListSize, waitList, nullptr));
1772 
1773     queue.queueCapabilities = CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL |
1774                               CL_QUEUE_CAPABILITY_SINGLE_QUEUE_EVENT_WAIT_LIST_INTEL |
1775                               CL_QUEUE_CAPABILITY_CREATE_SINGLE_QUEUE_EVENTS_INTEL;
1776     EXPECT_TRUE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, 0, nullptr, nullptr));
1777     EXPECT_TRUE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, waitListSize, waitList, nullptr));
1778 }
1779 
TEST(CommandQueue,givenCrossQueueDependencyAndBothQueuesSupportItWhenValidatingSupportThenReturnTrue)1780 TEST(CommandQueue, givenCrossQueueDependencyAndBothQueuesSupportItWhenValidatingSupportThenReturnTrue) {
1781     MockContext context{};
1782     MockCommandQueue queue{context};
1783     MockCommandQueue otherQueue{context};
1784 
1785     MockEvent<Event> events[] = {
1786         {&otherQueue, CL_COMMAND_READ_BUFFER, 0, 0},
1787         {&otherQueue, CL_COMMAND_READ_BUFFER, 0, 0},
1788         {&otherQueue, CL_COMMAND_READ_BUFFER, 0, 0},
1789     };
1790     const cl_event waitList[] = {events, events + 1, events + 2};
1791     const cl_uint waitListSize = static_cast<cl_uint>(arrayCount(waitList));
1792 
1793     queue.queueCapabilities = CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL;
1794     otherQueue.queueCapabilities = CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL;
1795     EXPECT_FALSE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, waitListSize, waitList, nullptr));
1796 
1797     queue.queueCapabilities = CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL | CL_QUEUE_CAPABILITY_CROSS_QUEUE_EVENT_WAIT_LIST_INTEL;
1798     otherQueue.queueCapabilities = CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL;
1799     EXPECT_FALSE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, waitListSize, waitList, nullptr));
1800 
1801     queue.queueCapabilities = CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL;
1802     otherQueue.queueCapabilities = CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL | CL_QUEUE_CAPABILITY_CREATE_CROSS_QUEUE_EVENTS_INTEL;
1803     EXPECT_FALSE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, waitListSize, waitList, nullptr));
1804 
1805     queue.queueCapabilities = CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL | CL_QUEUE_CAPABILITY_CROSS_QUEUE_EVENT_WAIT_LIST_INTEL;
1806     otherQueue.queueCapabilities = CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL | CL_QUEUE_CAPABILITY_CREATE_CROSS_QUEUE_EVENTS_INTEL;
1807     EXPECT_TRUE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, waitListSize, waitList, nullptr));
1808 }
1809 
TEST(CommandQueue,givenUserEventInWaitListWhenValidatingSupportThenReturnTrue)1810 TEST(CommandQueue, givenUserEventInWaitListWhenValidatingSupportThenReturnTrue) {
1811     MockContext context{};
1812     MockCommandQueue queue{context};
1813 
1814     MockEvent<Event> events[] = {
1815         {&queue, CL_COMMAND_READ_BUFFER, 0, 0},
1816         {&queue, CL_COMMAND_READ_BUFFER, 0, 0},
1817         {&queue, CL_COMMAND_READ_BUFFER, 0, 0},
1818     };
1819     MockEvent<UserEvent> userEvent{&context};
1820     const cl_event waitList[] = {events, events + 1, events + 2, &userEvent};
1821     const cl_uint waitListSize = static_cast<cl_uint>(arrayCount(waitList));
1822 
1823     queue.queueCapabilities = CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL |
1824                               CL_QUEUE_CAPABILITY_CREATE_SINGLE_QUEUE_EVENTS_INTEL |
1825                               CL_QUEUE_CAPABILITY_SINGLE_QUEUE_EVENT_WAIT_LIST_INTEL;
1826     EXPECT_TRUE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, waitListSize, waitList, nullptr));
1827 }
1828 
TEST(CommandQueue,givenSupportForOutEventAndOutEventIsPassedWhenValidatingSupportThenReturnSuccess)1829 TEST(CommandQueue, givenSupportForOutEventAndOutEventIsPassedWhenValidatingSupportThenReturnSuccess) {
1830     MockCommandQueue queue{};
1831     cl_event outEvent{};
1832 
1833     queue.queueCapabilities = CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL;
1834     EXPECT_TRUE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, 0, nullptr, nullptr));
1835     EXPECT_FALSE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, 0, nullptr, &outEvent));
1836 
1837     queue.queueCapabilities = CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL | CL_QUEUE_CAPABILITY_CREATE_SINGLE_QUEUE_EVENTS_INTEL;
1838     EXPECT_TRUE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, 0, nullptr, nullptr));
1839     EXPECT_TRUE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, 0, nullptr, &outEvent));
1840 
1841     queue.queueCapabilities = CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL | CL_QUEUE_CAPABILITY_CREATE_CROSS_QUEUE_EVENTS_INTEL;
1842     EXPECT_TRUE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, 0, nullptr, nullptr));
1843     EXPECT_TRUE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, 0, nullptr, &outEvent));
1844 
1845     queue.queueCapabilities = CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL |
1846                               CL_QUEUE_CAPABILITY_CREATE_SINGLE_QUEUE_EVENTS_INTEL |
1847                               CL_QUEUE_CAPABILITY_CREATE_CROSS_QUEUE_EVENTS_INTEL;
1848     EXPECT_TRUE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, 0, nullptr, nullptr));
1849     EXPECT_TRUE(queue.validateCapabilityForOperation(CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL, 0, nullptr, &outEvent));
1850 }
1851 
1852 using KernelExecutionTypesTests = DispatchFlagsTests;
HWTEST_F(KernelExecutionTypesTests,givenConcurrentKernelWhileDoingNonBlockedEnqueueThenCorrectKernelTypeIsSetInCSR)1853 HWTEST_F(KernelExecutionTypesTests, givenConcurrentKernelWhileDoingNonBlockedEnqueueThenCorrectKernelTypeIsSetInCSR) {
1854     using CsrType = MockCsrHw2<FamilyType>;
1855     SetUpImpl<CsrType>();
1856     auto mockCmdQ = std::make_unique<MockCommandQueueHw<FamilyType>>(context.get(), device.get(), nullptr);
1857     MockKernelWithInternals mockKernelWithInternals(*device.get());
1858     auto pKernel = mockKernelWithInternals.mockKernel;
1859 
1860     pKernel->setKernelExecutionType(CL_KERNEL_EXEC_INFO_CONCURRENT_TYPE_INTEL);
1861     size_t gws[3] = {63, 0, 0};
1862 
1863     mockCmdQ->enqueueKernel(pKernel, 1, nullptr, gws, nullptr, 0, nullptr, nullptr);
1864 
1865     auto &mockCsr = device->getUltCommandStreamReceiver<FamilyType>();
1866     EXPECT_EQ(mockCsr.lastKernelExecutionType, KernelExecutionType::Concurrent);
1867 }
1868 
HWTEST_F(KernelExecutionTypesTests,givenKernelWithDifferentExecutionTypeWhileDoingNonBlockedEnqueueThenKernelTypeInCSRIsChanging)1869 HWTEST_F(KernelExecutionTypesTests, givenKernelWithDifferentExecutionTypeWhileDoingNonBlockedEnqueueThenKernelTypeInCSRIsChanging) {
1870     using CsrType = MockCsrHw2<FamilyType>;
1871     SetUpImpl<CsrType>();
1872     auto mockCmdQ = std::make_unique<MockCommandQueueHw<FamilyType>>(context.get(), device.get(), nullptr);
1873     MockKernelWithInternals mockKernelWithInternals(*device.get());
1874     auto pKernel = mockKernelWithInternals.mockKernel;
1875     size_t gws[3] = {63, 0, 0};
1876     auto &mockCsr = device->getUltCommandStreamReceiver<FamilyType>();
1877 
1878     pKernel->setKernelExecutionType(CL_KERNEL_EXEC_INFO_CONCURRENT_TYPE_INTEL);
1879     mockCmdQ->enqueueKernel(pKernel, 1, nullptr, gws, nullptr, 0, nullptr, nullptr);
1880     EXPECT_EQ(mockCsr.lastKernelExecutionType, KernelExecutionType::Concurrent);
1881 
1882     mockCmdQ->enqueueMarkerWithWaitList(0, nullptr, nullptr);
1883     EXPECT_EQ(mockCsr.lastKernelExecutionType, KernelExecutionType::Concurrent);
1884 
1885     pKernel->setKernelExecutionType(CL_KERNEL_EXEC_INFO_DEFAULT_TYPE_INTEL);
1886     mockCmdQ->enqueueKernel(pKernel, 1, nullptr, gws, nullptr, 0, nullptr, nullptr);
1887 
1888     EXPECT_EQ(mockCsr.lastKernelExecutionType, KernelExecutionType::Default);
1889 }
1890 
HWTEST_F(KernelExecutionTypesTests,givenConcurrentKernelWhileDoingBlockedEnqueueThenCorrectKernelTypeIsSetInCSR)1891 HWTEST_F(KernelExecutionTypesTests, givenConcurrentKernelWhileDoingBlockedEnqueueThenCorrectKernelTypeIsSetInCSR) {
1892     using CsrType = MockCsrHw2<FamilyType>;
1893     SetUpImpl<CsrType>();
1894     auto mockCmdQ = std::make_unique<MockCommandQueueHw<FamilyType>>(context.get(), device.get(), nullptr);
1895     MockKernelWithInternals mockKernelWithInternals(*device.get());
1896     auto pKernel = mockKernelWithInternals.mockKernel;
1897 
1898     pKernel->setKernelExecutionType(CL_KERNEL_EXEC_INFO_CONCURRENT_TYPE_INTEL);
1899     UserEvent userEvent;
1900     cl_event waitlist[] = {&userEvent};
1901     size_t gws[3] = {63, 0, 0};
1902 
1903     mockCmdQ->enqueueKernel(pKernel, 1, nullptr, gws, nullptr, 1, waitlist, nullptr);
1904     userEvent.setStatus(CL_COMPLETE);
1905 
1906     auto &mockCsr = device->getUltCommandStreamReceiver<FamilyType>();
1907     EXPECT_EQ(mockCsr.lastKernelExecutionType, KernelExecutionType::Concurrent);
1908     mockCmdQ->isQueueBlocked();
1909 }
1910 
1911 struct CommandQueueOnSpecificEngineTests : ::testing::Test {
fillPropertiesCommandQueueOnSpecificEngineTests1912     static void fillProperties(cl_queue_properties *properties, cl_uint queueFamily, cl_uint queueIndex) {
1913         properties[0] = CL_QUEUE_FAMILY_INTEL;
1914         properties[1] = queueFamily;
1915         properties[2] = CL_QUEUE_INDEX_INTEL;
1916         properties[3] = queueIndex;
1917         properties[4] = 0;
1918     }
1919 
1920     template <typename GfxFamily, int rcsCount, int ccsCount, int bcsCount>
1921     class MockHwHelper : public HwHelperHw<GfxFamily> {
1922       public:
getGpgpuEngineInstances(const HardwareInfo & hwInfo) const1923         const EngineInstancesContainer getGpgpuEngineInstances(const HardwareInfo &hwInfo) const override {
1924             EngineInstancesContainer result{};
1925             for (int i = 0; i < rcsCount; i++) {
1926                 result.push_back({aub_stream::ENGINE_RCS, EngineUsage::Regular});
1927             }
1928             for (int i = 0; i < ccsCount; i++) {
1929                 result.push_back({aub_stream::ENGINE_CCS, EngineUsage::Regular});
1930             }
1931             for (int i = 0; i < bcsCount; i++) {
1932                 result.push_back({aub_stream::ENGINE_BCS, EngineUsage::Regular});
1933             }
1934 
1935             return result;
1936         }
1937 
getEngineGroupType(aub_stream::EngineType engineType,EngineUsage engineUsage,const HardwareInfo & hwInfo) const1938         EngineGroupType getEngineGroupType(aub_stream::EngineType engineType, EngineUsage engineUsage, const HardwareInfo &hwInfo) const override {
1939             switch (engineType) {
1940             case aub_stream::ENGINE_RCS:
1941                 return EngineGroupType::RenderCompute;
1942             case aub_stream::ENGINE_CCS:
1943             case aub_stream::ENGINE_CCS1:
1944             case aub_stream::ENGINE_CCS2:
1945             case aub_stream::ENGINE_CCS3:
1946                 return EngineGroupType::Compute;
1947             case aub_stream::ENGINE_BCS:
1948                 return EngineGroupType::Copy;
1949             default:
1950                 UNRECOVERABLE_IF(true);
1951             }
1952         }
1953     };
1954 
1955     template <typename GfxFamily, typename HwHelperType>
overrideHwHelperCommandQueueOnSpecificEngineTests1956     auto overrideHwHelper() {
1957         return RAIIHwHelperFactory<HwHelperType>{::defaultHwInfo->platform.eRenderCoreFamily};
1958     }
1959 };
1960 
HWTEST_F(CommandQueueOnSpecificEngineTests,givenMultipleFamiliesWhenCreatingQueueOnSpecificEngineThenUseCorrectEngine)1961 HWTEST_F(CommandQueueOnSpecificEngineTests, givenMultipleFamiliesWhenCreatingQueueOnSpecificEngineThenUseCorrectEngine) {
1962     auto raiiHwHelper = overrideHwHelper<FamilyType, MockHwHelper<FamilyType, 0, 1, 1>>();
1963     HardwareInfo hwInfo = *defaultHwInfo;
1964     hwInfo.capabilityTable.blitterOperationsSupported = true;
1965     MockDevice *device = MockDevice::createWithNewExecutionEnvironment<MockDevice>(&hwInfo, 0);
1966     MockClDevice clDevice{device};
1967     MockContext context{&clDevice};
1968     cl_command_queue_properties properties[5] = {};
1969 
1970     fillProperties(properties, 0, 0);
1971     EngineControl &engineCcs = context.getDevice(0)->getEngine(aub_stream::ENGINE_CCS, EngineUsage::Regular);
1972     MockCommandQueue queueRcs(&context, context.getDevice(0), properties, false);
1973     EXPECT_EQ(&engineCcs, &queueRcs.getGpgpuEngine());
1974     EXPECT_FALSE(queueRcs.isCopyOnly);
1975     EXPECT_TRUE(queueRcs.isQueueFamilySelected());
1976     EXPECT_EQ(properties[1], queueRcs.getQueueFamilyIndex());
1977     EXPECT_EQ(properties[3], queueRcs.getQueueIndexWithinFamily());
1978 
1979     fillProperties(properties, 1, 0);
1980     EngineControl &engineBcs = context.getDevice(0)->getEngine(aub_stream::ENGINE_BCS, EngineUsage::Regular);
1981     MockCommandQueue queueBcs(&context, context.getDevice(0), properties, false);
1982     EXPECT_EQ(engineBcs.commandStreamReceiver, queueBcs.getBcsCommandStreamReceiver(aub_stream::ENGINE_BCS));
1983     EXPECT_TRUE(queueBcs.isCopyOnly);
1984     EXPECT_TRUE(queueBcs.isQueueFamilySelected());
1985     EXPECT_EQ(properties[1], queueBcs.getQueueFamilyIndex());
1986     EXPECT_EQ(properties[3], queueBcs.getQueueIndexWithinFamily());
1987     EXPECT_NE(nullptr, queueBcs.getTimestampPacketContainer());
1988 }
1989 
HWTEST_F(CommandQueueOnSpecificEngineTests,givenRootDeviceAndMultipleFamiliesWhenCreatingQueueOnSpecificEngineThenUseDefaultEngine)1990 HWTEST_F(CommandQueueOnSpecificEngineTests, givenRootDeviceAndMultipleFamiliesWhenCreatingQueueOnSpecificEngineThenUseDefaultEngine) {
1991     VariableBackup<HardwareInfo> backupHwInfo(defaultHwInfo.get());
1992     defaultHwInfo->capabilityTable.blitterOperationsSupported = true;
1993     auto raiiHwHelper = overrideHwHelper<FamilyType, MockHwHelper<FamilyType, 0, 1, 1>>();
1994     UltClDeviceFactory deviceFactory{1, 2};
1995     MockContext context{deviceFactory.rootDevices[0]};
1996     cl_command_queue_properties properties[5] = {};
1997 
1998     fillProperties(properties, 0, 0);
1999     EngineControl &defaultEngine = context.getDevice(0)->getDefaultEngine();
2000     MockCommandQueue defaultQueue(&context, context.getDevice(0), properties, false);
2001     EXPECT_EQ(&defaultEngine, &defaultQueue.getGpgpuEngine());
2002     EXPECT_FALSE(defaultQueue.isCopyOnly);
2003     EXPECT_TRUE(defaultQueue.isQueueFamilySelected());
2004     EXPECT_EQ(properties[1], defaultQueue.getQueueFamilyIndex());
2005     EXPECT_EQ(properties[3], defaultQueue.getQueueIndexWithinFamily());
2006 }
2007 
HWTEST_F(CommandQueueOnSpecificEngineTests,givenSubDeviceAndMultipleFamiliesWhenCreatingQueueOnSpecificEngineThenUseDefaultEngine)2008 HWTEST_F(CommandQueueOnSpecificEngineTests, givenSubDeviceAndMultipleFamiliesWhenCreatingQueueOnSpecificEngineThenUseDefaultEngine) {
2009     auto raiiHwHelper = overrideHwHelper<FamilyType, MockHwHelper<FamilyType, 0, 1, 1>>();
2010 
2011     VariableBackup<HardwareInfo> backupHwInfo(defaultHwInfo.get());
2012     defaultHwInfo->capabilityTable.blitterOperationsSupported = true;
2013     UltClDeviceFactory deviceFactory{1, 2};
2014     MockContext context{deviceFactory.subDevices[0]};
2015     cl_command_queue_properties properties[5] = {};
2016 
2017     fillProperties(properties, 0, 0);
2018     EngineControl &engineCcs = context.getDevice(0)->getEngine(aub_stream::ENGINE_CCS, EngineUsage::Regular);
2019     MockCommandQueue queueRcs(&context, context.getDevice(0), properties, false);
2020     EXPECT_EQ(&engineCcs, &queueRcs.getGpgpuEngine());
2021     EXPECT_FALSE(queueRcs.isCopyOnly);
2022     EXPECT_TRUE(queueRcs.isQueueFamilySelected());
2023     EXPECT_EQ(properties[1], queueRcs.getQueueFamilyIndex());
2024     EXPECT_EQ(properties[3], queueRcs.getQueueIndexWithinFamily());
2025 
2026     fillProperties(properties, 1, 0);
2027     EngineControl &engineBcs = context.getDevice(0)->getEngine(aub_stream::ENGINE_BCS, EngineUsage::Regular);
2028     MockCommandQueue queueBcs(&context, context.getDevice(0), properties, false);
2029     EXPECT_EQ(engineBcs.commandStreamReceiver, queueBcs.getBcsCommandStreamReceiver(aub_stream::ENGINE_BCS));
2030     EXPECT_TRUE(queueBcs.isCopyOnly);
2031     EXPECT_NE(nullptr, queueBcs.getTimestampPacketContainer());
2032     EXPECT_TRUE(queueBcs.isQueueFamilySelected());
2033     EXPECT_EQ(properties[1], queueBcs.getQueueFamilyIndex());
2034     EXPECT_EQ(properties[3], queueBcs.getQueueIndexWithinFamily());
2035 }
2036 
HWTEST_F(CommandQueueOnSpecificEngineTests,givenBcsFamilySelectedWhenCreatingQueueOnSpecificEngineThenInitializeBcsProperly)2037 HWTEST_F(CommandQueueOnSpecificEngineTests, givenBcsFamilySelectedWhenCreatingQueueOnSpecificEngineThenInitializeBcsProperly) {
2038     auto raiiHwHelper = overrideHwHelper<FamilyType, MockHwHelper<FamilyType, 0, 0, 1>>();
2039 
2040     VariableBackup<HardwareInfo> backupHwInfo(defaultHwInfo.get());
2041     defaultHwInfo->capabilityTable.blitterOperationsSupported = true;
2042     MockContext context{};
2043     cl_command_queue_properties properties[5] = {};
2044 
2045     fillProperties(properties, 0, 0);
2046     EngineControl &engineBcs = context.getDevice(0)->getEngine(aub_stream::ENGINE_BCS, EngineUsage::Regular);
2047     MockCommandQueue queueBcs(&context, context.getDevice(0), properties, false);
2048     EXPECT_EQ(engineBcs.commandStreamReceiver, queueBcs.getBcsCommandStreamReceiver(aub_stream::ENGINE_BCS));
2049     EXPECT_TRUE(queueBcs.isCopyOnly);
2050     EXPECT_NE(nullptr, queueBcs.getTimestampPacketContainer());
2051     EXPECT_TRUE(queueBcs.isQueueFamilySelected());
2052     EXPECT_EQ(properties[1], queueBcs.getQueueFamilyIndex());
2053     EXPECT_EQ(properties[3], queueBcs.getQueueIndexWithinFamily());
2054 }
2055 
HWTEST_F(CommandQueueOnSpecificEngineTests,givenNotInitializedRcsOsContextWhenCreatingQueueThenInitializeOsContext)2056 HWTEST_F(CommandQueueOnSpecificEngineTests, givenNotInitializedRcsOsContextWhenCreatingQueueThenInitializeOsContext) {
2057     VariableBackup<HardwareInfo> backupHwInfo(defaultHwInfo.get());
2058     defaultHwInfo->capabilityTable.blitterOperationsSupported = true;
2059     DebugManagerStateRestore restore{};
2060     DebugManager.flags.NodeOrdinal.set(static_cast<int32_t>(aub_stream::EngineType::ENGINE_RCS));
2061     DebugManager.flags.DeferOsContextInitialization.set(1);
2062 
2063     auto raiiHwHelper = overrideHwHelper<FamilyType, MockHwHelper<FamilyType, 1, 1, 1>>();
2064     MockContext context{};
2065     cl_command_queue_properties properties[5] = {};
2066 
2067     OsContext &osContext = *context.getDevice(0)->getEngine(aub_stream::ENGINE_CCS, EngineUsage::Regular).osContext;
2068     EXPECT_FALSE(osContext.isInitialized());
2069 
2070     const auto ccsFamilyIndex = static_cast<cl_uint>(context.getDevice(0)->getDevice().getEngineGroupIndexFromEngineGroupType(EngineGroupType::Compute));
2071     fillProperties(properties, ccsFamilyIndex, 0);
2072     MockCommandQueueHw<FamilyType> queue(&context, context.getDevice(0), properties);
2073     ASSERT_EQ(&osContext, queue.gpgpuEngine->osContext);
2074     EXPECT_TRUE(osContext.isInitialized());
2075 }
2076 
HWTEST_F(CommandQueueOnSpecificEngineTests,givenNotInitializedCcsOsContextWhenCreatingQueueThenInitializeOsContext)2077 HWTEST_F(CommandQueueOnSpecificEngineTests, givenNotInitializedCcsOsContextWhenCreatingQueueThenInitializeOsContext) {
2078     VariableBackup<HardwareInfo> backupHwInfo(defaultHwInfo.get());
2079     defaultHwInfo->capabilityTable.blitterOperationsSupported = true;
2080     DebugManagerStateRestore restore{};
2081     DebugManager.flags.NodeOrdinal.set(static_cast<int32_t>(aub_stream::EngineType::ENGINE_CCS));
2082     DebugManager.flags.DeferOsContextInitialization.set(1);
2083 
2084     auto raiiHwHelper = overrideHwHelper<FamilyType, MockHwHelper<FamilyType, 1, 1, 1>>();
2085     MockContext context{};
2086     cl_command_queue_properties properties[5] = {};
2087 
2088     OsContext &osContext = *context.getDevice(0)->getEngine(aub_stream::ENGINE_RCS, EngineUsage::Regular).osContext;
2089     EXPECT_FALSE(osContext.isInitialized());
2090 
2091     const auto rcsFamilyIndex = static_cast<cl_uint>(context.getDevice(0)->getDevice().getEngineGroupIndexFromEngineGroupType(EngineGroupType::RenderCompute));
2092     fillProperties(properties, rcsFamilyIndex, 0);
2093     MockCommandQueueHw<FamilyType> queue(&context, context.getDevice(0), properties);
2094     ASSERT_EQ(&osContext, queue.gpgpuEngine->osContext);
2095     EXPECT_TRUE(osContext.isInitialized());
2096 }
2097 
TEST_F(MultiTileFixture,givenSubDeviceWhenQueueIsCreatedThenItContainsProperDevice)2098 TEST_F(MultiTileFixture, givenSubDeviceWhenQueueIsCreatedThenItContainsProperDevice) {
2099     VariableBackup<HardwareInfo> backupHwInfo(defaultHwInfo.get());
2100     defaultHwInfo->capabilityTable.blitterOperationsSupported = true;
2101     auto tile0 = platform()->getClDevice(0)->getSubDevice(0);
2102 
2103     const cl_device_id deviceId = tile0;
2104     auto returnStatus = CL_SUCCESS;
2105     auto context = clCreateContext(nullptr, 1, &deviceId, nullptr, nullptr, &returnStatus);
2106     EXPECT_EQ(CL_SUCCESS, returnStatus);
2107     EXPECT_NE(nullptr, context);
2108 
2109     auto commandQueue = clCreateCommandQueueWithProperties(context, tile0, nullptr, &returnStatus);
2110     EXPECT_EQ(CL_SUCCESS, returnStatus);
2111     EXPECT_NE(nullptr, commandQueue);
2112 
2113     auto neoQueue = castToObject<CommandQueue>(commandQueue);
2114     EXPECT_EQ(&tile0->getDevice(), &neoQueue->getDevice());
2115 
2116     clReleaseCommandQueue(commandQueue);
2117     clReleaseContext(context);
2118 }
2119 
TEST_F(MultiTileFixture,givenTile1WhenQueueIsCreatedThenItContainsTile1Device)2120 TEST_F(MultiTileFixture, givenTile1WhenQueueIsCreatedThenItContainsTile1Device) {
2121     auto tile1 = platform()->getClDevice(0)->getSubDevice(1);
2122 
2123     const cl_device_id deviceId = tile1;
2124     auto returnStatus = CL_SUCCESS;
2125     auto context = clCreateContext(nullptr, 1, &deviceId, nullptr, nullptr, &returnStatus);
2126     EXPECT_EQ(CL_SUCCESS, returnStatus);
2127     EXPECT_NE(nullptr, context);
2128 
2129     auto commandQueue = clCreateCommandQueueWithProperties(context, tile1, nullptr, &returnStatus);
2130     EXPECT_EQ(CL_SUCCESS, returnStatus);
2131     EXPECT_NE(nullptr, commandQueue);
2132 
2133     auto neoQueue = castToObject<CommandQueue>(commandQueue);
2134     EXPECT_EQ(&tile1->getDevice(), &neoQueue->getDevice());
2135 
2136     clReleaseCommandQueue(commandQueue);
2137     clReleaseContext(context);
2138 }
2139 
2140 struct CopyOnlyQueueTests : ::testing::Test {
SetUpCopyOnlyQueueTests2141     void SetUp() override {
2142         typeUsageRcs.first = EngineHelpers::remapEngineTypeToHwSpecific(typeUsageRcs.first, *defaultHwInfo);
2143 
2144         auto device = MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get());
2145         auto copyEngineGroup = std::find_if(device->regularEngineGroups.begin(), device->regularEngineGroups.end(), [](const auto &engineGroup) {
2146             return engineGroup.engineGroupType == EngineGroupType::Copy;
2147         });
2148         if (copyEngineGroup == device->regularEngineGroups.end()) {
2149             GTEST_SKIP();
2150         }
2151         device->regularEngineGroups.clear();
2152         device->allEngines.clear();
2153 
2154         device->createEngine(0, typeUsageRcs);
2155         device->createEngine(1, typeUsageBcs);
2156         bcsEngine = &device->getAllEngines().back();
2157 
2158         clDevice = std::make_unique<MockClDevice>(device);
2159 
2160         context = std::make_unique<MockContext>(clDevice.get());
2161 
2162         properties[1] = device->getEngineGroupIndexFromEngineGroupType(EngineGroupType::Copy);
2163     }
2164 
2165     EngineTypeUsage typeUsageBcs = EngineTypeUsage{aub_stream::EngineType::ENGINE_BCS, EngineUsage::Regular};
2166     EngineTypeUsage typeUsageRcs = EngineTypeUsage{aub_stream::EngineType::ENGINE_RCS, EngineUsage::Regular};
2167 
2168     std::unique_ptr<MockClDevice> clDevice{};
2169     std::unique_ptr<MockContext> context{};
2170     std::unique_ptr<MockCommandQueue> queue{};
2171     const EngineControl *bcsEngine = nullptr;
2172 
2173     cl_queue_properties properties[5] = {CL_QUEUE_FAMILY_INTEL, 0, CL_QUEUE_INDEX_INTEL, 0, 0};
2174 };
2175 
TEST_F(CopyOnlyQueueTests,givenBcsSelectedWhenCreatingCommandQueueThenItIsCopyOnly)2176 TEST_F(CopyOnlyQueueTests, givenBcsSelectedWhenCreatingCommandQueueThenItIsCopyOnly) {
2177     MockCommandQueue queue{context.get(), clDevice.get(), properties, false};
2178     EXPECT_EQ(bcsEngine->commandStreamReceiver, queue.getBcsCommandStreamReceiver(aub_stream::EngineType::ENGINE_BCS));
2179     EXPECT_EQ(1u, queue.countBcsEngines());
2180     EXPECT_NE(nullptr, queue.timestampPacketContainer);
2181     EXPECT_TRUE(queue.isCopyOnly);
2182 }
2183 
HWTEST_F(CopyOnlyQueueTests,givenBcsSelectedWhenEnqueuingCopyThenBcsIsUsed)2184 HWTEST_F(CopyOnlyQueueTests, givenBcsSelectedWhenEnqueuingCopyThenBcsIsUsed) {
2185     auto srcBuffer = std::unique_ptr<Buffer>{BufferHelper<>::create(context.get())};
2186     auto dstBuffer = std::unique_ptr<Buffer>{BufferHelper<>::create(context.get())};
2187     MockCommandQueueHw<FamilyType> queue{context.get(), clDevice.get(), properties};
2188     auto commandStream = &bcsEngine->commandStreamReceiver->getCS(1024);
2189 
2190     auto usedCommandStream = commandStream->getUsed();
2191     cl_int retVal = queue.enqueueCopyBuffer(
2192         srcBuffer.get(),
2193         dstBuffer.get(),
2194         0,
2195         0,
2196         1,
2197         0,
2198         nullptr,
2199         nullptr);
2200     ASSERT_EQ(CL_SUCCESS, retVal);
2201     EXPECT_NE(usedCommandStream, commandStream->getUsed());
2202 }
2203 
HWTEST_F(CopyOnlyQueueTests,givenBlitterEnabledWhenCreatingBcsCommandQueueThenReturnSuccess)2204 HWTEST_F(CopyOnlyQueueTests, givenBlitterEnabledWhenCreatingBcsCommandQueueThenReturnSuccess) {
2205     DebugManagerStateRestore restore{};
2206     DebugManager.flags.EnableBlitterOperationsSupport.set(1);
2207 
2208     cl_int retVal{};
2209     auto commandQueue = clCreateCommandQueueWithProperties(context.get(), clDevice.get(), properties, &retVal);
2210     EXPECT_EQ(CL_SUCCESS, retVal);
2211     EXPECT_NE(nullptr, commandQueue);
2212     EXPECT_EQ(CL_SUCCESS, clReleaseCommandQueue(commandQueue));
2213 }
2214 
2215 using MultiEngineQueueHwTests = ::testing::Test;
2216 
HWCMDTEST_F(IGFX_XE_HP_CORE,MultiEngineQueueHwTests,givenQueueFamilyPropertyWhenQueueIsCreatedThenSelectValidEngine)2217 HWCMDTEST_F(IGFX_XE_HP_CORE, MultiEngineQueueHwTests, givenQueueFamilyPropertyWhenQueueIsCreatedThenSelectValidEngine) {
2218     initPlatform();
2219     HardwareInfo localHwInfo = *defaultHwInfo;
2220 
2221     localHwInfo.featureTable.flags.ftrCCSNode = true;
2222 
2223     auto device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(&localHwInfo));
2224     MockContext context(device.get());
2225     context.contextType = ContextType::CONTEXT_TYPE_UNRESTRICTIVE;
2226 
2227     bool ccsFound = false;
2228     for (auto &engine : device->allEngines) {
2229         if (engine.osContext->getEngineType() == aub_stream::EngineType::ENGINE_CCS) {
2230             ccsFound = true;
2231             break;
2232         }
2233     }
2234 
2235     struct CommandQueueTestValues {
2236         CommandQueueTestValues() = delete;
2237         CommandQueueTestValues(cl_queue_properties engineFamily, cl_queue_properties engineIndex, aub_stream::EngineType expectedEngine)
2238             : expectedEngine(expectedEngine) {
2239             properties[1] = engineFamily;
2240             properties[3] = engineIndex;
2241         };
2242 
2243         cl_command_queue clCommandQueue = nullptr;
2244         CommandQueue *commandQueueObj = nullptr;
2245         cl_queue_properties properties[5] = {CL_QUEUE_FAMILY_INTEL, 0, CL_QUEUE_INDEX_INTEL, 0, 0};
2246         aub_stream::EngineType expectedEngine;
2247     };
2248     auto addTestValueIfAvailable = [&](std::vector<CommandQueueTestValues> &vec, EngineGroupType engineGroup, cl_queue_properties queueIndex, aub_stream::EngineType engineType, bool csEnabled) {
2249         if (csEnabled) {
2250             const auto familyIndex = device->getDevice().getEngineGroupIndexFromEngineGroupType(engineGroup);
2251             vec.push_back(CommandQueueTestValues(static_cast<cl_queue_properties>(familyIndex), queueIndex, engineType));
2252         }
2253     };
2254     auto retVal = CL_SUCCESS;
2255     const auto &ccsInstances = localHwInfo.gtSystemInfo.CCSInfo.Instances.Bits;
2256     std::vector<CommandQueueTestValues> commandQueueTestValues;
2257     addTestValueIfAvailable(commandQueueTestValues, EngineGroupType::RenderCompute, 0, EngineHelpers::remapEngineTypeToHwSpecific(aub_stream::EngineType::ENGINE_RCS, device->getHardwareInfo()), true);
2258     addTestValueIfAvailable(commandQueueTestValues, EngineGroupType::Compute, 0, aub_stream::ENGINE_CCS, ccsFound);
2259     addTestValueIfAvailable(commandQueueTestValues, EngineGroupType::Compute, 1, aub_stream::ENGINE_CCS1, ccsInstances.CCS1Enabled);
2260     addTestValueIfAvailable(commandQueueTestValues, EngineGroupType::Compute, 2, aub_stream::ENGINE_CCS2, ccsInstances.CCS2Enabled);
2261     addTestValueIfAvailable(commandQueueTestValues, EngineGroupType::Compute, 3, aub_stream::ENGINE_CCS3, ccsInstances.CCS3Enabled);
2262 
2263     for (auto &commandQueueTestValue : commandQueueTestValues) {
2264         if (commandQueueTestValue.properties[1] >= device->getHardwareInfo().gtSystemInfo.CCSInfo.NumberOfCCSEnabled) {
2265             continue;
2266         }
2267         commandQueueTestValue.clCommandQueue = clCreateCommandQueueWithProperties(&context, device.get(),
2268                                                                                   &commandQueueTestValue.properties[0], &retVal);
2269         EXPECT_EQ(CL_SUCCESS, retVal);
2270         commandQueueTestValue.commandQueueObj = castToObject<CommandQueue>(commandQueueTestValue.clCommandQueue);
2271 
2272         auto &cmdQueueEngine = commandQueueTestValue.commandQueueObj->getGpgpuCommandStreamReceiver().getOsContext().getEngineType();
2273         EXPECT_EQ(commandQueueTestValue.expectedEngine, cmdQueueEngine);
2274 
2275         clReleaseCommandQueue(commandQueueTestValue.commandQueueObj);
2276     }
2277 }
2278 
TEST_F(MultiTileFixture,givenDefaultContextWithRootDeviceWhenQueueIsCreatedThenQueueIsMultiEngine)2279 TEST_F(MultiTileFixture, givenDefaultContextWithRootDeviceWhenQueueIsCreatedThenQueueIsMultiEngine) {
2280     auto rootDevice = platform()->getClDevice(0);
2281     MockContext context(rootDevice);
2282     context.contextType = ContextType::CONTEXT_TYPE_DEFAULT;
2283 
2284     auto rootCsr = rootDevice->getDefaultEngine().commandStreamReceiver;
2285 
2286     MockCommandQueue queue(&context, rootDevice, nullptr, false);
2287     ASSERT_NE(nullptr, queue.gpgpuEngine);
2288     EXPECT_EQ(rootCsr->isMultiOsContextCapable(), queue.getGpgpuCommandStreamReceiver().isMultiOsContextCapable());
2289     EXPECT_EQ(rootCsr, queue.gpgpuEngine->commandStreamReceiver);
2290 }
2291 
TEST_F(MultiTileFixture,givenDefaultContextWithSubdeviceWhenQueueIsCreatedThenQueueIsNotMultiEngine)2292 TEST_F(MultiTileFixture, givenDefaultContextWithSubdeviceWhenQueueIsCreatedThenQueueIsNotMultiEngine) {
2293     auto subdevice = platform()->getClDevice(0)->getSubDevice(0);
2294     MockContext context(subdevice);
2295     context.contextType = ContextType::CONTEXT_TYPE_DEFAULT;
2296 
2297     MockCommandQueue queue(&context, subdevice, nullptr, false);
2298     ASSERT_NE(nullptr, queue.gpgpuEngine);
2299     EXPECT_FALSE(queue.getGpgpuCommandStreamReceiver().isMultiOsContextCapable());
2300 }
2301 
TEST_F(MultiTileFixture,givenUnrestrictiveContextWithRootDeviceWhenQueueIsCreatedThenQueueIsMultiEngine)2302 TEST_F(MultiTileFixture, givenUnrestrictiveContextWithRootDeviceWhenQueueIsCreatedThenQueueIsMultiEngine) {
2303     auto rootDevice = platform()->getClDevice(0);
2304     MockContext context(rootDevice);
2305     context.contextType = ContextType::CONTEXT_TYPE_UNRESTRICTIVE;
2306 
2307     auto rootCsr = rootDevice->getDefaultEngine().commandStreamReceiver;
2308 
2309     MockCommandQueue queue(&context, rootDevice, nullptr, false);
2310     ASSERT_NE(nullptr, queue.gpgpuEngine);
2311     EXPECT_EQ(rootCsr->isMultiOsContextCapable(), queue.getGpgpuCommandStreamReceiver().isMultiOsContextCapable());
2312     EXPECT_EQ(rootCsr, queue.gpgpuEngine->commandStreamReceiver);
2313 }
2314 
TEST_F(MultiTileFixture,givenNotDefaultContextWithRootDeviceAndTileIdMaskWhenQueueIsCreatedThenQueueIsMultiEngine)2315 TEST_F(MultiTileFixture, givenNotDefaultContextWithRootDeviceAndTileIdMaskWhenQueueIsCreatedThenQueueIsMultiEngine) {
2316     auto rootClDevice = platform()->getClDevice(0);
2317     auto rootDevice = static_cast<RootDevice *>(&rootClDevice->getDevice());
2318     MockContext context(rootClDevice);
2319     context.contextType = ContextType::CONTEXT_TYPE_UNRESTRICTIVE;
2320 
2321     auto rootCsr = rootDevice->getDefaultEngine().commandStreamReceiver;
2322 
2323     MockCommandQueue queue(&context, rootClDevice, nullptr, false);
2324     ASSERT_NE(nullptr, queue.gpgpuEngine);
2325     EXPECT_EQ(rootCsr->isMultiOsContextCapable(), queue.getGpgpuCommandStreamReceiver().isMultiOsContextCapable());
2326     EXPECT_EQ(rootCsr, queue.gpgpuEngine->commandStreamReceiver);
2327 }
2328