-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDescriptorAllocator.cpp
120 lines (100 loc) · 2.91 KB
/
DescriptorAllocator.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "D3D12FrameWork/DescriptorAllocator.h"
#include "D3D12FrameWork/D3DDevice.h"
#include "D3D12FrameWork/Common.h"
namespace D3D12FrameWork{
void DescriptorInfo::Free() {
if (m_pAllocator == nullptr) {
return;
}
m_pAllocator->Free(*this);
m_pAllocator = nullptr;
m_pItem = nullptr;
}
DescriptorAllocator::DescriptorAllocator()
:m_pBuffer(nullptr)
, m_pFreeList(nullptr)
, m_IncrementSize(0)
, m_pHeap(nullptr)
, m_HeapDesc() {}
bool DescriptorAllocator::Init(D3DDevice* dev
, D3D12_DESCRIPTOR_HEAP_DESC const& desc) {
m_HeapDesc = desc;
//ヒープの作製
auto hr = dev->GetDev()->CreateDescriptorHeap(
&desc, IID_PPV_ARGS(m_pHeap.ReleaseAndGetAddressOf())
);
if (FAILED(hr)) {
assert(SUCCEEDED(hr));
return false;
}
m_IncrementSize = dev->GetDev()->GetDescriptorHandleIncrementSize(desc.Type);
m_hCpuHead = m_pHeap->GetCPUDescriptorHandleForHeapStart();
if (desc.Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE) {
m_hGpuHead = m_pHeap->GetGPUDescriptorHandleForHeapStart();
m_isGPUVisible = true;
}
else {
m_isGPUVisible = false;
}
//メモリ管理情報の作製
m_pBuffer = std::make_unique<uint8_t[]>(
desc.NumDescriptors * sizeof(DescriptorInfo::Item)
);
//static_cast<uint8_t*>(
//std::malloc(desc.NumDescriptors * sizeof(DescriptorInfo::Item)));
m_pFreeList = GetItem(0);
m_pFreeList->m_Index = 0;
m_pFreeList->m_Next = GetItem(1);
for (auto i = 1u; i < desc.NumDescriptors-1; i++) {
auto item = GetItem(i);
item->m_Index = i;
item->m_Next = GetItem(i + 1);
}
auto tmpItem = GetItem(desc.NumDescriptors - 1);
tmpItem->m_Index = desc.NumDescriptors - 1;
tmpItem->m_Next = nullptr;
return true;
}
DescriptorInfo::Item* DescriptorAllocator::GetItem(uint32_t index) {
assert(index < m_HeapDesc.NumDescriptors);
return reinterpret_cast<DescriptorInfo::Item*>(
m_pBuffer.get() + sizeof(DescriptorInfo::Item) * index
);
}
DescriptorInfo const& DescriptorAllocator::Allocate() {
std::lock_guard<std::mutex> lockguard(m_mutex);
DescriptorInfo retInfo = {};
if (m_pFreeList == nullptr) {
LOG_ERR("Memory Pool Shortage!");
return retInfo;
}
//空いているメモリを割り当て
auto idx = m_pFreeList->m_Index;
retInfo.m_pItem = m_pFreeList;
retInfo.m_CpuHandle = m_hCpuHead;
retInfo.m_CpuHandle.ptr += m_IncrementSize * idx;
if (m_isGPUVisible) {
retInfo.m_GpuHandle = m_hGpuHead;
retInfo.m_GpuHandle.ptr += m_IncrementSize * idx;
}
else {
retInfo.m_GpuHandle.ptr = 0;
}
retInfo.m_pAllocator = this;
//空き情報更新
m_pFreeList = m_pFreeList->m_Next;
return retInfo;
}
void DescriptorAllocator::Free(DescriptorInfo const& descInfo) {
std::lock_guard<std::mutex> lockguard(m_mutex);
if (descInfo.m_pItem == nullptr) {
assert(false);
return;
}
//空き情報更新
descInfo.m_pItem->m_Next = m_pFreeList;
m_pFreeList = descInfo.m_pItem;
}
void DescriptorAllocator::Term() {
}
}