-
Notifications
You must be signed in to change notification settings - Fork 45
/
DescriptorAllocator.cs
86 lines (64 loc) · 3.32 KB
/
DescriptorAllocator.cs
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
using System;
using Vortice.Direct3D12;
namespace DirectX12GameEngine.Graphics
{
internal sealed class DescriptorAllocator : IDisposable
{
private const int DescriptorsPerHeap = 4096;
private readonly object allocatorLock = new object();
public DescriptorAllocator(GraphicsDevice device, DescriptorHeapType descriptorHeapType, int descriptorCount = DescriptorsPerHeap, DescriptorHeapFlags descriptorHeapFlags = DescriptorHeapFlags.None)
{
if (descriptorCount < 1 || descriptorCount > DescriptorsPerHeap)
{
throw new ArgumentOutOfRangeException(nameof(descriptorCount), $"Descriptor count must be between 1 and {DescriptorsPerHeap}.");
}
DescriptorHandleIncrementSize = device.NativeDevice.GetDescriptorHandleIncrementSize((Vortice.Direct3D12.DescriptorHeapType)descriptorHeapType);
DescriptorHeapDescription descriptorHeapDescription = new DescriptorHeapDescription((Vortice.Direct3D12.DescriptorHeapType)descriptorHeapType, descriptorCount, descriptorHeapFlags);
DescriptorHeap = device.NativeDevice.CreateDescriptorHeap(descriptorHeapDescription);
TotalDescriptorCount = descriptorCount;
}
public int CurrentDescriptorCount { get; private set; }
public int TotalDescriptorCount { get; private set; }
internal ID3D12DescriptorHeap DescriptorHeap { get; }
internal int DescriptorHandleIncrementSize { get; }
internal CpuDescriptorHandle CurrentCpuDescriptorHandle => DescriptorHeap.GetCPUDescriptorHandleForHeapStart() + CurrentDescriptorCount * DescriptorHandleIncrementSize;
internal GpuDescriptorHandle CurrentGpuDescriptorHandle => DescriptorHeap.GetGPUDescriptorHandleForHeapStart() + CurrentDescriptorCount * DescriptorHandleIncrementSize;
public CpuDescriptorHandle Allocate(int count)
{
lock (allocatorLock)
{
if (count < 1 || (CurrentDescriptorCount + count > TotalDescriptorCount && CurrentDescriptorCount != TotalDescriptorCount))
{
throw new ArgumentOutOfRangeException(nameof(count), "Count must be between 1 and the remaining handles if the remaining handles are not 0.");
}
if (CurrentDescriptorCount == TotalDescriptorCount)
{
Reset();
}
CpuDescriptorHandle cpuDescriptorHandle = CurrentCpuDescriptorHandle;
CurrentDescriptorCount += count;
return cpuDescriptorHandle;
}
}
public CpuDescriptorHandle AllocateSlot(int slot)
{
lock (allocatorLock)
{
if (slot < 0 || slot > TotalDescriptorCount - 1)
{
throw new ArgumentOutOfRangeException(nameof(slot), "Slot must be between 0 and the descript count - 1.");
}
CpuDescriptorHandle cpuDescriptorHandle = DescriptorHeap.GetCPUDescriptorHandleForHeapStart() + slot * DescriptorHandleIncrementSize;
return cpuDescriptorHandle;
}
}
public void Reset()
{
CurrentDescriptorCount = 0;
}
public void Dispose()
{
DescriptorHeap.Dispose();
}
}
}