forked from discosultan/dx12-game-programming
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFrameResource.cs
173 lines (150 loc) · 5.63 KB
/
FrameResource.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
using System;
using System.Runtime.InteropServices;
using SharpDX;
using SharpDX.Direct3D12;
namespace DX12GameProgramming
{
[StructLayout(LayoutKind.Sequential, Pack = 4)]
internal struct ObjectConstants
{
public Matrix World;
public Matrix TexTransform;
public int MaterialIndex;
public int ObjPad0;
public int ObjPad1;
public int ObjPad2;
public static ObjectConstants Default => new ObjectConstants
{
World = Matrix.Identity,
TexTransform = Matrix.Identity
};
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
internal struct PassConstants
{
public Matrix View;
public Matrix InvView;
public Matrix Proj;
public Matrix InvProj;
public Matrix ViewProj;
public Matrix InvViewProj;
public Matrix ViewProjTex;
public Matrix ShadowTransform;
public Vector3 EyePosW;
public float PerObjectPad1;
public Vector2 RenderTargetSize;
public Vector2 InvRenderTargetSize;
public float NearZ;
public float FarZ;
public float TotalTime;
public float DeltaTime;
public Vector4 AmbientLight;
// Indices [0, NUM_DIR_LIGHTS) are directional lights;
// indices [NUM_DIR_LIGHTS, NUM_DIR_LIGHTS+NUM_POINT_LIGHTS) are point lights;
// indices [NUM_DIR_LIGHTS+NUM_POINT_LIGHTS, NUM_DIR_LIGHTS+NUM_POINT_LIGHT+NUM_SPOT_LIGHTS)
// are spot lights for a maximum of MaxLights per object.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = Light.MaxLights)]
public Light[] Lights;
public static PassConstants Default => new PassConstants
{
View = Matrix.Identity,
InvView = Matrix.Identity,
Proj = Matrix.Identity,
InvProj = Matrix.Identity,
ViewProj = Matrix.Identity,
InvViewProj = Matrix.Identity,
ViewProjTex = Matrix.Identity,
ShadowTransform = Matrix.Identity,
AmbientLight = Vector4.UnitW,
Lights = Light.DefaultArray
};
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
internal struct SsaoConstants
{
private const int OffsetVectorCount = 14;
private const int BlurWeightCount = 3;
public Matrix Proj;
public Matrix InvProj;
public Matrix ProjTex;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = OffsetVectorCount)]
public Vector4[] OffsetVectors;
// For SsaoBlur.hlsl
[MarshalAs(UnmanagedType.ByValArray, SizeConst = BlurWeightCount)]
public Vector4[] BlurWeights;
public Vector2 InvRenderTargetSize;
// Coordinates given in view space.
public float OcclusionRadius;
public float OcclusionFadeStart;
public float OcclusionFadeEnd;
public float SurfaceEpsilon;
public static SsaoConstants Default => new SsaoConstants
{
OcclusionRadius = 0.5f,
OcclusionFadeStart = 0.2f,
OcclusionFadeEnd = 2.0f,
SurfaceEpsilon = 0.05f,
OffsetVectors = new Vector4[OffsetVectorCount],
BlurWeights = new Vector4[BlurWeightCount]
};
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
internal struct MaterialData
{
public Vector4 DiffuseAlbedo;
public Vector3 FresnelR0;
public float Roughness;
// Used in texture mapping.
public Matrix MatTransform;
public int DiffuseMapIndex;
public int NormalMapIndex;
public int MaterialPad0;
public int MaterialPad1;
public static MaterialData Default => new MaterialData
{
DiffuseAlbedo = Vector4.One,
FresnelR0 = new Vector3(0.01f),
Roughness = 0.5f,
MatTransform = Matrix.Identity
};
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
internal struct Vertex
{
public Vector3 Pos;
public Vector3 Normal;
public Vector2 TexC;
public Vector3 TangentU;
}
internal class FrameResource : IDisposable
{
public FrameResource(Device device, int passCount, int objectCount, int materialCount)
{
CmdListAlloc = device.CreateCommandAllocator(CommandListType.Direct);
PassCB = new UploadBuffer<PassConstants>(device, passCount, true);
SsaoCB = new UploadBuffer<SsaoConstants>(device, 1, true);
MaterialBuffer = new UploadBuffer<MaterialData>(device, materialCount, false);
ObjectCB = new UploadBuffer<ObjectConstants>(device, objectCount, true);
}
// We cannot reset the allocator until the GPU is done processing the commands.
// So each frame needs their own allocator.
public CommandAllocator CmdListAlloc { get; }
// We cannot update a cbuffer until the GPU is done processing the commands
// that reference it. So each frame needs their own cbuffers.
public UploadBuffer<PassConstants> PassCB { get; }
public UploadBuffer<ObjectConstants> ObjectCB { get; }
public UploadBuffer<SsaoConstants> SsaoCB { get; }
public UploadBuffer<MaterialData> MaterialBuffer { get; }
// Fence value to mark commands up to this fence point. This lets us
// check if these frame resources are still in use by the GPU.
public long Fence { get; set; }
public void Dispose()
{
MaterialBuffer.Dispose();
SsaoCB.Dispose();
ObjectCB.Dispose();
PassCB.Dispose();
CmdListAlloc.Dispose();
}
}
}