2020-10-19 16:02:28 +08:00
|
|
|
/*
|
2021-05-17 02:51:16 +08:00
|
|
|
* Copyright (C) 2020-2021 Intel Corporation
|
2020-10-19 16:02:28 +08:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "shared/source/helpers/bindless_heaps_helper.h"
|
|
|
|
|
|
|
|
#include "shared/source/helpers/string.h"
|
|
|
|
#include "shared/source/indirect_heap/indirect_heap.h"
|
|
|
|
#include "shared/source/memory_manager/memory_manager.h"
|
|
|
|
|
|
|
|
namespace NEO {
|
|
|
|
|
|
|
|
constexpr size_t globalSshAllocationSize = 4 * MemoryConstants::pageSize64k;
|
2020-11-03 18:42:35 +08:00
|
|
|
using BindlesHeapType = BindlessHeapsHelper::BindlesHeapType;
|
2020-10-19 16:02:28 +08:00
|
|
|
|
|
|
|
BindlessHeapsHelper::BindlessHeapsHelper(MemoryManager *memManager, bool isMultiOsContextCapable, const uint32_t rootDeviceIndex) : memManager(memManager), isMultiOsContextCapable(isMultiOsContextCapable), rootDeviceIndex(rootDeviceIndex) {
|
2020-11-03 18:42:35 +08:00
|
|
|
for (auto heapType = 0; heapType < BindlesHeapType::NUM_HEAP_TYPES; heapType++) {
|
|
|
|
auto allocInFrontWindow = heapType != BindlesHeapType::GLOBAL_DSH;
|
|
|
|
auto heapAllocation = getHeapAllocation(MemoryConstants::pageSize64k, MemoryConstants::pageSize64k, allocInFrontWindow);
|
|
|
|
UNRECOVERABLE_IF(heapAllocation == nullptr);
|
|
|
|
ssHeapsAllocations.push_back(heapAllocation);
|
2020-12-04 19:28:18 +08:00
|
|
|
surfaceStateHeaps[heapType] = std::make_unique<IndirectHeap>(heapAllocation, true);
|
2020-11-03 18:42:35 +08:00
|
|
|
}
|
2020-10-19 16:02:28 +08:00
|
|
|
|
2020-11-03 18:42:35 +08:00
|
|
|
borderColorStates = getHeapAllocation(MemoryConstants::pageSize, MemoryConstants::pageSize, true);
|
2020-10-19 16:02:28 +08:00
|
|
|
UNRECOVERABLE_IF(borderColorStates == nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
BindlessHeapsHelper::~BindlessHeapsHelper() {
|
|
|
|
for (auto *allocation : ssHeapsAllocations) {
|
|
|
|
memManager->freeGraphicsMemory(allocation);
|
|
|
|
}
|
|
|
|
memManager->freeGraphicsMemory(borderColorStates);
|
|
|
|
ssHeapsAllocations.clear();
|
|
|
|
}
|
|
|
|
|
2020-11-03 18:42:35 +08:00
|
|
|
GraphicsAllocation *BindlessHeapsHelper::getHeapAllocation(size_t heapSize, size_t alignment, bool allocInFrontWindow) {
|
2020-10-19 16:02:28 +08:00
|
|
|
auto allocationType = GraphicsAllocation::AllocationType::LINEAR_STREAM;
|
|
|
|
NEO::AllocationProperties properties{rootDeviceIndex, true, heapSize, allocationType, isMultiOsContextCapable, false};
|
2020-11-03 18:42:35 +08:00
|
|
|
properties.flags.use32BitFrontWindow = allocInFrontWindow;
|
2020-10-19 16:02:28 +08:00
|
|
|
properties.alignment = alignment;
|
|
|
|
|
|
|
|
return this->memManager->allocateGraphicsMemoryWithProperties(properties);
|
|
|
|
}
|
|
|
|
|
2020-11-03 18:42:35 +08:00
|
|
|
SurfaceStateInHeapInfo BindlessHeapsHelper::allocateSSInHeap(size_t ssSize, GraphicsAllocation *surfaceAllocation, BindlesHeapType heapType) {
|
|
|
|
auto heap = surfaceStateHeaps[heapType].get();
|
|
|
|
if (heapType == BindlesHeapType::GLOBAL_SSH) {
|
|
|
|
auto ssAllocatedInfo = surfaceStateInHeapAllocationMap.find(surfaceAllocation);
|
|
|
|
if (ssAllocatedInfo != surfaceStateInHeapAllocationMap.end()) {
|
|
|
|
return *ssAllocatedInfo->second.get();
|
2021-01-27 21:31:29 +08:00
|
|
|
} else {
|
|
|
|
std::lock_guard<std::mutex> autolock(this->mtx);
|
|
|
|
if (surfaceStateInHeapVectorReuse.size()) {
|
|
|
|
SurfaceStateInHeapInfo surfaceStateFromVector = *(surfaceStateInHeapVectorReuse.back());
|
|
|
|
surfaceStateInHeapVectorReuse.pop_back();
|
|
|
|
std::pair<GraphicsAllocation *, std::unique_ptr<SurfaceStateInHeapInfo>> pair(surfaceAllocation, std::make_unique<SurfaceStateInHeapInfo>(surfaceStateFromVector));
|
|
|
|
surfaceStateInHeapAllocationMap.insert(std::move(pair));
|
|
|
|
return surfaceStateFromVector;
|
|
|
|
}
|
2020-11-03 18:42:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
void *ptrInHeap = getSpaceInHeap(ssSize, heapType);
|
2020-12-04 19:28:18 +08:00
|
|
|
memset(ptrInHeap, 0, ssSize);
|
2020-11-03 18:42:35 +08:00
|
|
|
auto bindlessOffset = heap->getGraphicsAllocation()->getGpuAddress() - heap->getGraphicsAllocation()->getGpuBaseAddress() + heap->getUsed() - ssSize;
|
|
|
|
SurfaceStateInHeapInfo bindlesInfo;
|
|
|
|
if (heapType == BindlesHeapType::GLOBAL_SSH) {
|
|
|
|
std::pair<GraphicsAllocation *, std::unique_ptr<SurfaceStateInHeapInfo>> pair(surfaceAllocation, std::make_unique<SurfaceStateInHeapInfo>(SurfaceStateInHeapInfo{heap->getGraphicsAllocation(), bindlessOffset, ptrInHeap}));
|
|
|
|
bindlesInfo = *pair.second;
|
|
|
|
surfaceStateInHeapAllocationMap.insert(std::move(pair));
|
|
|
|
} else {
|
|
|
|
bindlesInfo = SurfaceStateInHeapInfo{heap->getGraphicsAllocation(), bindlessOffset, ptrInHeap};
|
2020-10-19 16:02:28 +08:00
|
|
|
}
|
|
|
|
return bindlesInfo;
|
|
|
|
}
|
|
|
|
|
2020-11-03 18:42:35 +08:00
|
|
|
void *BindlessHeapsHelper::getSpaceInHeap(size_t ssSize, BindlesHeapType heapType) {
|
|
|
|
auto heap = surfaceStateHeaps[heapType].get();
|
|
|
|
if (heap->getAvailableSpace() < ssSize) {
|
|
|
|
growHeap(heapType);
|
2020-10-19 16:02:28 +08:00
|
|
|
}
|
2020-11-03 18:42:35 +08:00
|
|
|
return heap->getSpace(ssSize);
|
2020-10-19 16:02:28 +08:00
|
|
|
}
|
|
|
|
|
2020-11-03 18:42:35 +08:00
|
|
|
uint64_t BindlessHeapsHelper::getGlobalHeapsBase() {
|
|
|
|
return surfaceStateHeaps[BindlesHeapType::GLOBAL_SSH]->getGraphicsAllocation()->getGpuBaseAddress();
|
2020-10-19 16:02:28 +08:00
|
|
|
}
|
|
|
|
|
2021-04-28 23:53:39 +08:00
|
|
|
uint32_t BindlessHeapsHelper::getBorderColorOffset() {
|
|
|
|
return borderColorOffset;
|
2020-10-19 16:02:28 +08:00
|
|
|
}
|
2021-04-28 23:53:39 +08:00
|
|
|
void BindlessHeapsHelper::setBorderColor(void *borderColor, size_t size) {
|
|
|
|
borderColorOffset = static_cast<uint32_t>(borderColorStates->getGpuAddress() - borderColorStates->getGpuBaseAddress());
|
|
|
|
memcpy_s(borderColorStates->getUnderlyingBuffer(), borderColorStates->getUnderlyingBufferSize(), borderColor, size);
|
2020-11-26 17:04:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
IndirectHeap *BindlessHeapsHelper::getHeap(BindlesHeapType heapType) {
|
|
|
|
return surfaceStateHeaps[heapType].get();
|
2020-10-19 16:02:28 +08:00
|
|
|
}
|
|
|
|
|
2020-11-03 18:42:35 +08:00
|
|
|
void BindlessHeapsHelper::growHeap(BindlesHeapType heapType) {
|
|
|
|
auto heap = surfaceStateHeaps[heapType].get();
|
|
|
|
auto allocInFrontWindow = heapType != BindlesHeapType::GLOBAL_DSH;
|
|
|
|
auto newAlloc = getHeapAllocation(globalSshAllocationSize, MemoryConstants::pageSize64k, allocInFrontWindow);
|
2020-10-19 16:02:28 +08:00
|
|
|
UNRECOVERABLE_IF(newAlloc == nullptr);
|
|
|
|
ssHeapsAllocations.push_back(newAlloc);
|
2020-11-03 18:42:35 +08:00
|
|
|
heap->replaceGraphicsAllocation(newAlloc);
|
|
|
|
heap->replaceBuffer(newAlloc->getUnderlyingBuffer(),
|
|
|
|
newAlloc->getUnderlyingBufferSize());
|
2020-10-19 16:02:28 +08:00
|
|
|
}
|
|
|
|
|
2021-01-27 21:31:29 +08:00
|
|
|
void BindlessHeapsHelper::placeSSAllocationInReuseVectorOnFreeMemory(GraphicsAllocation *gfxAllocation) {
|
|
|
|
auto ssAllocatedInfo = surfaceStateInHeapAllocationMap.find(gfxAllocation);
|
|
|
|
if (ssAllocatedInfo != surfaceStateInHeapAllocationMap.end()) {
|
|
|
|
std::lock_guard<std::mutex> autolock(this->mtx);
|
|
|
|
surfaceStateInHeapVectorReuse.push_back(std::move(ssAllocatedInfo->second));
|
|
|
|
surfaceStateInHeapAllocationMap.erase(ssAllocatedInfo);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-10-19 16:02:28 +08:00
|
|
|
} // namespace NEO
|