1 /*
2  * Copyright (C) 2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #include "shared/source/command_stream/aub_command_stream_receiver_hw.h"
9 #include "shared/source/command_stream/command_stream_receiver_hw.h"
10 #include "shared/test/common/helpers/dispatch_flags_helper.h"
11 #include "shared/test/common/test_macros/test.h"
12 
13 #include "opencl/test/unit_test/aub_tests/fixtures/aub_fixture.h"
14 
15 #include <cstdint>
16 
17 using namespace NEO;
18 
19 struct MiAtomicAubFixture : public AUBFixture {
SetUpMiAtomicAubFixture20     void SetUp() override {
21         AUBFixture::SetUp(nullptr);
22         auto memoryManager = this->device->getMemoryManager();
23 
24         AllocationProperties commandBufferProperties = {device->getRootDeviceIndex(),
25                                                         true,
26                                                         MemoryConstants::pageSize,
27                                                         GraphicsAllocation::AllocationType::COMMAND_BUFFER,
28                                                         false,
29                                                         device->getDeviceBitfield()};
30         streamAllocation = memoryManager->allocateGraphicsMemoryWithProperties(commandBufferProperties);
31         ASSERT_NE(nullptr, streamAllocation);
32 
33         AllocationProperties deviceBufferProperties = {device->getRootDeviceIndex(),
34                                                        true,
35                                                        MemoryConstants::pageSize,
36                                                        GraphicsAllocation::AllocationType::BUFFER,
37                                                        false,
38                                                        device->getDeviceBitfield()};
39         deviceSurface = memoryManager->allocateGraphicsMemoryWithProperties(deviceBufferProperties);
40         ASSERT_NE(nullptr, deviceSurface);
41 
42         AllocationProperties systemBufferProperties = {device->getRootDeviceIndex(),
43                                                        true,
44                                                        MemoryConstants::pageSize,
45                                                        GraphicsAllocation::AllocationType::SVM_CPU,
46                                                        false,
47                                                        device->getDeviceBitfield()};
48         systemSurface = memoryManager->allocateGraphicsMemoryWithProperties(systemBufferProperties);
49         ASSERT_NE(nullptr, systemSurface);
50 
51         taskStream.replaceGraphicsAllocation(streamAllocation);
52         taskStream.replaceBuffer(streamAllocation->getUnderlyingBuffer(),
53                                  streamAllocation->getUnderlyingBufferSize());
54     }
55 
TearDownMiAtomicAubFixture56     void TearDown() override {
57         auto memoryManager = this->device->getMemoryManager();
58         memoryManager->freeGraphicsMemory(streamAllocation);
59         memoryManager->freeGraphicsMemory(deviceSurface);
60         memoryManager->freeGraphicsMemory(systemSurface);
61 
62         AUBFixture::TearDown();
63     }
64 
flushStreamMiAtomicAubFixture65     void flushStream() {
66         DispatchFlags dispatchFlags = DispatchFlagsHelper::createDefaultDispatchFlags();
67         dispatchFlags.guardCommandBufferWithPipeControl = true;
68 
69         csr->makeResident(*deviceSurface);
70         csr->makeResident(*systemSurface);
71         csr->flushTask(taskStream, 0,
72                        csr->getIndirectHeap(IndirectHeap::DYNAMIC_STATE, 0u),
73                        csr->getIndirectHeap(IndirectHeap::INDIRECT_OBJECT, 0u),
74                        csr->getIndirectHeap(IndirectHeap::SURFACE_STATE, 0u),
75                        0u, dispatchFlags, device->getDevice());
76 
77         csr->flushBatchedSubmissions();
78     }
79 
80     LinearStream taskStream;
81     GraphicsAllocation *streamAllocation = nullptr;
82     GraphicsAllocation *deviceSurface = nullptr;
83     GraphicsAllocation *systemSurface = nullptr;
84 };
85 
86 using MiAtomicAubTest = Test<MiAtomicAubFixture>;
87 
HWTEST_F(MiAtomicAubTest,WhenDispatchingAtomicMoveOperationThenExpectCorrectEndValues)88 HWTEST_F(MiAtomicAubTest, WhenDispatchingAtomicMoveOperationThenExpectCorrectEndValues) {
89     using MI_ATOMIC = typename FamilyType::MI_ATOMIC;
90     auto atomicAddress = deviceSurface->getGpuAddress();
91 
92     auto expectedGpuAddressDwordOp1 = atomicAddress;
93     auto expectedGpuAddressDwordOp2 = expectedGpuAddressDwordOp1 + sizeof(uint32_t);
94     auto expectedGpuAddressQwordOp3 = expectedGpuAddressDwordOp2 + sizeof(uint32_t);
95 
96     uint32_t operation1dword0 = 0x10;
97     EncodeAtomic<FamilyType>::programMiAtomic(taskStream, expectedGpuAddressDwordOp1,
98                                               MI_ATOMIC::ATOMIC_OPCODES::ATOMIC_4B_MOVE,
99                                               MI_ATOMIC::DATA_SIZE::DATA_SIZE_DWORD,
100                                               0, 0, operation1dword0, 0u);
101 
102     uint32_t operation2dword0 = 0x22;
103     EncodeAtomic<FamilyType>::programMiAtomic(taskStream, expectedGpuAddressDwordOp2,
104                                               MI_ATOMIC::ATOMIC_OPCODES::ATOMIC_4B_MOVE,
105                                               MI_ATOMIC::DATA_SIZE::DATA_SIZE_DWORD,
106                                               0, 0, operation2dword0, 0u);
107 
108     uint32_t operation3dword0 = 0xF0;
109     uint32_t operation3dword1 = 0x1F;
110     EncodeAtomic<FamilyType>::programMiAtomic(taskStream, expectedGpuAddressQwordOp3,
111                                               MI_ATOMIC::ATOMIC_OPCODES::ATOMIC_8B_MOVE,
112                                               MI_ATOMIC::DATA_SIZE::DATA_SIZE_QWORD,
113                                               0, 0, operation3dword0, operation3dword1);
114     uint64_t operation3qword = (static_cast<uint64_t>(operation3dword1) << 32) | operation3dword0;
115 
116     flushStream();
117 
118     expectMemory<FamilyType>(reinterpret_cast<void *>(expectedGpuAddressDwordOp1), &operation1dword0, sizeof(operation1dword0));
119     expectMemory<FamilyType>(reinterpret_cast<void *>(expectedGpuAddressDwordOp2), &operation2dword0, sizeof(operation2dword0));
120     expectMemory<FamilyType>(reinterpret_cast<void *>(expectedGpuAddressQwordOp3), &operation3qword, sizeof(operation3qword));
121 }
122 
HWTEST_F(MiAtomicAubTest,GivenSystemMemoryWhenDispatchingAtomicMove4BytesOperationThenExpectCorrectEndValues)123 HWTEST_F(MiAtomicAubTest, GivenSystemMemoryWhenDispatchingAtomicMove4BytesOperationThenExpectCorrectEndValues) {
124     using MI_ATOMIC = typename FamilyType::MI_ATOMIC;
125 
126     auto atomicAddress = systemSurface->getGpuAddress();
127 
128     auto expectedGpuAddressDwordOp1 = atomicAddress;
129     auto expectedGpuAddressDwordOp2 = expectedGpuAddressDwordOp1 + sizeof(uint32_t);
130 
131     uint32_t operation1dword0 = 0x15;
132     EncodeAtomic<FamilyType>::programMiAtomic(taskStream, expectedGpuAddressDwordOp1,
133                                               MI_ATOMIC::ATOMIC_OPCODES::ATOMIC_4B_MOVE,
134                                               MI_ATOMIC::DATA_SIZE::DATA_SIZE_DWORD,
135                                               0, 0, operation1dword0, 0u);
136 
137     uint32_t operation2dword0 = 0xFF;
138     EncodeAtomic<FamilyType>::programMiAtomic(taskStream, expectedGpuAddressDwordOp2,
139                                               MI_ATOMIC::ATOMIC_OPCODES::ATOMIC_4B_MOVE,
140                                               MI_ATOMIC::DATA_SIZE::DATA_SIZE_DWORD,
141                                               0, 0, operation2dword0, 0u);
142 
143     flushStream();
144 
145     expectMemory<FamilyType>(reinterpret_cast<void *>(expectedGpuAddressDwordOp1), &operation1dword0, sizeof(operation1dword0));
146     expectMemory<FamilyType>(reinterpret_cast<void *>(expectedGpuAddressDwordOp2), &operation2dword0, sizeof(operation2dword0));
147 }
148