-
Notifications
You must be signed in to change notification settings - Fork 45
/
DescriptorSet.cs
114 lines (86 loc) · 4.43 KB
/
DescriptorSet.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
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
using System;
using System.Collections.Generic;
using System.Linq;
using Vortice.Direct3D12;
namespace DirectX12GameEngine.Graphics
{
public class DescriptorSet
{
public DescriptorSet(GraphicsDevice device, int descriptorCount, DescriptorHeapType descriptorHeapType = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView)
{
if (descriptorCount < 1) throw new ArgumentOutOfRangeException(nameof(descriptorCount));
GraphicsDevice = device;
DescriptorHeapType = descriptorHeapType;
TotalDescriptorCount = descriptorCount;
DescriptorAllocator = GetDescriptorAllocator();
StartCpuDescriptorHandle = DescriptorAllocator.Allocate(TotalDescriptorCount);
}
public GraphicsDevice GraphicsDevice { get; }
public DescriptorHeapType DescriptorHeapType { get; }
public int CurrentDescriptorCount { get; private set; }
public int TotalDescriptorCount { get; private set; }
internal DescriptorAllocator DescriptorAllocator { get; }
internal CpuDescriptorHandle StartCpuDescriptorHandle { get; }
public void AddConstantBufferViews(params GraphicsBuffer[] buffers)
{
AddConstantBufferViews(buffers.AsEnumerable());
}
public void AddConstantBufferViews(IEnumerable<GraphicsBuffer> buffers)
{
AddDescriptors(buffers.Select(r => r.CreateConstantBufferView()).ToArray());
}
public void AddShaderResourceViews(params GraphicsResource[] resources)
{
AddShaderResourceViews(resources.AsEnumerable());
}
public void AddShaderResourceViews(IEnumerable<GraphicsResource> resources)
{
AddDescriptors(resources.Select(r => r.NativeShaderResourceView).ToArray());
}
public void AddUnorderedAccessViews(params GraphicsResource[] resources)
{
AddUnorderedAccessViews(resources.AsEnumerable());
}
public void AddUnorderedAccessViews(IEnumerable<GraphicsResource> resources)
{
AddDescriptors(resources.Select(r => r.NativeUnorderedAccessView).ToArray());
}
public void AddSamplers(params SamplerState[] samplers)
{
AddSamplers(samplers);
}
public void AddSamplers(IEnumerable<SamplerState> samplers)
{
AddDescriptors(samplers.Select(r => r.NativeCpuDescriptorHandle).ToArray());
}
private void AddDescriptor(CpuDescriptorHandle descriptorHandle)
{
if (CurrentDescriptorCount + 1 > TotalDescriptorCount) throw new InvalidOperationException();
CpuDescriptorHandle destinationDescriptor = StartCpuDescriptorHandle + CurrentDescriptorCount * DescriptorAllocator.DescriptorHandleIncrementSize;
GraphicsDevice.NativeDevice.CopyDescriptorsSimple(1, destinationDescriptor, descriptorHandle, (Vortice.Direct3D12.DescriptorHeapType)DescriptorHeapType);
CurrentDescriptorCount++;
}
private void AddDescriptors(CpuDescriptorHandle[] descriptors)
{
if (CurrentDescriptorCount + descriptors.Length > TotalDescriptorCount) throw new InvalidOperationException();
int[] sourceDescriptorRangeStarts = new int[descriptors.Length];
//Array.Fill(srcDescriptorRangeStarts, 1);
for (int i = 0; i < sourceDescriptorRangeStarts.Length; i++)
{
sourceDescriptorRangeStarts[i] = 1;
}
CpuDescriptorHandle destinationDescriptor = StartCpuDescriptorHandle + CurrentDescriptorCount * DescriptorAllocator.DescriptorHandleIncrementSize;
GraphicsDevice.NativeDevice.CopyDescriptors(
1, new[] { destinationDescriptor }, new[] { descriptors.Length },
descriptors.Length, descriptors, sourceDescriptorRangeStarts,
(Vortice.Direct3D12.DescriptorHeapType)DescriptorHeapType);
CurrentDescriptorCount += descriptors.Length;
}
private DescriptorAllocator GetDescriptorAllocator() => DescriptorHeapType switch
{
DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView => GraphicsDevice.ShaderResourceViewAllocator,
DescriptorHeapType.Sampler => GraphicsDevice.SamplerAllocator,
_ => throw new NotSupportedException("This descriptor heap type is not supported.")
};
}
}