Render Dependency Graph
- "An immediate-mode API which records render commands into a graph data structure to be compiled and executed." Automates error-prone operations; traverses graph to optimize memory usage and parallelize render passes on CPU and GPU.
- Features: async compute fences; transient resources with optimal lifetimes and memory aliasing; split-barrier sub-resource transitions; parallel command list recording; culling unused resources and passes; validation; RDG Insights.
- Converted for deferred and mobile renderers; "All high-level rendering code should be written using RDG".
- Shader parameter structs (BEGIN_SHADER_PARAMETER_STRUCT) generate compile-time reflection metadata (FShaderParametersMetadata) used for RHI binding and RDG dependency derivation. Static uniform buffers bind at pass frequency rather than PSO frequency because Mesh Draw Commands are cached and shared between passes and views.
- FRDGBuilder: CreateTexture/CreateBuffer only allocate descriptors; RHI resources allocated during execution. AddPass(name, params, flags, lambda); Execute compiles and executes. Avoid FRHICommandListImmediate (disqualifies pass from parallel execution). Builder API is single-threaded, one instance at a time; deferred and mobile renderers use one builder per scene render.
- Two timelines: setup (graph built, resource creation, pipeline branching) and execute (pass lambdas, parallel across threads, should be side-effect free).
- GetRHI only inside the pass lambda declaring the resource (validation asserts). Transient vs External (RegisterExternalTexture, QueueTextureExtraction, ConvertToExternal).
- Raster passes: RENDER_TARGET_BINDING_SLOTS; load actions Load/Clear/NoAction; "Tiled rendering hardware requires accurate actions".
- ClearUnusedGraphResources nulls resources not used by the shader permutation.
- Async compute: ERDGPassFlags::AsyncCompute; RDG finds last producer on graphics pipe and inserts fence, joins when first consumed; r.RDG.AsyncCompute.
- Transient allocator: resources with disjoint lifetimes overlap in memory; "significant reduction in the GPU memory watermark over the default resource pool approach"; prior contents will be garbage; r.RDG.TransientAllocator.
- QueueBufferUpload; memory lifetime pitfall (capturing stack objects by reference); AllocObject/AllocPOD linear allocator.
- Profiling scopes: RDG_EVENT_SCOPE (RenderDoc, RDG Insights), RDG_GPU_STAT_SCOPE (stat gpu), RDG_CSV_STAT_EXCLUSIVE_SCOPE.
- Debug: r.RDG.ImmediateMode / -rdgimmediate (all graph optimizations disabled); r.RHICmdBypass; r.RDG.CullPasses, r.RDG.MergeRenderPasses, r.RDG.ParallelExecute, r.RDG.TransientAllocator; validation layer in Debug/Development (compiled out of Test/Shipping); transition logs; vis; RDG Insights via -trace=rdg,defaults.