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