365 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			365 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								---
							 | 
						|||
| 
								 | 
							
								title: 剖析虚幻渲染体系(11)- RDG
							 | 
						|||
| 
								 | 
							
								date: 2024-02-04 21:42:54
							 | 
						|||
| 
								 | 
							
								excerpt: 
							 | 
						|||
| 
								 | 
							
								tags: 
							 | 
						|||
| 
								 | 
							
								rating: ⭐
							 | 
						|||
| 
								 | 
							
								---
							 | 
						|||
| 
								 | 
							
								# 前言
							 | 
						|||
| 
								 | 
							
								原文地址:https://www.cnblogs.com/timlly/p/15217090.html
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								# 概念
							 | 
						|||
| 
								 | 
							
								- FRDGAllocator:简单的C++对象分配器, 用MemStack分配器追踪和销毁物体。
							 | 
						|||
| 
								 | 
							
								- FComputeShaderUtils
							 | 
						|||
| 
								 | 
							
									- Dispatch():派发ComputeShader到RHI命令列表,携带其参数。
							 | 
						|||
| 
								 | 
							
									- DispatchIndirect():派发非直接的ComputeShader到RHI命令列表,,携带其参数。
							 | 
						|||
| 
								 | 
							
									- AddPass():派发计算着色器到**RenderGraphBuilder**, 携带其参数。
							 | 
						|||
| 
								 | 
							
									- ClearUAV():清理UAV。
							 | 
						|||
| 
								 | 
							
									- AddCopyTexturePass():增加拷贝纹理Pass。
							 | 
						|||
| 
								 | 
							
									- AddCopyToResolveTargetPass():增加拷贝到解析目标的Pass。
							 | 
						|||
| 
								 | 
							
									- AddEnqueueCopyPass():增加回读纹理的Pass。
							 | 
						|||
| 
								 | 
							
									- AddPass():无参数的Pass增加。
							 | 
						|||
| 
								 | 
							
									- AddBeginUAVOverlapPass()/AddEndUAVOverlapPass(): 其它特殊Pass。
							 | 
						|||
| 
								 | 
							
								- FRDGResource:RDG资源并不是直接用RHI资源,而是包裹了RHI资源引用,然后针对不同类型的资源各自封装,且增加了额外的信息。
							 | 
						|||
| 
								 | 
							
									- FRDGUniformBuffer、TRDGUniformBuffer
							 | 
						|||
| 
								 | 
							
									- FRDGParentResource:一种由图跟踪分配生命周期的渲染图资源。可能有引用它的子资源(例如视图)
							 | 
						|||
| 
								 | 
							
									- FRDGView
							 | 
						|||
| 
								 | 
							
									- FRDGBuffer、FRDGBufferSRV、FRDGBufferUAV
							 | 
						|||
| 
								 | 
							
									- FRDGViewableResource:一种由图跟踪分配生命周期的RPGResource。可能有引用它的子资源
							 | 
						|||
| 
								 | 
							
										- FRDGTexture
							 | 
						|||
| 
								 | 
							
									- FRDGView 
							 | 
						|||
| 
								 | 
							
										- FRDGUnorderedAccessView、FRDGTextureUAV
							 | 
						|||
| 
								 | 
							
										- FRDGShaderResourceView、FRDGTextureSRV
							 | 
						|||
| 
								 | 
							
								- FRDGTextureDesc:创建渲染纹理的描述信息。
							 | 
						|||
| 
								 | 
							
								- FRDGPooledTexture:贴图池里的贴图资源。
							 | 
						|||
| 
								 | 
							
								- FRDGPooledBuffer:池化的缓冲区。
							 | 
						|||
| 
								 | 
							
								- FRHITransition:用于表示RHI中挂起的资源转换的**不透明表面材质**数据结构。
							 | 
						|||
| 
								 | 
							
								- FRDGBarrierBatch:RDG屏障批。
							 | 
						|||
| 
								 | 
							
									- FRDGBarrierBatchBegin
							 | 
						|||
| 
								 | 
							
									- FRDGBarrierBatchEnd
							 | 
						|||
| 
								 | 
							
								- FRDGPass
							 | 
						|||
| 
								 | 
							
									- TRDGLambdaPass
							 | 
						|||
| 
								 | 
							
									- FRDGSentinelPass:哨兵Pass,用于开始/结束。
							 | 
						|||
| 
								 | 
							
								- [[#FRDGBuilder]]
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## RDG基础类型
							 | 
						|||
| 
								 | 
							
								```c++
							 | 
						|||
| 
								 | 
							
								enum class ERDGBuilderFlags
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									None = 0,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** Allows the builder to parallelize execution of passes. Without this flag, all passes execute on the render thread. */
							 | 
						|||
| 
								 | 
							
									AllowParallelExecute = 1 << 0
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/** Flags to annotate a pass with when calling AddPass. */
							 | 
						|||
| 
								 | 
							
								enum class ERDGPassFlags : uint16
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									/** Pass doesn't have any inputs or outputs tracked by the graph. This may only be used by the parameterless AddPass function. */
							 | 
						|||
| 
								 | 
							
									None = 0,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** Pass uses rasterization on the graphics pipe. */
							 | 
						|||
| 
								 | 
							
									Raster = 1 << 0,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** Pass uses compute on the graphics pipe. */
							 | 
						|||
| 
								 | 
							
									Compute = 1 << 1,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** Pass uses compute on the async compute pipe. */
							 | 
						|||
| 
								 | 
							
									AsyncCompute = 1 << 2,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** Pass uses copy commands on the graphics pipe. */
							 | 
						|||
| 
								 | 
							
									Copy = 1 << 3,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** Pass (and its producers) will never be culled. Necessary if outputs cannot be tracked by the graph. */
							 | 
						|||
| 
								 | 
							
									NeverCull = 1 << 4,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** Render pass begin / end is skipped and left to the user. Only valid when combined with 'Raster'. Disables render pass merging for the pass. */
							 | 
						|||
| 
								 | 
							
									SkipRenderPass = 1 << 5,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** Pass will never have its render pass merged with other passes. */
							 | 
						|||
| 
								 | 
							
									NeverMerge = 1 << 6,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** Pass will never run off the render thread. */
							 | 
						|||
| 
								 | 
							
									NeverParallel = 1 << 7,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									ParallelTranslate = 1 << 8,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** Pass uses copy commands but writes to a staging resource. */
							 | 
						|||
| 
								 | 
							
									Readback = Copy | NeverCull
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/** Flags to annotate a render graph buffer. */
							 | 
						|||
| 
								 | 
							
								enum class ERDGBufferFlags : uint8
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									None = 0,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** Tag the buffer to survive through frame, that is important for multi GPU alternate frame rendering. */
							 | 
						|||
| 
								 | 
							
									MultiFrame = 1 << 0,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** The buffer is ignored by RDG tracking and will never be transitioned. Use the flag when registering a buffer with no writable GPU flags.
							 | 
						|||
| 
								 | 
							
									 *  Write access is not allowed for the duration of the graph. This flag is intended as an optimization to cull out tracking of read-only
							 | 
						|||
| 
								 | 
							
									 *  buffers that are used frequently throughout the graph. Note that it's the user's responsibility to ensure the resource is in the correct
							 | 
						|||
| 
								 | 
							
									 *  readable state for use with RDG passes, as RDG does not know the exact state of the resource.
							 | 
						|||
| 
								 | 
							
									 */
							 | 
						|||
| 
								 | 
							
									SkipTracking = 1 << 1,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** When set, RDG will perform its first barrier without splitting. Practically, this means the resource is left in its initial state
							 | 
						|||
| 
								 | 
							
									 *  until the first pass it's used within the graph. Without this flag, the resource is split-transitioned at the start of the graph.
							 | 
						|||
| 
								 | 
							
									 */
							 | 
						|||
| 
								 | 
							
									ForceImmediateFirstBarrier = 1 << 2,
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/** Flags to annotate a render graph texture. */
							 | 
						|||
| 
								 | 
							
								enum class ERDGTextureFlags : uint8
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									None = 0,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** Tag the texture to survive through frame, that is important for multi GPU alternate frame rendering. */
							 | 
						|||
| 
								 | 
							
									MultiFrame = 1 << 0,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** The buffer is ignored by RDG tracking and will never be transitioned. Use the flag when registering a buffer with no writable GPU flags.
							 | 
						|||
| 
								 | 
							
									 *  Write access is not allowed for the duration of the graph. This flag is intended as an optimization to cull out tracking of read-only
							 | 
						|||
| 
								 | 
							
									 *  buffers that are used frequently throughout the graph. Note that it's the user's responsibility to ensure the resource is in the correct
							 | 
						|||
| 
								 | 
							
									 *  readable state for use with RDG passes, as RDG does not know the exact state of the resource.
							 | 
						|||
| 
								 | 
							
									 */
							 | 
						|||
| 
								 | 
							
									SkipTracking = 1 << 1,
							 | 
						|||
| 
								 | 
							
									
							 | 
						|||
| 
								 | 
							
									/** When set, RDG will perform its first barrier without splitting. Practically, this means the resource is left in its initial state
							 | 
						|||
| 
								 | 
							
									 *  until the first pass it's used within the graph. Without this flag, the resource is split-transitioned at the start of the graph.
							 | 
						|||
| 
								 | 
							
									 */
							 | 
						|||
| 
								 | 
							
									ForceImmediateFirstBarrier = 1 << 2,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** Prevents metadata decompression on this texture. */
							 | 
						|||
| 
								 | 
							
									MaintainCompression = 1 << 3,
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								ENUM_CLASS_FLAGS(ERDGTextureFlags);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/** Flags to annotate a view with when calling CreateUAV. */
							 | 
						|||
| 
								 | 
							
								enum class ERDGUnorderedAccessViewFlags : uint8
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									None = 0,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									// The view will not perform UAV barriers between consecutive usage.
							 | 
						|||
| 
								 | 
							
									SkipBarrier = 1 << 0
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								ENUM_CLASS_FLAGS(ERDGUnorderedAccessViewFlags);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/** The set of concrete parent resource types. */
							 | 
						|||
| 
								 | 
							
								enum class ERDGViewableResourceType : uint8
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									Texture,
							 | 
						|||
| 
								 | 
							
									Buffer,
							 | 
						|||
| 
								 | 
							
									MAX
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/** The set of concrete view types. */
							 | 
						|||
| 
								 | 
							
								enum class ERDGViewType : uint8
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									TextureUAV,
							 | 
						|||
| 
								 | 
							
									TextureSRV,
							 | 
						|||
| 
								 | 
							
									BufferUAV,
							 | 
						|||
| 
								 | 
							
									BufferSRV,
							 | 
						|||
| 
								 | 
							
									MAX
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								inline ERDGViewableResourceType GetParentType(ERDGViewType ViewType)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									switch (ViewType)
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
									case ERDGViewType::TextureUAV:
							 | 
						|||
| 
								 | 
							
									case ERDGViewType::TextureSRV:
							 | 
						|||
| 
								 | 
							
										return ERDGViewableResourceType::Texture;
							 | 
						|||
| 
								 | 
							
									case ERDGViewType::BufferUAV:
							 | 
						|||
| 
								 | 
							
									case ERDGViewType::BufferSRV:
							 | 
						|||
| 
								 | 
							
										return ERDGViewableResourceType::Buffer;
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
									checkNoEntry();
							 | 
						|||
| 
								 | 
							
									return ERDGViewableResourceType::MAX;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								enum class ERDGResourceExtractionFlags : uint8
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									None = 0,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									// Allows the resource to remain transient. Only use this flag if you intend to register the resource back
							 | 
						|||
| 
								 | 
							
									// into the graph and release the reference. This should not be used if the resource is cached for a long
							 | 
						|||
| 
								 | 
							
									// period of time.
							 | 
						|||
| 
								 | 
							
									AllowTransient = 1,
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								enum class ERDGInitialDataFlags : uint8
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									/** Specifies the default behavior, which is to make a copy of the initial data for replay when
							 | 
						|||
| 
								 | 
							
									 *  the graph is executed. The user does not need to preserve lifetime of the data pointer.
							 | 
						|||
| 
								 | 
							
									 */
							 | 
						|||
| 
								 | 
							
									None = 0,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									/** Specifies that the user will maintain ownership of the data until the graph is executed. The
							 | 
						|||
| 
								 | 
							
									 *  upload pass will only use a reference to store the data. Use caution with this flag since graph
							 | 
						|||
| 
								 | 
							
									 *  execution is deferred! Useful to avoid the copy if the initial data lifetime is guaranteed to
							 | 
						|||
| 
								 | 
							
									 *  outlive the graph.
							 | 
						|||
| 
								 | 
							
									 */
							 | 
						|||
| 
								 | 
							
									 NoCopy = 1 << 0
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								enum class ERDGPooledBufferAlignment : uint8
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									// The buffer size is not aligned.
							 | 
						|||
| 
								 | 
							
									None,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									// The buffer size is aligned up to the next page size.
							 | 
						|||
| 
								 | 
							
									Page,
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
									// The buffer size is aligned up to the next power of two.
							 | 
						|||
| 
								 | 
							
									PowerOfTwo
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/** Returns the equivalent parent resource type for a view type. */
							 | 
						|||
| 
								 | 
							
								inline ERDGViewableResourceType GetViewableResourceType(ERDGViewType ViewType)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									switch (ViewType)
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
									case ERDGViewType::TextureUAV:
							 | 
						|||
| 
								 | 
							
									case ERDGViewType::TextureSRV:
							 | 
						|||
| 
								 | 
							
										return ERDGViewableResourceType::Texture;
							 | 
						|||
| 
								 | 
							
									case ERDGViewType::BufferUAV:
							 | 
						|||
| 
								 | 
							
									case ERDGViewType::BufferSRV:
							 | 
						|||
| 
								 | 
							
										return ERDGViewableResourceType::Buffer;
							 | 
						|||
| 
								 | 
							
									default:
							 | 
						|||
| 
								 | 
							
										checkNoEntry();
							 | 
						|||
| 
								 | 
							
										return ERDGViewableResourceType::MAX;
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								using ERDGTextureMetaDataAccess = ERHITextureMetaDataAccess;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								/** Returns the associated FRHITransitionInfo plane index. */
							 | 
						|||
| 
								 | 
							
								inline int32 GetResourceTransitionPlaneForMetadataAccess(ERDGTextureMetaDataAccess Metadata)
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
									switch (Metadata)
							 | 
						|||
| 
								 | 
							
									{
							 | 
						|||
| 
								 | 
							
									case ERDGTextureMetaDataAccess::CompressedSurface:
							 | 
						|||
| 
								 | 
							
									case ERDGTextureMetaDataAccess::HTile:
							 | 
						|||
| 
								 | 
							
									case ERDGTextureMetaDataAccess::Depth:
							 | 
						|||
| 
								 | 
							
										return FRHITransitionInfo::kDepthPlaneSlice;
							 | 
						|||
| 
								 | 
							
									case ERDGTextureMetaDataAccess::Stencil:
							 | 
						|||
| 
								 | 
							
										return FRHITransitionInfo::kStencilPlaneSlice;
							 | 
						|||
| 
								 | 
							
									default:
							 | 
						|||
| 
								 | 
							
										return 0;
							 | 
						|||
| 
								 | 
							
									}
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## FRDGBuilder
							 | 
						|||
| 
								 | 
							
								FRDGBuilder是RDG体系的心脏和发动机,也是个大管家,负责收集渲染Pass和参数,编译Pass、数据,处理资源依赖,裁剪和优化各类数据,还有提供执行接口。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								重要函数:
							 | 
						|||
| 
								 | 
							
								- FindExternalTexture():查找外部纹理, 若找不到返回null.
							 | 
						|||
| 
								 | 
							
								- RegisterExternalTexture():注册外部池内RT到RDG, 以便RDG追踪之. 池内RT可能包含两种RHI纹理: MSAA和非MSAA。
							 | 
						|||
| 
								 | 
							
								- RegisterExternalBuffer():注册外部缓冲区到RDG, 以便RDG追踪之.
							 | 
						|||
| 
								 | 
							
								- 资源创建接口:
							 | 
						|||
| 
								 | 
							
									- CreateTexture()
							 | 
						|||
| 
								 | 
							
									- CreateBuffer()
							 | 
						|||
| 
								 | 
							
									- CreateUAV()
							 | 
						|||
| 
								 | 
							
									- CreateSRV()
							 | 
						|||
| 
								 | 
							
									- CreateUniformBuffer()
							 | 
						|||
| 
								 | 
							
								- 分配内存, 内存由RDG管理生命周期。
							 | 
						|||
| 
								 | 
							
									- Alloc()
							 | 
						|||
| 
								 | 
							
									- AllocPOD()
							 | 
						|||
| 
								 | 
							
									- AllocObject()
							 | 
						|||
| 
								 | 
							
									- AllocParameters()
							 | 
						|||
| 
								 | 
							
								- AddPass()
							 | 
						|||
| 
								 | 
							
									- FRDGPassRef AddPass(FRDGEventName&& Name, const ParameterStructType* ParameterStruct, ERDGPassFlags Flags, ExecuteLambdaType&& ExecuteLambda);  :增加有参数的LambdaPass。
							 | 
						|||
| 
								 | 
							
									- FRDGPassRef AddPass(FRDGEventName&& Name, const FShaderParametersMetadata* ParametersMetadata, const void* ParameterStruct, ERDGPassFlags Flags, ExecuteLambdaType&& ExecuteLambda);  :增加带有实时生成结构体的LambdaPass
							 | 
						|||
| 
								 | 
							
									- FRDGPassRef AddPass(FRDGEventName&& Name, ERDGPassFlags Flags, ExecuteLambdaType&& ExecuteLambda);:增加没有参数的LambdaPass
							 | 
						|||
| 
								 | 
							
								- QueueTextureExtraction():在Builder执行末期, 提取池内纹理到指定的指针. 对于RDG创建的资源, 这将延长GPU资源的生命周期,直到执行,指针被填充. 如果指定,纹理将转换为AccessFinal状态, 否则将转换为kDefaultAccessFinal状态。
							 | 
						|||
| 
								 | 
							
								- QueueBufferExtraction():在Builder执行末期, 提取缓冲区到指定的指针。
							 | 
						|||
| 
								 | 
							
								- PreallocateTexture()/PreallocateBuffer():预分配资源. 只对RDG创建的资源, 会强制立即分配底层池内资源, 有效地将其推广到外部资源. 这将增加内存压力,但允许使用GetPooled{Texture, Buffer}查询池中的资源. 主要用于增量地将代码移植到RDG.
							 | 
						|||
| 
								 | 
							
								- GetPooledTexture()/GetPooledBuffer():立即获取底层资源, 只允许用于注册或预分配的资源。
							 | 
						|||
| 
								 | 
							
								- SetTextureAccessFinal()/SetBufferAccessFinal():设置执行之后的状态。
							 | 
						|||
| 
								 | 
							
								- 变量
							 | 
						|||
| 
								 | 
							
									- RDG对象注册表 
							 | 
						|||
| 
								 | 
							
										- FRDGPassRegistry Passes;
							 | 
						|||
| 
								 | 
							
										- FRDGTextureRegistry Textures; 
							 | 
						|||
| 
								 | 
							
										- FRDGBufferRegistry Buffers; 
							 | 
						|||
| 
								 | 
							
										- FRDGViewRegistry Views; 
							 | 
						|||
| 
								 | 
							
										- FRDGUniformBufferRegistry UniformBuffers;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### FRDGBuilder::Compile
							 | 
						|||
| 
								 | 
							
								RDG编译期间的逻辑非常复杂,步骤繁多,先后经历构建生产者和消费者的依赖关系,确定Pass的裁剪等各类标记,调整资源的生命周期,裁剪Pass,处理Pass的资源转换和屏障,处理异步计算Pass的依赖和引用关系,查找并建立分叉和合并Pass节点,合并所有具体相同渲染目标的光栅化Pass等步骤。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								# RDG开发
							 | 
						|||
| 
								 | 
							
								### 注册外部资源
							 | 
						|||
| 
								 | 
							
								如果我们已有非RDG创建的资源,可以在RDG使用么?答案是可以,通过FRDGBuilder::RegisterExternalXXX接口可以完成将外部资源注册到RDG系统中。下面以注册纹理为例:
							 | 
						|||
| 
								 | 
							
								```c++
							 | 
						|||
| 
								 | 
							
								// 在RDG外创建RHI资源.
							 | 
						|||
| 
								 | 
							
								FRHIResourceCreateInfo CreateInfo;
							 | 
						|||
| 
								 | 
							
								FTexture2DRHIRef MyRHITexture = RHICreateTexture2D(1024, 768, PF_B8G8R8A8, 1, 1, TexCreate_CPUReadback, CreateInfo);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 将外部创建的RHI资源注册成RDG资源.
							 | 
						|||
| 
								 | 
							
								FRDGTextureRef MyExternalRDGTexture = GraphBuilder.RegisterExternalTexture(MyRHITexture);
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								需要注意的是,外部注册的资源,RDG无法控制和管理其生命周期,需要保证RDG使用期间外部资源的生命周期处于正常状态,否则将引发异常甚至程序崩溃。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								如果想从RDG资源获取RHI资源的实例,以下代码可达成:
							 | 
						|||
| 
								 | 
							
								```c++
							 | 
						|||
| 
								 | 
							
								FRHITexture* MyRHITexture = MyRDGTexture.GetRHI();
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								用图例展示RHI资源和RDG资源之间的转换关系:
							 | 
						|||
| 
								 | 
							
								- FRHIResource =>FRDGBuilder::RegisterExternalXXX =>FRDGResource
							 | 
						|||
| 
								 | 
							
								- FRDGResource => FRDGResource::GetRHI => FRHIResource
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								### 提取资源
							 | 
						|||
| 
								 | 
							
								RDG收集Pass之后并非立即执行,而是延迟执行(包括资源被延迟创建或分配),这就导致了一个问题:如果想将渲染后的资源赋值给某个变量,无法使用立即模式,需要适配延迟执行模式。这种适配延迟执行的资源提取是通过以下接口来实现的:
							 | 
						|||
| 
								 | 
							
								- FRDGBuilder::QueueTextureExtraction
							 | 
						|||
| 
								 | 
							
								- FRDGBuilder::QueueBufferExtraction
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```c++
							 | 
						|||
| 
								 | 
							
								// 创建RDG纹理.
							 | 
						|||
| 
								 | 
							
								FRDGTextureRef MyRDGTexture;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								FRDGTextureDesc MyTextureDesc = FRDGTextureDesc::Create2D(OutputExtent, HistoryPixelFormat, FClearValueBinding::Black, TexCreate_ShaderResource | TexCreate_UAV);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								MyRDGTexture = GraphBuilder.CreateTexture(MyTextureDesc, "MyRDGTexture", ERDGTextureFlags::MultiFrame);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 创建UAV并作为Pass的shader参数.
							 | 
						|||
| 
								 | 
							
								(......)
							 | 
						|||
| 
								 | 
							
								PassParameters->MyRDGTextureUAV = GraphBuilder.CreateUAV(MyRDGTexture);
							 | 
						|||
| 
								 | 
							
								(......)
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 增加Pass, 以便渲染图像到MyRDGTextureUAV.
							 | 
						|||
| 
								 | 
							
								FComputeShaderUtils::AddPass(GraphBuilder, RDG_EVENT_NAME("MyCustomPass", ...), ComputeShader, PassParameters, FComputeShaderUtils::GetGroupCount(8, 8));
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 入队提取资源.
							 | 
						|||
| 
								 | 
							
								TRefCountPtr<IPooledRenderTarget>* OutputRT;
							 | 
						|||
| 
								 | 
							
								GraphBuilder.QueueTextureExtraction(MyRDGTexture, &OutputRT);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								// 对提取的OutputRT进行后续操作.
							 | 
						|||
| 
								 | 
							
								(......)
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								# RDG调试
							 | 
						|||
| 
								 | 
							
								RDG系统存在一些控制台命令,其名称和描述如下:
							 | 
						|||
| 
								 | 
							
								|控制台变量|描述|
							 | 
						|||
| 
								 | 
							
								|---|---|
							 | 
						|||
| 
								 | 
							
								|**r.RDG.AsyncCompute**|控制异步计算策略:0-禁用;1-为异步计算Pass启用标记(默认);2-开启所有使用compute命令列表的计算通道。|
							 | 
						|||
| 
								 | 
							
								|**r.RDG.Breakpoint**|当满足某些条件时,断点到调试器的断点位置。0-禁用,1~4-不同的特殊调试模式。|
							 | 
						|||
| 
								 | 
							
								|**r.RDG.ClobberResources**|在分配时间用指定的清理颜色清除所有渲染目标和纹理/缓冲UAV。用于调试。|
							 | 
						|||
| 
								 | 
							
								|**r.RDG.CullPasses**|RDG是否开启裁剪无用的Pass。0-禁用,1-开启(默认)。|
							 | 
						|||
| 
								 | 
							
								|**r.RDG.Debug**|允许输出在连接和执行过程中发现的效率低下的警告。|
							 | 
						|||
| 
								 | 
							
								|**r.RDG.Debug.FlushGPU**|开启每次Pass执行后刷新指令到GPU。当设置(r.RDG.AsyncCompute=0)时禁用异步计算。|
							 | 
						|||
| 
								 | 
							
								|**r.RDG.Debug.GraphFilter**|将某些调试事件过滤到特定的图中。|
							 | 
						|||
| 
								 | 
							
								|**r.RDG.Debug.PassFilter**|将某些调试事件过滤到特定的Pass。|
							 | 
						|||
| 
								 | 
							
								|**r.RDG.Debug.ResourceFilter**|将某些调试事件过滤到特定的资源。|
							 | 
						|||
| 
								 | 
							
								|**r.RDG.DumpGraph**|将多个可视化日志转储到磁盘。0-禁用,1-显示生产者、消费者Pass依赖,2-显示资源状态和转换,3-显示图形、异步计算的重叠。|
							 | 
						|||
| 
								 | 
							
								|**r.RDG.ExtendResourceLifetimes**|RDG将把资源生命周期扩展到图的全部长度。会增加内存的占用。|
							 | 
						|||
| 
								 | 
							
								|**r.RDG.ImmediateMode**|在创建Pass时执行Pass。当在Pass的Lambda中崩溃时,连接代码的调用堆栈非常有用。|
							 | 
						|||
| 
								 | 
							
								|**r.RDG.MergeRenderPasses**|图形将合并相同的、连续的渲染通道到一个单一的渲染通道。0-禁用,1-开启(默认)。|
							 | 
						|||
| 
								 | 
							
								|**r.RDG.OverlapUAVs**|RDG将在需要时重叠UAV的工作。如果禁用,UAV屏障总是插入。|
							 | 
						|||
| 
								 | 
							
								|**r.RDG.TransitionLog**|输出资源转换到控制台。|
							 | 
						|||
| 
								 | 
							
								|**r.RDG.VerboseCSVStats**|控制RDG的CSV分析统计的详细程度。0-为图形执行生成一个CSV配置文件,1-为图形执行的每个阶段生成一个CSV文件。|
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								除了以上列出的RDG控制台,还有一些命令可以显示RDG系统运行过程中的有用信息。
							 | 
						|||
| 
								 | 
							
								`vis`列出所有有效的纹理,输入之后可能显示如下所示的信息:
							 |