namespace Ghost.Graphics.RenderGraphModule; /// /// Delegate for pass setup function /// public delegate void PassSetupFunction(ref TPassData data, RenderPassBuilder builder) where TPassData : struct; /// /// Delegate for pass execution function /// public delegate void PassExecuteFunction(ref TPassData data, RenderPassContext context) where TPassData : struct; /// /// Base class for render passes in the render graph /// internal abstract class RenderPass { public string Name { get; } public int Index { get; internal set; } public List ResourceAccesses { get; } public List Dependencies { get; } protected RenderPass(string name) { Name = name; ResourceAccesses = new List(); Dependencies = new List(); } public abstract void Setup(RenderPassBuilder builder); public abstract void Execute(RenderPassContext context); } /// /// Typed render pass implementation /// internal sealed class RenderPass : RenderPass where TPassData : struct { private readonly PassSetupFunction _setupFunction; private readonly PassExecuteFunction _executeFunction; private TPassData _passData; public RenderPass(string name, PassSetupFunction setupFunction, PassExecuteFunction executeFunction) : base(name) { _setupFunction = setupFunction; _executeFunction = executeFunction; } public override void Setup(RenderPassBuilder builder) { _setupFunction(ref _passData, builder); ResourceAccesses.AddRange(builder.ResourceAccesses); } public override void Execute(RenderPassContext context) { _executeFunction(ref _passData, context); } public void SetPassData(TPassData passData) { _passData = passData; } } /// /// Builder for creating render passes /// public sealed class RenderPassCreator where TPassData : struct { private readonly RenderGraph _renderGraph; private readonly string _passName; private PassSetupFunction? _setupFunction; private PassExecuteFunction? _executeFunction; internal RenderPassCreator(RenderGraph renderGraph, string passName) { _renderGraph = renderGraph; _passName = passName; } /// /// Set the setup function for the render pass /// public RenderPassCreator Setup(PassSetupFunction setupFunction) { _setupFunction = setupFunction; return this; } /// /// Set the render function for the render pass /// public RenderPassCreator SetRenderFunc(PassExecuteFunction executeFunction) { _executeFunction = executeFunction; return this; } public void Compile() { if (_setupFunction == null) throw new InvalidOperationException($"Setup function not set for pass '{_passName}'"); if (_executeFunction == null) throw new InvalidOperationException($"Execute function not set for pass '{_passName}'"); var pass = new RenderPass(_passName, _setupFunction, _executeFunction); _renderGraph.AddPass(pass); } }