1 /*
2  * Copyright (C) 2019-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #pragma once
9 #include "shared/source/command_stream/csr_definitions.h"
10 #include "shared/source/helpers/heap_helper.h"
11 #include "shared/source/helpers/non_copyable_or_moveable.h"
12 #include "shared/source/indirect_heap/indirect_heap.h"
13 
14 #include <cstdint>
15 #include <limits>
16 #include <memory>
17 #include <vector>
18 
19 namespace NEO {
20 class Device;
21 class GraphicsAllocation;
22 class LinearStream;
23 class AllocationsList;
24 
25 using ResidencyContainer = std::vector<GraphicsAllocation *>;
26 using CmdBufferContainer = std::vector<GraphicsAllocation *>;
27 using HeapType = IndirectHeap::Type;
28 
29 enum class ErrorCode {
30     SUCCESS = 0,
31     OUT_OF_DEVICE_MEMORY = 1
32 };
33 
34 class CommandContainer : public NonCopyableOrMovableClass {
35   public:
36     static constexpr size_t defaultListCmdBufferSize = MemoryConstants::kiloByte * 256;
37     static constexpr size_t totalCmdBufferSize =
38         defaultListCmdBufferSize +
39         MemoryConstants::cacheLineSize +
40         CSRequirements::csOverfetchSize;
41 
CommandContainer()42     CommandContainer() {
43         for (auto &indirectHeap : indirectHeaps) {
44             indirectHeap = nullptr;
45         }
46 
47         for (auto &allocationIndirectHeap : allocationIndirectHeaps) {
48             allocationIndirectHeap = nullptr;
49         }
50     }
51 
CommandContainer(uint32_t maxNumAggregatedIdds)52     CommandContainer(uint32_t maxNumAggregatedIdds) : CommandContainer() {
53         numIddsPerBlock = maxNumAggregatedIdds;
54     }
55 
getCmdBufferAllocations()56     CmdBufferContainer &getCmdBufferAllocations() { return cmdBufferAllocations; }
57 
getResidencyContainer()58     ResidencyContainer &getResidencyContainer() { return residencyContainer; }
59 
getDeallocationContainer()60     std::vector<GraphicsAllocation *> &getDeallocationContainer() { return deallocationContainer; }
61 
62     void addToResidencyContainer(GraphicsAllocation *alloc);
63     void removeDuplicatesFromResidencyContainer();
64 
getCommandStream()65     LinearStream *getCommandStream() { return commandStream.get(); }
66 
getIndirectHeap(HeapType heapType)67     IndirectHeap *getIndirectHeap(HeapType heapType) { return indirectHeaps[heapType].get(); }
68 
getHeapHelper()69     HeapHelper *getHeapHelper() { return heapHelper.get(); }
70 
getIndirectHeapAllocation(HeapType heapType)71     GraphicsAllocation *getIndirectHeapAllocation(HeapType heapType) { return allocationIndirectHeaps[heapType]; }
72 
setIndirectHeapAllocation(HeapType heapType,GraphicsAllocation * allocation)73     void setIndirectHeapAllocation(HeapType heapType, GraphicsAllocation *allocation) { allocationIndirectHeaps[heapType] = allocation; }
74 
getInstructionHeapBaseAddress()75     uint64_t getInstructionHeapBaseAddress() const { return instructionHeapBaseAddress; }
76 
getIndirectObjectHeapBaseAddress()77     uint64_t getIndirectObjectHeapBaseAddress() const { return indirectObjectHeapBaseAddress; }
78 
79     void *getHeapSpaceAllowGrow(HeapType heapType, size_t size);
80 
81     ErrorCode initialize(Device *device, AllocationsList *reusableAllocationList);
82 
83     void prepareBindfulSsh();
84 
85     virtual ~CommandContainer();
86 
87     uint32_t slmSize = std::numeric_limits<uint32_t>::max();
88     uint32_t nextIddInBlock = 0;
89     uint32_t lastSentNumGrfRequired = 0;
90     bool lastPipelineSelectModeRequired = false;
91     bool lastSentUseGlobalAtomics = false;
92 
getDevice()93     Device *getDevice() const { return device; }
94 
95     IndirectHeap *getHeapWithRequiredSizeAndAlignment(HeapType heapType, size_t sizeRequired, size_t alignment);
96     void allocateNextCommandBuffer();
97 
98     void handleCmdBufferAllocations(size_t startIndex);
99     GraphicsAllocation *obtainNextCommandBufferAllocation();
100 
101     void reset();
102 
isHeapDirty(HeapType heapType)103     bool isHeapDirty(HeapType heapType) const { return (dirtyHeaps & (1u << heapType)); }
isAnyHeapDirty()104     bool isAnyHeapDirty() const { return dirtyHeaps != 0; }
setHeapDirty(HeapType heapType)105     void setHeapDirty(HeapType heapType) { dirtyHeaps |= (1u << heapType); }
setDirtyStateForAllHeaps(bool dirty)106     void setDirtyStateForAllHeaps(bool dirty) { dirtyHeaps = dirty ? std::numeric_limits<uint32_t>::max() : 0; }
setIddBlock(void * iddBlock)107     void setIddBlock(void *iddBlock) { this->iddBlock = iddBlock; }
getIddBlock()108     void *getIddBlock() { return iddBlock; }
getNumIddPerBlock()109     uint32_t getNumIddPerBlock() const { return numIddsPerBlock; }
setReservedSshSize(size_t reserveSize)110     void setReservedSshSize(size_t reserveSize) {
111         reservedSshSize = reserveSize;
112     }
113     HeapContainer sshAllocations;
114 
getFlushTaskUsedForImmediate()115     bool getFlushTaskUsedForImmediate() { return isFlushTaskUsedForImmediate; }
setFlushTaskUsedForImmediate(bool flushTaskUsedForImmediate)116     void setFlushTaskUsedForImmediate(bool flushTaskUsedForImmediate) { isFlushTaskUsedForImmediate = flushTaskUsedForImmediate; }
117 
118   protected:
119     void *iddBlock = nullptr;
120     Device *device = nullptr;
121     AllocationsList *reusableAllocationList = nullptr;
122     std::unique_ptr<HeapHelper> heapHelper;
123 
124     CmdBufferContainer cmdBufferAllocations;
125     GraphicsAllocation *allocationIndirectHeaps[HeapType::NUM_TYPES] = {};
126     uint64_t instructionHeapBaseAddress = 0u;
127     uint64_t indirectObjectHeapBaseAddress = 0u;
128     uint32_t dirtyHeaps = std::numeric_limits<uint32_t>::max();
129     uint32_t numIddsPerBlock = 64;
130     size_t reservedSshSize = 0;
131 
132     std::unique_ptr<LinearStream> commandStream;
133     std::unique_ptr<IndirectHeap> indirectHeaps[HeapType::NUM_TYPES];
134     ResidencyContainer residencyContainer;
135     std::vector<GraphicsAllocation *> deallocationContainer;
136 
137     bool isFlushTaskUsedForImmediate = false;
138 };
139 
140 } // namespace NEO
141