Render graph: native pass merging & heap-based aliasing
Major architecture upgrade: - Add native render pass merging (hardware pass grouping, load/store op inference) - Implement heap-based aliasing for textures & buffers (D3D12-style) - Unify resource model: buffers and textures in one registry - Extend builder API for buffer creation/usage, access flags, hints - Improve barrier/state tracking (buffer hints, indirect argument state) - Update caching, hashing, and debug output for new model - Add enums/structs: AttachmentLoadOp, StoreOp, BufferHint, etc. - D3D12 backend: support named resources, temp upload buffers, correct heap usage - Update docs, benchmarks, and project files for new features Brings render graph closer to AAA engine standards, enabling efficient memory usage, lower driver overhead, and a more flexible API.
This commit is contained in:
@@ -4,11 +4,14 @@ using System.Diagnostics;
|
||||
namespace Ghost.RenderGraph.Concept;
|
||||
|
||||
[Flags]
|
||||
public enum AccessFlags
|
||||
public enum AccessFlags : byte
|
||||
{
|
||||
None = 0,
|
||||
Read = 1 << 0,
|
||||
Write = 1 << 1,
|
||||
Discard = 1 << 2,
|
||||
|
||||
WriteAll = Write | Discard,
|
||||
ReadWrite = Read | Write,
|
||||
}
|
||||
|
||||
@@ -26,6 +29,13 @@ public interface IRenderGraphBuilder : IDisposable
|
||||
/// <param name="descriptor">A structure that defines the properties and configuration of the texture to create.</param>
|
||||
/// <returns>An identifier for the newly created texture resource.</returns>
|
||||
Identifier<RGTexture> CreateTexture(in TextureDescriptor descriptor);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new buffer resource based on the specified descriptor.
|
||||
/// </summary>
|
||||
/// <param name="descriptor">A structure that defines the properties and configuration of the buffer to create.</param>
|
||||
/// <returns>An identifier for the newly created buffer resource.</returns>
|
||||
Identifier<RGBuffer> CreateBuffer(in BufferDescriptor descriptor);
|
||||
|
||||
/// <summary>
|
||||
/// Registers the specified texture for use in the current render graph pass with the given access mode.
|
||||
@@ -34,6 +44,15 @@ public interface IRenderGraphBuilder : IDisposable
|
||||
/// <param name="accessMode">The access mode specifying how the texture will be read or written during the pass.</param>
|
||||
/// <returns>An identifier for the texture.</returns>
|
||||
Identifier<RGTexture> UseTexture(Identifier<RGTexture> texture, AccessFlags accessMode);
|
||||
|
||||
/// <summary>
|
||||
/// Registers the specified buffer for use in the current render graph pass with the given access mode.
|
||||
/// </summary>
|
||||
/// <param name="buffer">The identifier of the buffer to be used in the render graph pass.</param>
|
||||
/// <param name="accessMode">The access mode specifying how the buffer will be read or written during the pass.</param>
|
||||
/// <param name="hint">Optional hint about how the buffer will be used (e.g., IndirectArgument). Default is None (ByteAddressBuffer SRV).</param>
|
||||
/// <returns>An identifier for the buffer.</returns>
|
||||
Identifier<RGBuffer> UseBuffer(Identifier<RGBuffer> buffer, AccessFlags accessMode, BufferHint hint = BufferHint.None);
|
||||
}
|
||||
|
||||
public interface IRasterRenderGraphBuilder : IRenderGraphBuilder
|
||||
@@ -56,13 +75,15 @@ public interface IRasterRenderGraphBuilder : IRenderGraphBuilder
|
||||
/// </summary>
|
||||
/// <param name="texture">The identifier of the texture to use as the color attachment.</param>
|
||||
/// <param name="index">The zero-based index of the color attachment to set.</param>
|
||||
void SetColorAttachment(Identifier<RGTexture> texture, int index);
|
||||
/// <param name="flags">Access flags. Default is Write (assumes partial update). Use WriteAll for fullscreen passes.</param>
|
||||
void SetColorAttachment(Identifier<RGTexture> texture, int index, AccessFlags flags = AccessFlags.Write);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the depth attachment for the current render pass using the specified texture.
|
||||
/// </summary>
|
||||
/// <param name="texture">The identifier of the texture to use as the depth attachment. Cannot be null.</param>
|
||||
void SetDepthAttachment(Identifier<RGTexture> texture);
|
||||
/// <param name="flags">Access flags. Default is ReadWrite (assumes partial update). Use WriteAll for fullscreen passes.</param>
|
||||
void SetDepthAttachment(Identifier<RGTexture> texture, AccessFlags flags = AccessFlags.ReadWrite);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the function used to render a pass with the specified pass data and render context.
|
||||
@@ -146,12 +167,35 @@ internal class RenderGraphBuilder : IRasterRenderGraphBuilder, IComputeRenderGra
|
||||
_resources.SetProducer(handle.AsResource(), _pass.index);
|
||||
return handle;
|
||||
}
|
||||
|
||||
public Identifier<RGBuffer> CreateBuffer(in BufferDescriptor descriptor)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
|
||||
var handle = _resources.CreateBuffer(descriptor);
|
||||
_pass.resourceCreates[(int)RenderGraphResourceType.Buffer].Add(handle.AsResource());
|
||||
_resources.SetProducer(handle.AsResource(), _pass.index);
|
||||
return handle;
|
||||
}
|
||||
|
||||
public Identifier<RGTexture> UseTexture(Identifier<RGTexture> texture, AccessFlags flags)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
return UseResource(texture.AsResource(), flags, RenderGraphResourceType.Texture).AsTexture();
|
||||
}
|
||||
|
||||
public Identifier<RGBuffer> UseBuffer(Identifier<RGBuffer> buffer, AccessFlags flags, BufferHint hint = BufferHint.None)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
|
||||
// Store buffer hint if not None
|
||||
if (hint != BufferHint.None)
|
||||
{
|
||||
_pass.bufferHints[buffer.AsResource().Value] = hint;
|
||||
}
|
||||
|
||||
return UseResource(buffer.AsResource(), flags, RenderGraphResourceType.Buffer).AsBuffer();
|
||||
}
|
||||
|
||||
public Identifier<RGTexture> UseRandomAccessTexture(Identifier<RGTexture> texture)
|
||||
{
|
||||
@@ -173,17 +217,17 @@ internal class RenderGraphBuilder : IRasterRenderGraphBuilder, IComputeRenderGra
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public void SetColorAttachment(Identifier<RGTexture> texture, int index)
|
||||
public void SetColorAttachment(Identifier<RGTexture> texture, int index, AccessFlags flags = AccessFlags.Write)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
|
||||
Debug.Assert(index >= 0 && index < _pass.colorAccess.Length, "Color attachment index out of range.");
|
||||
|
||||
var id = UseTexture(texture, AccessFlags.Write);
|
||||
var id = UseTexture(texture, flags);
|
||||
if (_pass.colorAccess[index].id == id || _pass.colorAccess[index].id.IsInvalid)
|
||||
{
|
||||
_pass.maxColorIndex = Math.Max(_pass.maxColorIndex, index);
|
||||
_pass.colorAccess[index] = new TextureAccess(id, AccessFlags.Write);
|
||||
_pass.colorAccess[index] = new TextureAccess(id, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -191,14 +235,14 @@ internal class RenderGraphBuilder : IRasterRenderGraphBuilder, IComputeRenderGra
|
||||
}
|
||||
}
|
||||
|
||||
public void SetDepthAttachment(Identifier<RGTexture> texture)
|
||||
public void SetDepthAttachment(Identifier<RGTexture> texture, AccessFlags flags = AccessFlags.Write)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
|
||||
var id = UseTexture(texture, AccessFlags.Write);
|
||||
var id = UseTexture(texture, flags);
|
||||
if (_pass.depthAccess.id == id || _pass.depthAccess.id.IsInvalid)
|
||||
{
|
||||
_pass.depthAccess = new TextureAccess(id, AccessFlags.Write);
|
||||
_pass.depthAccess = new TextureAccess(id, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user