2 // Copyright (c) Microsoft. All rights reserved.
3 // This code is licensed under the MIT License (MIT).
4 // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
5 // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
6 // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
7 // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
9 // Developed by Minigraph
11 // Author: James Stanard
15 #include "DescriptorHeap.h"
16 #include "GraphicsCore.h"
17 #include "CommandListManager.h"
19 using namespace Graphics
;
22 // DescriptorAllocator implementation
24 std::mutex
DescriptorAllocator::sm_AllocationMutex
;
25 std::vector
<Microsoft::WRL::ComPtr
<ID3D12DescriptorHeap
>> DescriptorAllocator::sm_DescriptorHeapPool
;
27 void DescriptorAllocator::DestroyAll(void)
29 sm_DescriptorHeapPool
.clear();
32 ID3D12DescriptorHeap
* DescriptorAllocator::RequestNewHeap(D3D12_DESCRIPTOR_HEAP_TYPE Type
)
34 std::lock_guard
<std::mutex
> LockGuard(sm_AllocationMutex
);
36 D3D12_DESCRIPTOR_HEAP_DESC Desc
;
38 Desc
.NumDescriptors
= sm_NumDescriptorsPerHeap
;
39 Desc
.Flags
= D3D12_DESCRIPTOR_HEAP_FLAG_NONE
;
42 Microsoft::WRL::ComPtr
<ID3D12DescriptorHeap
> pHeap
;
43 ASSERT_SUCCEEDED(Graphics::g_Device
->CreateDescriptorHeap(&Desc
, MY_IID_PPV_ARGS(&pHeap
)));
44 sm_DescriptorHeapPool
.emplace_back(pHeap
);
48 D3D12_CPU_DESCRIPTOR_HANDLE
DescriptorAllocator::Allocate( uint32_t Count
)
50 if (m_CurrentHeap
== nullptr || m_RemainingFreeHandles
< Count
)
52 m_CurrentHeap
= RequestNewHeap(m_Type
);
53 m_CurrentHandle
= m_CurrentHeap
->GetCPUDescriptorHandleForHeapStart();
54 m_RemainingFreeHandles
= sm_NumDescriptorsPerHeap
;
56 if (m_DescriptorSize
== 0)
57 m_DescriptorSize
= Graphics::g_Device
->GetDescriptorHandleIncrementSize(m_Type
);
60 D3D12_CPU_DESCRIPTOR_HANDLE ret
= m_CurrentHandle
;
61 m_CurrentHandle
.ptr
+= Count
* m_DescriptorSize
;
62 m_RemainingFreeHandles
-= Count
;
67 // UserDescriptorHeap implementation
70 void UserDescriptorHeap::Create( const std::wstring
& DebugHeapName
)
72 ASSERT_SUCCEEDED(Graphics::g_Device
->CreateDescriptorHeap(&m_HeapDesc
, MY_IID_PPV_ARGS(m_Heap
.ReleaseAndGetAddressOf())));
76 m_Heap
->SetName(DebugHeapName
.c_str());
79 m_DescriptorSize
= Graphics::g_Device
->GetDescriptorHandleIncrementSize(m_HeapDesc
.Type
);
80 m_NumFreeDescriptors
= m_HeapDesc
.NumDescriptors
;
81 m_FirstHandle
= DescriptorHandle( m_Heap
->GetCPUDescriptorHandleForHeapStart(), m_Heap
->GetGPUDescriptorHandleForHeapStart() );
82 m_NextFreeHandle
= m_FirstHandle
;
85 DescriptorHandle
UserDescriptorHeap::Alloc( uint32_t Count
)
87 ASSERT(HasAvailableSpace(Count
), "Descriptor Heap out of space. Increase heap size.");
88 DescriptorHandle ret
= m_NextFreeHandle
;
89 m_NextFreeHandle
+= Count
* m_DescriptorSize
;
93 bool UserDescriptorHeap::ValidateHandle( const DescriptorHandle
& DHandle
) const
95 if (DHandle
.GetCpuHandle().ptr
< m_FirstHandle
.GetCpuHandle().ptr
||
96 DHandle
.GetCpuHandle().ptr
>= m_FirstHandle
.GetCpuHandle().ptr
+ m_HeapDesc
.NumDescriptors
* m_DescriptorSize
)
99 if (DHandle
.GetGpuHandle().ptr
- m_FirstHandle
.GetGpuHandle().ptr
!=
100 DHandle
.GetCpuHandle().ptr
- m_FirstHandle
.GetCpuHandle().ptr
)