1#include "Project/Draw/GpuMemAllocator.h"
2
3#include <common/aglGPUMemBlock.h>
4
5#include "Library/Base/StringUtil.h"
6
7namespace al {
8
9GpuMemAllocator::GpuMemAllocator() {
10 mBlocks.allocBuffer(ptrNumMax: 16, heap: nullptr);
11}
12
13GpuMemAllocator::~GpuMemAllocator() {
14 for (s32 i = 0; i < mBlocks.size(); i++) {
15 Block* block = mBlocks[i];
16 if (block->addr.isValid()) {
17 block->addr.deleteGPUMemBlock();
18 block->addr.invalidate();
19 }
20
21 if (block->tmpAddr.isValid()) {
22 block->tmpAddr.deleteGPUMemBlock();
23 block->tmpAddr.invalidate();
24 }
25 }
26}
27
28void GpuMemAllocator::createMemory(const char* name, s32 size, sead::Heap* heap, s32 alignment,
29 agl::MemoryAttribute attribute) {
30 if (findGpuMemInfo(name))
31 return;
32
33 Block* block = new Block;
34 s64 longSize = size;
35 agl::GPUMemBlockT<u8>* memBlock = new (heap) agl::GPUMemBlockT<u8>;
36 memBlock->allocBuffer_(longSize, heap, alignment, attribute);
37 block->addr = agl::GPUMemAddrBase(*memBlock, 0);
38 block->memorySize = size;
39 block->name.format(formatStr: "%s", name);
40
41 mBlocks.pushBack(ptr: block);
42}
43
44GpuMemAllocator::Block* GpuMemAllocator::findGpuMemInfo(const char* name) const {
45 for (s32 i = 0; i < mBlocks.size(); i++) {
46 Block* block = mBlocks[i];
47 if (isEqualString(str1: name, str2: block->name.cstr()))
48 return block;
49 }
50 return nullptr;
51}
52
53void GpuMemAllocator::createMemoryWithTmp(const char* name, s32 size, s32 tmpSize, sead::Heap* heap,
54 s32 alignment, agl::MemoryAttribute attribute) {
55 createMemory(name, size, heap, alignment, attribute);
56 Block* block = findGpuMemInfo(name);
57 s64 longSize = tmpSize;
58 agl::GPUMemBlockT<u8>* memBlock = new (heap) agl::GPUMemBlockT<u8>;
59 memBlock->allocBuffer_(longSize, heap, alignment, attribute);
60 block->tmpAddr = agl::GPUMemAddrBase(*memBlock, 0);
61 block->tmpMemorySize = tmpSize;
62}
63
64agl::GPUMemAddrBase GpuMemAllocator::allocMemory(const char* name, s32 size, s32 alignment) {
65 Block* block = findGpuMemInfo(name);
66 if (!block)
67 return {};
68
69 if (block->usedSize + size > block->memorySize)
70 return {};
71
72 s32 alignedSize;
73 if (block->usedSize >= 0) {
74 s32 unalignedSize = block->usedSize + alignment - 1;
75 alignedSize = unalignedSize / alignment * alignment;
76 } else {
77 s32 unalignedSize = block->usedSize - alignment + 1;
78 alignedSize = unalignedSize / alignment * alignment;
79 }
80
81 block->usedSize = alignedSize + size;
82 return {block->addr, alignedSize};
83}
84
85agl::GPUMemAddrBase GpuMemAllocator::getTmpMemoryAddr(const char* name) const {
86 Block* block = findGpuMemInfo(name);
87 if (!block)
88 return {};
89
90 block->tmpAddr.invalidateCPUCache(block->tmpMemorySize);
91 return {block->tmpAddr, 0};
92}
93
94u32 GpuMemAllocator::getTmpMemorySize(const char* name) const {
95 Block* block = findGpuMemInfo(name);
96 if (!block)
97 return 0;
98
99 return block->tmpMemorySize;
100}
101
102} // namespace al
103