-
Notifications
You must be signed in to change notification settings - Fork 63
/
Copy pathFrameResource.cs
130 lines (113 loc) · 4.17 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
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 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,
AmbientLight = Vector4.UnitW,
Lights = Light.DefaultArray
};
}
[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 MaterialPad0;
public int MaterialPad1;
public int MaterialPad2;
public static MaterialData Default => new MaterialData
{
DiffuseAlbedo = Vector4.One,
FresnelR0 = new Vector3(0.01f),
Roughness = 64.0f,
MatTransform = Matrix.Identity
};
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
internal struct Vertex
{
public Vector3 Pos;
public Vector3 Normal;
public Vector2 TexC;
}
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);
ObjectCB = new UploadBuffer<ObjectConstants>(device, objectCount, true);
MaterialBuffer = new UploadBuffer<MaterialData>(device, materialCount, false);
}
// 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<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();
ObjectCB.Dispose();
PassCB.Dispose();
CmdListAlloc.Dispose();
}
}
}