Skip to content

Commit 1ec60d5

Browse files
Add new function to CommandContainer returning indirectHeap
- returned heap allocatino will have required size and alignment Change-Id: I3612036d5598770fbe74d047de214aedde65ff77 Signed-off-by: Mateusz Hoppe <[email protected]>
1 parent 28511bb commit 1ec60d5

File tree

3 files changed

+135
-3
lines changed

3 files changed

+135
-3
lines changed

core/command_container/cmdcontainer.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2019 Intel Corporation
2+
* Copyright (C) 2019-2020 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -110,4 +110,35 @@ void CommandContainer::reset() {
110110
}
111111
}
112112

113+
IndirectHeap *CommandContainer::getHeapWithRequiredSizeAndAlignment(NEO::HeapType heapType, size_t sizeRequired, size_t alignment) {
114+
auto indirectHeap = getIndirectHeap(heapType);
115+
auto sizeRequested = sizeRequired;
116+
117+
auto heapBuffer = indirectHeap->getSpace(0);
118+
if (alignment && (heapBuffer != alignUp(heapBuffer, alignment))) {
119+
sizeRequested += alignment;
120+
}
121+
122+
if (indirectHeap->getAvailableSpace() < sizeRequested) {
123+
size_t newSize = indirectHeap->getUsed() + indirectHeap->getAvailableSpace();
124+
newSize = alignUp(newSize, 4096U);
125+
auto oldAlloc = getIndirectHeapAllocation(heapType);
126+
auto newAlloc = getHeapHelper()->getHeapAllocation(heapType, newSize, 4096u, device->getRootDeviceIndex());
127+
UNRECOVERABLE_IF(!oldAlloc);
128+
UNRECOVERABLE_IF(!newAlloc);
129+
indirectHeap->replaceGraphicsAllocation(newAlloc);
130+
indirectHeap->replaceBuffer(newAlloc->getUnderlyingBuffer(),
131+
newAlloc->getUnderlyingBufferSize());
132+
getResidencyContainer().push_back(newAlloc);
133+
getDeallocationContainer().push_back(oldAlloc);
134+
setIndirectHeapAllocation(heapType, newAlloc);
135+
setHeapDirty(heapType);
136+
}
137+
138+
if (alignment) {
139+
indirectHeap->align(alignment);
140+
}
141+
return indirectHeap;
142+
}
143+
113144
} // namespace NEO

core/command_container/cmdcontainer.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2019 Intel Corporation
2+
* Copyright (C) 2019-2020 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -63,6 +63,8 @@ class CommandContainer : public NonCopyableOrMovableClass {
6363

6464
Device *getDevice() const { return device; }
6565

66+
IndirectHeap *getHeapWithRequiredSizeAndAlignment(NEO::HeapType heapType, size_t sizeRequired, size_t alignment);
67+
6668
void reset();
6769

6870
bool isHeapDirty(HeapType heapType) const { return (dirtyHeaps & (1u << heapType)); }

core/unit_tests/command_container/command_container_tests.cpp

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017-2019 Intel Corporation
2+
* Copyright (C) 2017-2020 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -187,3 +187,102 @@ TEST_F(CommandContainerTest, givenCommandContainerWhenWantToAddAleradyAddedAlloc
187187

188188
EXPECT_EQ(sizeAfterFirstAdd, sizeAfterSecondAdd);
189189
}
190+
191+
TEST_F(CommandContainerTest, givenAvailableSpaceWhenGetHeapWithRequiredSizeAndAlignmentCalledThenExistingAllocationIsReturned) {
192+
std::unique_ptr<CommandContainer> cmdContainer(new CommandContainer);
193+
cmdContainer->initialize(pDevice);
194+
cmdContainer->setDirtyStateForAllHeaps(false);
195+
auto heapAllocation = cmdContainer->getIndirectHeapAllocation(HeapType::SURFACE_STATE);
196+
auto heap = cmdContainer->getIndirectHeap(HeapType::SURFACE_STATE);
197+
198+
const size_t sizeRequested = 32;
199+
const size_t alignment = 32;
200+
201+
EXPECT_GE(heap->getAvailableSpace(), sizeRequested + alignment);
202+
203+
auto heapRequested = cmdContainer->getHeapWithRequiredSizeAndAlignment(HeapType::SURFACE_STATE, sizeRequested, alignment);
204+
auto newAllocation = heapRequested->getGraphicsAllocation();
205+
206+
EXPECT_EQ(heap, heapRequested);
207+
EXPECT_EQ(heapAllocation, newAllocation);
208+
209+
EXPECT_TRUE((reinterpret_cast<size_t>(heapRequested->getSpace(0)) & (alignment - 1)) == 0);
210+
EXPECT_FALSE(cmdContainer->isHeapDirty(HeapType::SURFACE_STATE));
211+
}
212+
213+
TEST_F(CommandContainerTest, givenUnalignedAvailableSpaceWhenGetHeapWithRequiredSizeAndAlignmentCalledThenHeapReturnedIsCorrectlyAligned) {
214+
std::unique_ptr<CommandContainer> cmdContainer(new CommandContainer);
215+
cmdContainer->initialize(pDevice);
216+
cmdContainer->setDirtyStateForAllHeaps(false);
217+
auto heapAllocation = cmdContainer->getIndirectHeapAllocation(HeapType::SURFACE_STATE);
218+
auto heap = cmdContainer->getIndirectHeap(HeapType::SURFACE_STATE);
219+
220+
const size_t sizeRequested = 32;
221+
const size_t alignment = 32;
222+
223+
heap->getSpace(sizeRequested / 2);
224+
225+
EXPECT_GE(heap->getAvailableSpace(), sizeRequested + alignment);
226+
227+
auto heapRequested = cmdContainer->getHeapWithRequiredSizeAndAlignment(HeapType::SURFACE_STATE, sizeRequested, alignment);
228+
auto newAllocation = heapRequested->getGraphicsAllocation();
229+
230+
EXPECT_EQ(heap, heapRequested);
231+
EXPECT_EQ(heapAllocation, newAllocation);
232+
233+
EXPECT_TRUE((reinterpret_cast<size_t>(heapRequested->getSpace(0)) & (alignment - 1)) == 0);
234+
EXPECT_FALSE(cmdContainer->isHeapDirty(HeapType::SURFACE_STATE));
235+
}
236+
237+
TEST_F(CommandContainerTest, givenNoAlignmentAndAvailableSpaceWhenGetHeapWithRequiredSizeAndAlignmentCalledThenHeapReturnedIsNotAligned) {
238+
std::unique_ptr<CommandContainer> cmdContainer(new CommandContainer);
239+
cmdContainer->initialize(pDevice);
240+
cmdContainer->setDirtyStateForAllHeaps(false);
241+
auto heapAllocation = cmdContainer->getIndirectHeapAllocation(HeapType::SURFACE_STATE);
242+
auto heap = cmdContainer->getIndirectHeap(HeapType::SURFACE_STATE);
243+
244+
const size_t sizeRequested = 32;
245+
const size_t alignment = 0;
246+
247+
heap->getSpace(sizeRequested / 2);
248+
249+
EXPECT_GE(heap->getAvailableSpace(), sizeRequested + alignment);
250+
251+
auto heapRequested = cmdContainer->getHeapWithRequiredSizeAndAlignment(HeapType::SURFACE_STATE, sizeRequested, alignment);
252+
auto newAllocation = heapRequested->getGraphicsAllocation();
253+
254+
EXPECT_EQ(heap, heapRequested);
255+
EXPECT_EQ(heapAllocation, newAllocation);
256+
257+
EXPECT_TRUE((reinterpret_cast<size_t>(heapRequested->getSpace(0)) & (sizeRequested / 2)) == sizeRequested / 2);
258+
EXPECT_FALSE(cmdContainer->isHeapDirty(HeapType::SURFACE_STATE));
259+
}
260+
261+
TEST_F(CommandContainerTest, givenNotEnoughSpaceWhenGetHeapWithRequiredSizeAndAlignmentCalledThenNewAllocationIsReturned) {
262+
std::unique_ptr<CommandContainer> cmdContainer(new CommandContainer);
263+
cmdContainer->initialize(pDevice);
264+
cmdContainer->setDirtyStateForAllHeaps(false);
265+
auto heapAllocation = cmdContainer->getIndirectHeapAllocation(HeapType::SURFACE_STATE);
266+
auto heap = cmdContainer->getIndirectHeap(HeapType::SURFACE_STATE);
267+
268+
const size_t sizeRequested = 32;
269+
const size_t alignment = 32;
270+
size_t availableSize = heap->getAvailableSpace();
271+
272+
heap->getSpace(availableSize - sizeRequested / 2);
273+
274+
EXPECT_LT(heap->getAvailableSpace(), sizeRequested + alignment);
275+
276+
auto heapRequested = cmdContainer->getHeapWithRequiredSizeAndAlignment(HeapType::SURFACE_STATE, sizeRequested, alignment);
277+
auto newAllocation = heapRequested->getGraphicsAllocation();
278+
279+
EXPECT_EQ(heap, heapRequested);
280+
EXPECT_NE(heapAllocation, newAllocation);
281+
282+
EXPECT_TRUE((reinterpret_cast<size_t>(heapRequested->getSpace(0)) & (alignment - 1)) == 0);
283+
EXPECT_TRUE(cmdContainer->isHeapDirty(HeapType::SURFACE_STATE));
284+
285+
for (auto deallocation : cmdContainer->getDeallocationContainer()) {
286+
cmdContainer->getDevice()->getMemoryManager()->freeGraphicsMemory(deallocation);
287+
}
288+
}

0 commit comments

Comments
 (0)