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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
|
#pragma once
#include "DependencyGraph.h"
#include "RDGHandle.h"
#include "RDGNode.h"
#include "Hazel/Renderer/RHI/RHICommandList.h"
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
// #define RDG_DEBUG
/*
RDGNode分为PassNode(RenderPass, ComputePass, RayTracingPass, CopyPass, PresentPass)和ResourceNode(TextureNode, BufferNode)
RDGEdge用于存储 资源->Pass的View,用于在Pass时创建对应的view
*/
namespace GameEngine {
// name->node
class RDGBlackBoard
{
public:
RDGPassNodeRef Pass(std::string name);
RDGBufferNodeRef Buffer(std::string name);
RDGTextureNodeRef Texture(std::string name);
#ifdef RDG_DEBUG
std::string PassName(RDGPassNodeRef pass);
std::string BufferName(RDGBufferNodeRef buffer);
std::string TextureName(RDGTextureNodeRef texture);
#endif
void AddPass(RDGPassNodeRef pass);
void AddBuffer(RDGBufferNodeRef buffer);
void AddTexture(RDGTextureNodeRef texture);
void Clear() { passes.clear(); buffers.clear(); textures.clear(); }
private:
std::unordered_map<std::string, RDGPassNodeRef> passes;
std::unordered_map<std::string, RDGBufferNodeRef> buffers;
std::unordered_map<std::string, RDGTextureNodeRef> textures;
#ifdef RDG_DEBUG
std::unordered_map<RDGPassNodeRef,std::string> passeNames;
std::unordered_map<RDGTextureNodeRef,std::string> textureNames;
std::unordered_map<RDGBufferNodeRef,std::string> bufferNames;
#endif
};
class RDGBuilder
{
public:
RDGBuilder() = default;
RDGBuilder(RHICommandListRef command): command(command){} // 给一个commandList
~RDGBuilder() {};
RDGTextureBuilder CreateTexture(std::string name);
RDGBufferBuilder CreateBuffer(std::string name);
RDGRenderPassBuilder CreateRenderPass(std::string name); // 假定所有pass的添加顺序就是执行顺序,方便处理排序和依赖关系等
RDGComputePassBuilder CreateComputePass(std::string name);
RDGRayTracingPassBuilder CreateRayTracingPass(std::string name);
RDGPresentPassBuilder CreatePresentPass(std::string name);
RDGCopyPassBuilder CreateCopyPass(std::string name);
RDGTextureHandle GetTexture(std::string name);
RDGBufferHandle GetBuffer(std::string name);
RDGRenderPassHandle GetRenderPass(std::string name) { return GetPass<RDGRenderPassNodeRef, RDGRenderPassHandle>(name); }
RDGComputePassHandle GetComputePass(std::string name) { return GetPass<RDGComputePassNodeRef, RDGComputePassHandle>(name); }
RDGRayTracingPassHandle GetRayTracingPass(std::string name) { return GetPass<RDGRayTracingPassNodeRef, RDGRayTracingPassHandle>(name); }
RDGPresentPassHandle GetPresentPass(std::string name) { return GetPass<RDGPresentPassNodeRef, RDGPresentPassHandle>(name); }
RDGCopyPassHandle GetCopyPass(std::string name) { return GetPass<RDGCopyPassNodeRef, RDGCopyPassHandle>(name); }
RHITextureRef GetRHITexture(std::string name) { return blackBoard.Texture(name)->GetRHITexture(); }
DependencyGraphRef GetGraph() { return graph; }
void Execute();
private:
void CreateInputBarriers(RDGPassNodeRef pass);
void CreateOutputBarriers(RDGPassNodeRef pass);
void PrepareDescriptorSet(RDGPassNodeRef pass);
void PrepareRenderTarget(RDGRenderPassNodeRef pass, RHIRenderPassInfo& renderPassInfo);
void ReleaseResource(RDGPassNodeRef pass);
void ExecutePass(RDGRenderPassNodeRef pass);
void ExecutePass(RDGComputePassNodeRef pass);
void ExecutePass(RDGRayTracingPassNodeRef pass);
void ExecutePass(RDGPresentPassNodeRef pass);
void ExecutePass(RDGCopyPassNodeRef pass);
template<typename Type, typename Handle>
Handle GetPass(std::string name)
{
auto node = blackBoard.Pass(name);
if (node == nullptr)
{
LOG_TRACE("Unable to find RDG resource, please check name!");
return Handle(UINT32_MAX);
}
return dynamic_cast<Type>(node)->GetHandle();
}
// Resolve 创建真正的资源
RHITextureRef Resolve(RDGTextureNodeRef textureNode);
RHIBufferRef Resolve(RDGBufferNodeRef bufferNode);
void Release(RDGTextureNodeRef textureNode, RHIResourceState state);
void Release(RDGBufferNodeRef bufferNode, RHIResourceState state);
RHIResourceState PreviousState(RDGTextureNodeRef textureNode, RDGPassNodeRef passNode, TextureSubresourceRange subresource = {}, bool output = false); // 获取当前pass(在执行顺序上)的资源的前序状态
RHIResourceState PreviousState(RDGBufferNodeRef bufferNode, RDGPassNodeRef passNode, uint32_t offset = 0, uint32_t size = 0, bool output = false); // output用于标记是相对于输入还是输出资源
bool IsLastUsedPass(RDGTextureNodeRef textureNode, RDGPassNodeRef passNode, bool output = false);
bool IsLastUsedPass(RDGBufferNodeRef bufferNode, RDGPassNodeRef passNode, bool output = false);
std::vector<RDGPassNodeRef> passes; // 创建的全部pass,按照创建顺序执行
DependencyGraphRef graph = std::make_shared<DependencyGraph>();
RDGBlackBoard blackBoard;
RHICommandListRef command;
};
class RDGTextureBuilder
{
public:
RDGTextureBuilder(RDGBuilder* builder, RDGTextureNodeRef texture)
: builder(builder)
, texture(texture) {
};
RDGTextureBuilder& Import(RHITextureRef texture, RHIResourceState initState);
RDGTextureBuilder& Exetent(Extent3D extent);
RDGTextureBuilder& Format(RHIFormat format);
RDGTextureBuilder& MemoryUsage(MemoryUsage memoryUsage);
RDGTextureBuilder& AllowReadWrite();
RDGTextureBuilder& AllowRenderTarget();
RDGTextureBuilder& AllowDepthStencil();
RDGTextureBuilder& MipLevels(uint32_t mipLevels);
RDGTextureBuilder& ArrayLayers(uint32_t arrayLayers);
RDGTextureBuilder& CubeMap();
RDGTextureHandle Finish() { return texture->GetHandle(); }
private:
RDGBuilder* builder;
RDGTextureNodeRef texture;
};
class RDGBufferBuilder
{
public:
RDGBufferBuilder(RDGBuilder* builder, RDGBufferNodeRef buffer)
: builder(builder)
, buffer(buffer) {
};
RDGBufferBuilder& Import(RHIBufferRef buffer, RHIResourceState initState);
RDGBufferBuilder& Size(uint32_t size);
RDGBufferBuilder& MemoryUsage(MemoryUsage memoryUsage);
RDGBufferBuilder& AllowVertexBuffer();
RDGBufferBuilder& AllowIndexBuffer();
RDGBufferBuilder& AllowReadWrite();
RDGBufferBuilder& AllowRead();
RDGBufferHandle Finish() { return buffer->GetHandle(); }
private:
RDGBuilder* builder;
RDGBufferNodeRef buffer;
};
class RDGRenderPassBuilder
{
public:
RDGRenderPassBuilder(RDGBuilder* builder, RDGRenderPassNodeRef pass)
: builder(builder)
, pass(pass)
, graph(builder->GetGraph()) {
};
RDGRenderPassBuilder& PassIndex(uint32_t x = 0, uint32_t y = 0, uint32_t z = 0); // 给一个index设置函数方便给Execute传参
RDGRenderPassBuilder& RootSignature(RHIRootSignatureRef rootSignature); // 若提供根签名未提供描述符,使用池化创建
RDGRenderPassBuilder& DescriptorSet(uint32_t set, RHIDescriptorSetRef descriptorSet); // 若提供了描述符,直接用相应的描述符
// 创建边 默认View都是2D,如果需要cubeView,需要手动指定
RDGRenderPassBuilder& Read(uint32_t set, uint32_t binding, uint32_t index, RDGBufferHandle buffer, uint32_t offset = 0, uint32_t size = 0);
RDGRenderPassBuilder& Read(uint32_t set, uint32_t binding, uint32_t index, RDGTextureHandle texture, TextureViewType viewType = VIEW_TYPE_2D, TextureSubresourceRange subresource = {});
RDGRenderPassBuilder& ReadWrite(uint32_t set, uint32_t binding, uint32_t index, RDGBufferHandle buffer, uint32_t offset = 0, uint32_t size = 0); // 好像和read也没什么区别?
RDGRenderPassBuilder& ReadWrite(uint32_t set, uint32_t binding, uint32_t index, RDGTextureHandle texture, TextureViewType viewType = VIEW_TYPE_2D, TextureSubresourceRange subresource = {});
RDGRenderPassBuilder& LabelColor(Color3 color);
RDGRenderPassBuilder& Color(uint32_t binding, RDGTextureHandle texture,
AttachmentLoadOp load = ATTACHMENT_LOAD_OP_DONT_CARE,
AttachmentStoreOp store = ATTACHMENT_STORE_OP_DONT_CARE,
Color4 clearColor = { 0.0f, 0.0f, 0.0f, 0.0f },
TextureSubresourceRange subresource = {});
RDGRenderPassBuilder& DepthStencil(RDGTextureHandle texture,
AttachmentLoadOp load = ATTACHMENT_LOAD_OP_DONT_CARE,
AttachmentStoreOp store = ATTACHMENT_STORE_OP_DONT_CARE,
float clearDepth = 1.0f,
uint32_t clearStencil = 0,
TextureSubresourceRange subresource = {});
// 标识后续还会使用的资源,会用PassNode->ResourceNode
RDGRenderPassBuilder& OutputRead(RDGBufferHandle buffer, uint32_t offset = 0, uint32_t size = 0); // 在执行完Pass后作为输出,自动屏障,可能还会在其他地方使用
RDGRenderPassBuilder& OutputRead(RDGTextureHandle texture, TextureSubresourceRange subresource = {});
RDGRenderPassBuilder& OutputReadWrite(RDGBufferHandle buffer, uint32_t offset = 0, uint32_t size = 0);
RDGRenderPassBuilder& OutputReadWrite(RDGTextureHandle texture, TextureSubresourceRange subresource = {});
RDGRenderPassBuilder& Execute(const RDGPassExecuteFunc& execute);
RDGRenderPassHandle Finish() { return pass->GetHandle(); }
private:
RDGBuilder* builder;
RDGRenderPassNodeRef pass;
DependencyGraphRef graph;
};
class RDGComputePassBuilder
{
public:
RDGComputePassBuilder(RDGBuilder* builder, RDGComputePassNodeRef pass)
: builder(builder)
, pass(pass)
, graph(builder->GetGraph()) {
};
RDGComputePassBuilder& PassIndex(uint32_t x = 0, uint32_t y = 0, uint32_t z = 0); // 给一个index设置函数方便给Execute传参
RDGComputePassBuilder& RootSignature(RHIRootSignatureRef rootSignature); // 若提供根签名未提供描述符,使用池化创建
RDGComputePassBuilder& DescriptorSet(uint32_t set, RHIDescriptorSetRef descriptorSet); // 若提供了描述符,直接用相应的描述符
RDGComputePassBuilder& Read(uint32_t set, uint32_t binding, uint32_t index, RDGBufferHandle buffer, uint32_t offset = 0, uint32_t size = 0);
RDGComputePassBuilder& Read(uint32_t set, uint32_t binding, uint32_t index, RDGTextureHandle texture, TextureViewType viewType = VIEW_TYPE_2D, TextureSubresourceRange subresource = {});
RDGComputePassBuilder& ReadWrite(uint32_t set, uint32_t binding, uint32_t index, RDGBufferHandle buffer, uint32_t offset = 0, uint32_t size = 0); // 好像和read也没什么区别?
RDGComputePassBuilder& ReadWrite(uint32_t set, uint32_t binding, uint32_t index, RDGTextureHandle texture, TextureViewType viewType = VIEW_TYPE_2D, TextureSubresourceRange subresource = {});
RDGComputePassBuilder& OutputRead(RDGBufferHandle buffer, uint32_t offset = 0, uint32_t size = 0); // 在执行完Pass后作为输出,自动屏障,可能还会在其他地方使用
RDGComputePassBuilder& OutputRead(RDGTextureHandle texture, TextureSubresourceRange subresource = {});
RDGComputePassBuilder& OutputReadWrite(RDGBufferHandle buffer, uint32_t offset = 0, uint32_t size = 0);
RDGComputePassBuilder& OutputReadWrite(RDGTextureHandle texture, TextureSubresourceRange subresource = {});
RDGComputePassBuilder& OutputIndirectDraw(RDGBufferHandle buffer, uint32_t offset = 0, uint32_t size = 0);
RDGComputePassBuilder& Execute(const RDGPassExecuteFunc& execute);
RDGComputePassHandle Finish() { return pass->GetHandle(); }
private:
RDGBuilder* builder;
RDGComputePassNodeRef pass;
DependencyGraphRef graph;
};
class RDGRayTracingPassBuilder
{
public:
RDGRayTracingPassBuilder(RDGBuilder* builder, RDGRayTracingPassNodeRef pass)
: builder(builder)
, pass(pass)
, graph(builder->GetGraph()) {
};
RDGRayTracingPassBuilder& PassIndex(uint32_t x = 0, uint32_t y = 0, uint32_t z = 0); // 给一个index设置函数方便给Execute传参
RDGRayTracingPassBuilder& RootSignature(RHIRootSignatureRef rootSignature); // 若提供根签名未提供描述符,使用池化创建
RDGRayTracingPassBuilder& DescriptorSet(uint32_t set, RHIDescriptorSetRef descriptorSet); // 若提供了描述符,直接用相应的描述符
RDGRayTracingPassBuilder& Read(uint32_t set, uint32_t binding, uint32_t index, RDGBufferHandle buffer, uint32_t offset = 0, uint32_t size = 0);
RDGRayTracingPassBuilder& Read(uint32_t set, uint32_t binding, uint32_t index, RDGTextureHandle texture, TextureViewType viewType = VIEW_TYPE_2D, TextureSubresourceRange subresource = {});
RDGRayTracingPassBuilder& ReadWrite(uint32_t set, uint32_t binding, uint32_t index, RDGBufferHandle buffer, uint32_t offset = 0, uint32_t size = 0); // 好像和read也没什么区别?
RDGRayTracingPassBuilder& ReadWrite(uint32_t set, uint32_t binding, uint32_t index, RDGTextureHandle texture, TextureViewType viewType = VIEW_TYPE_2D, TextureSubresourceRange subresource = {});
RDGRayTracingPassBuilder& OutputRead(RDGBufferHandle buffer, uint32_t offset = 0, uint32_t size = 0); // 在执行完Pass后作为输出,自动屏障,可能还会在其他地方使用
RDGRayTracingPassBuilder& OutputRead(RDGTextureHandle texture, TextureSubresourceRange subresource = {});
RDGRayTracingPassBuilder& OutputReadWrite(RDGBufferHandle buffer, uint32_t offset = 0, uint32_t size = 0);
RDGRayTracingPassBuilder& OutputReadWrite(RDGTextureHandle texture, TextureSubresourceRange subresource = {});
RDGRayTracingPassBuilder& Execute(const RDGPassExecuteFunc& execute);
RDGRayTracingPassHandle Finish() { return pass->GetHandle(); }
private:
RDGBuilder* builder;
RDGRayTracingPassNodeRef pass;
DependencyGraphRef graph;
};
class RDGPresentPassBuilder
{
public:
RDGPresentPassBuilder(RDGBuilder* builder, RDGPresentPassNodeRef pass)
: builder(builder)
, pass(pass)
, graph(builder->GetGraph()) {
};
RDGPresentPassHandle Finish() { return pass->GetHandle(); }
RDGPresentPassBuilder& Texture(RDGTextureHandle texture, TextureSubresourceLayers subresource = {});
RDGPresentPassBuilder& PresentTexture(RDGTextureHandle texture);
private:
RDGBuilder* builder;
RDGPresentPassNodeRef pass;
DependencyGraphRef graph;
};
class RDGCopyPassBuilder
{
public:
RDGCopyPassBuilder(RDGBuilder* builder, RDGCopyPassNodeRef pass)
: builder(builder)
, pass(pass)
, graph(builder->GetGraph()) {
};
RDGCopyPassHandle Finish() { return pass->GetHandle(); }
RDGCopyPassBuilder& From(RDGTextureHandle texture, TextureSubresourceLayers subresource = {});
RDGCopyPassBuilder& To(RDGTextureHandle texture, TextureSubresourceLayers subresource = {});
RDGCopyPassBuilder& GenerateMips();
RDGCopyPassBuilder& OutputRead(RDGTextureHandle texture, TextureSubresourceLayers subresource = {});
RDGCopyPassBuilder& OutputReadWrite(RDGTextureHandle texture, TextureSubresourceLayers subresource = {});
private:
RDGBuilder* builder;
RDGCopyPassNodeRef pass;
DependencyGraphRef graph;
};
}
|