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:
@@ -224,6 +224,22 @@ public struct PassRenderTargetDesc
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies how to load the render target at the start of the render pass.
|
||||
/// </summary>
|
||||
public AttachmentLoadOp LoadOp
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies how to store the render target at the end of the render pass.
|
||||
/// </summary>
|
||||
public AttachmentStoreOp StoreOp
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public struct PassDepthStencilDesc
|
||||
@@ -243,6 +259,38 @@ public struct PassDepthStencilDesc
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies how to load the depth buffer at the start of the render pass.
|
||||
/// </summary>
|
||||
public AttachmentLoadOp DepthLoadOp
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies how to store the depth buffer at the end of the render pass.
|
||||
/// </summary>
|
||||
public AttachmentStoreOp DepthStoreOp
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies how to load the stencil buffer at the start of the render pass.
|
||||
/// </summary>
|
||||
public AttachmentLoadOp StencilLoadOp
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies how to store the stencil buffer at the end of the render pass.
|
||||
/// </summary>
|
||||
public AttachmentStoreOp StencilStoreOp
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -704,7 +752,7 @@ public struct SwapChainTarget
|
||||
{
|
||||
Type = SwapChainTargetType.WindowHandle,
|
||||
WindowHandle = hwnd,
|
||||
CompositionSurface = null
|
||||
CompositionSurface = 0
|
||||
};
|
||||
}
|
||||
|
||||
@@ -878,3 +926,42 @@ public enum ComparisonFunction
|
||||
GreaterEqual,
|
||||
Always
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies how to load attachment contents at the start of a render pass.
|
||||
/// </summary>
|
||||
public enum AttachmentLoadOp
|
||||
{
|
||||
/// <summary>
|
||||
/// Load existing contents from memory. Use when you need to preserve previous data.
|
||||
/// </summary>
|
||||
Load,
|
||||
|
||||
/// <summary>
|
||||
/// Clear the attachment to a specified value. Use when you want to start with a clean slate.
|
||||
/// </summary>
|
||||
Clear,
|
||||
|
||||
/// <summary>
|
||||
/// Don't care about previous contents. Use when you'll overwrite all pixels (fullscreen pass).
|
||||
/// On tile-based deferred renderers (TBDR), this can save significant memory bandwidth.
|
||||
/// </summary>
|
||||
DontCare
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies how to store attachment contents at the end of a render pass.
|
||||
/// </summary>
|
||||
public enum AttachmentStoreOp
|
||||
{
|
||||
/// <summary>
|
||||
/// Store the contents to memory for later use.
|
||||
/// </summary>
|
||||
Store,
|
||||
|
||||
/// <summary>
|
||||
/// Discard the contents (not needed after this pass).
|
||||
/// On tile-based deferred renderers (TBDR), this can save significant memory bandwidth.
|
||||
/// </summary>
|
||||
DontCare
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ public interface ICommandBuffer : IDisposable
|
||||
/// </summary>
|
||||
/// <param name="slot">The vertex buffer slot to bind to.</param>
|
||||
/// <param name="buffer">The handle to the graphics buffer containing vertex data.</param>
|
||||
/// <param name="offset">The offset in bytes from the start of the buffer.</param>
|
||||
/// <param name="offset">The Offset in bytes from the start of the buffer.</param>
|
||||
void SetVertexBuffer(uint slot, Handle<GraphicsBuffer> buffer, ulong offset = 0);
|
||||
|
||||
/// <summary>
|
||||
@@ -126,7 +126,7 @@ public interface ICommandBuffer : IDisposable
|
||||
/// </summary>
|
||||
/// <param name="buffer">The handle to the graphics buffer containing index data.</param>
|
||||
/// <param name="type">The space of indices (e.g., 16-bit or 32-bit).</param>
|
||||
/// <param name="offset">The offset in bytes from the start of the buffer.</param>
|
||||
/// <param name="offset">The Offset in bytes from the start of the buffer.</param>
|
||||
void SetIndexBuffer(Handle<GraphicsBuffer> buffer, IndexType type, ulong offset = 0);
|
||||
|
||||
/// <summary>
|
||||
@@ -140,7 +140,7 @@ public interface ICommandBuffer : IDisposable
|
||||
/// </summary>
|
||||
/// <param name="rootIndex">The zero-based index of the root parameter in the graphics root signature to set the constant for.</param>
|
||||
/// <param name="constantBuffer">A read-only span containing the 32-bit constant values to set.</param>
|
||||
/// <param name="offsetIn32Bits">The offset, in 32-bit values, from the start of the root parameter where the constants will be set.</param>
|
||||
/// <param name="offsetIn32Bits">The Offset, in 32-bit values, from the start of the root parameter where the constants will be set.</param>
|
||||
void SetGraphicsRoot32Constants(uint rootIndex, ReadOnlySpan<uint> constantBuffer, uint offsetIn32Bits = 0);
|
||||
|
||||
/// <summary>
|
||||
@@ -209,8 +209,8 @@ public interface ICommandBuffer : IDisposable
|
||||
/// </summary>
|
||||
/// <param name="dest">The handle to the destination graphics buffer where data will be written. Cannot be null.</param>
|
||||
/// <param name="src">The handle to the source graphics buffer from which data will be read. Cannot be null.</param>
|
||||
/// <param name="destOffset">The byte offset in the destination buffer at which to begin writing. Must be zero or greater.</param>
|
||||
/// <param name="srcOffset">The byte offset in the source buffer at which to begin reading. Must be zero or greater.</param>
|
||||
/// <param name="destOffset">The byte Offset in the destination buffer at which to begin writing. Must be zero or greater.</param>
|
||||
/// <param name="srcOffset">The byte Offset in the source buffer at which to begin reading. Must be zero or greater.</param>
|
||||
/// <param name="numBytes">The number of bytes to copy. If zero, copies the remaining bytes from the source buffer starting at <paramref name="srcOffset"/>.</param>
|
||||
void CopyBuffer(Handle<GraphicsBuffer> dest, Handle<GraphicsBuffer> src, ulong destOffset = 0, ulong srcOffset = 0, ulong numBytes = 0);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ public enum FeatureSupport
|
||||
SamplerFeedback = 1 << 3,
|
||||
BindlessResources = 1 << 4,
|
||||
WorkGraphs = 1 << 5,
|
||||
AliasBuffersAndTextures = 1 << 6,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,32 +1,121 @@
|
||||
using Ghost.Core;
|
||||
using Ghost.Core.Graphics;
|
||||
using Misaki.HighPerformance.LowLevel.Collections;
|
||||
using Ghost.Graphics.Core;
|
||||
using Misaki.HighPerformance.LowLevel.Collections;
|
||||
|
||||
namespace Ghost.Graphics.RHI;
|
||||
|
||||
public enum ResourceAllocationType
|
||||
{
|
||||
Default,
|
||||
Temporary,
|
||||
RenderGraphTransient,
|
||||
}
|
||||
|
||||
public struct CreationOptions
|
||||
{
|
||||
public ResourceAllocationType AllocationType
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public Handle<GPUResource> Heap
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public ulong Offset
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
public enum HeapType
|
||||
{
|
||||
Default,
|
||||
Upload,
|
||||
Readback
|
||||
}
|
||||
|
||||
public enum HeapFlags
|
||||
{
|
||||
None = 0,
|
||||
AllowBuffers,
|
||||
AllowTextures,
|
||||
AllowRTAndDS,
|
||||
AlowBufferAndTexture,
|
||||
}
|
||||
|
||||
public struct AllocationDesc
|
||||
{
|
||||
public ulong Size
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public ulong Alignment
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public HeapType HeapType
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public HeapFlags HeapFlags
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
public interface IResourceAllocator : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Allocates a block of memory on the GPU
|
||||
/// </summary>
|
||||
/// <param name="desc">Allocation description</param>
|
||||
/// <param name="name">Debug name of the allocation</param>
|
||||
/// <returns>An <see cref="Handle{GPUResource}"/> point to the allocated memory</returns>
|
||||
Handle<GPUResource> Allocate(ref readonly AllocationDesc desc, string name);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a texture resource
|
||||
/// </summary>
|
||||
/// <param name="desc">Texture description</param>
|
||||
/// <param name="name">Debug name of the resource</param>
|
||||
/// <param name="options">Additional options of the resource allocation</param>
|
||||
/// <returns>An <see cref="Handle{Texture}"/> point to the resource</returns>
|
||||
Handle<Texture> CreateTexture(ref readonly TextureDesc desc, bool tempResource = false);
|
||||
Handle<Texture> CreateTexture(ref readonly TextureDesc desc, string name, CreationOptions options = default);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a render Target for off-screen rendering
|
||||
/// </summary>
|
||||
/// <param name="desc">Render Target description</param>
|
||||
/// <param name="name">Debug name of the resource</param>
|
||||
/// <param name="options">Additional options of the resource allocation</param>
|
||||
/// <returns>An <see cref="Handle{Texture}"/> point to the resource</returns>
|
||||
Handle<Texture> CreateRenderTarget(ref readonly RenderTargetDesc desc, bool tempResource = false);
|
||||
Handle<Texture> CreateRenderTarget(ref readonly RenderTargetDesc desc, string name, CreationOptions options = default);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a buffer resource
|
||||
/// </summary>
|
||||
/// <param name="desc">Buffer description</param>
|
||||
/// <param name="name">Debug name of the resource</param>
|
||||
/// <param name="options">Additional options of the resource allocation</param>
|
||||
/// <returns>An <see cref="Handle{GraphicsBuffer}"/> point to the resource</returns>
|
||||
Handle<GraphicsBuffer> CreateBuffer(ref readonly BufferDesc desc, bool tempResource = false);
|
||||
Handle<GraphicsBuffer> CreateBuffer(ref readonly BufferDesc desc, string name, CreationOptions options = default);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a temporary upload buffer of the specified size in bytes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method has been optimized for frequent calls during frame updates. It efficiently manages memory to minimize fragmentation and overhead.
|
||||
/// </remarks>
|
||||
/// <param name="sizeInBytes">The size of the upload buffer to create, in bytes.</param>
|
||||
/// <param name="offset">The offset within the upload buffer where the allocation begins.</param>
|
||||
/// <returns>An <see cref="Handle{GraphicsBuffer}"/> pointing to the created upload buffer.</returns>
|
||||
Handle<GraphicsBuffer> CreateTempUploadBuffer(ulong sizeInBytes, out ulong offset);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new sampler object using the specified sampler description.
|
||||
|
||||
@@ -49,7 +49,7 @@ public interface ISwapChain : IDisposable
|
||||
/// <summary>
|
||||
/// Gets all back buffer textures
|
||||
/// </summary>
|
||||
/// <returns>All back buffer textures</returns>
|
||||
/// <returns>AlowBufferAndTexture back buffer textures</returns>
|
||||
ReadOnlySpan<Handle<Texture>> GetBackBuffers();
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user