-
Notifications
You must be signed in to change notification settings - Fork 2k
/
DescriptorHeap.cpp
113 lines (94 loc) · 3.48 KB
/
DescriptorHeap.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
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
// Developed by Minigraph
//
// Author: James Stanard
//
#include "pch.h"
#include "DescriptorHeap.h"
#include "GraphicsCore.h"
#include "CommandListManager.h"
using namespace Graphics;
//
// DescriptorAllocator implementation
//
std::mutex DescriptorAllocator::sm_AllocationMutex;
std::vector<Microsoft::WRL::ComPtr<ID3D12DescriptorHeap>> DescriptorAllocator::sm_DescriptorHeapPool;
void DescriptorAllocator::DestroyAll(void)
{
sm_DescriptorHeapPool.clear();
}
ID3D12DescriptorHeap* DescriptorAllocator::RequestNewHeap(D3D12_DESCRIPTOR_HEAP_TYPE Type)
{
std::lock_guard<std::mutex> LockGuard(sm_AllocationMutex);
D3D12_DESCRIPTOR_HEAP_DESC Desc;
Desc.Type = Type;
Desc.NumDescriptors = sm_NumDescriptorsPerHeap;
Desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
Desc.NodeMask = 1;
Microsoft::WRL::ComPtr<ID3D12DescriptorHeap> pHeap;
ASSERT_SUCCEEDED(Graphics::g_Device->CreateDescriptorHeap(&Desc, MY_IID_PPV_ARGS(&pHeap)));
sm_DescriptorHeapPool.emplace_back(pHeap);
return pHeap.Get();
}
D3D12_CPU_DESCRIPTOR_HANDLE DescriptorAllocator::Allocate( uint32_t Count )
{
if (m_CurrentHeap == nullptr || m_RemainingFreeHandles < Count)
{
m_CurrentHeap = RequestNewHeap(m_Type);
m_CurrentHandle = m_CurrentHeap->GetCPUDescriptorHandleForHeapStart();
m_RemainingFreeHandles = sm_NumDescriptorsPerHeap;
if (m_DescriptorSize == 0)
m_DescriptorSize = Graphics::g_Device->GetDescriptorHandleIncrementSize(m_Type);
}
D3D12_CPU_DESCRIPTOR_HANDLE ret = m_CurrentHandle;
m_CurrentHandle.ptr += Count * m_DescriptorSize;
m_RemainingFreeHandles -= Count;
return ret;
}
//
// DescriptorHeap implementation
//
void DescriptorHeap::Create( const std::wstring& Name, D3D12_DESCRIPTOR_HEAP_TYPE Type, uint32_t MaxCount )
{
m_HeapDesc.Type = Type;
m_HeapDesc.NumDescriptors = MaxCount;
m_HeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
m_HeapDesc.NodeMask = 1;
ASSERT_SUCCEEDED(g_Device->CreateDescriptorHeap(&m_HeapDesc, MY_IID_PPV_ARGS(m_Heap.ReleaseAndGetAddressOf())));
#ifdef RELEASE
(void)Name;
#else
m_Heap->SetName(Name.c_str());
#endif
m_DescriptorSize = g_Device->GetDescriptorHandleIncrementSize(m_HeapDesc.Type);
m_NumFreeDescriptors = m_HeapDesc.NumDescriptors;
m_FirstHandle = DescriptorHandle(
m_Heap->GetCPUDescriptorHandleForHeapStart(),
m_Heap->GetGPUDescriptorHandleForHeapStart());
m_NextFreeHandle = m_FirstHandle;
}
DescriptorHandle DescriptorHeap::Alloc( uint32_t Count )
{
ASSERT(HasAvailableSpace(Count), "Descriptor Heap out of space. Increase heap size.");
DescriptorHandle ret = m_NextFreeHandle;
m_NextFreeHandle += Count * m_DescriptorSize;
m_NumFreeDescriptors -= Count;
return ret;
}
bool DescriptorHeap::ValidateHandle( const DescriptorHandle& DHandle ) const
{
if (DHandle.GetCpuPtr() < m_FirstHandle.GetCpuPtr() ||
DHandle.GetCpuPtr() >= m_FirstHandle.GetCpuPtr() + m_HeapDesc.NumDescriptors * m_DescriptorSize)
return false;
if (DHandle.GetGpuPtr() - m_FirstHandle.GetGpuPtr() !=
DHandle.GetCpuPtr() - m_FirstHandle.GetCpuPtr())
return false;
return true;
}