Refactor render graph: modular compilation & execution
Major overhaul of render graph system for modularity and performance: - Split compilation and execution logic into dedicated classes (Compiler, Executor, NativePassBuilder, Barriers) - Overhauled barrier system: now uses CompiledBarrier with target state only, querying before state at execution - Resource size/alignment now queried from D3D12 device for accurate heap allocation - ResourceDesc now includes Type field and asserts correct union access - Centralized D3D12 interop logic in D3D12Utility extensions - Added RenderGraphHasher for structural graph hashing and cache invalidation - RenderGraph class simplified to orchestrate specialized components - ResourceAliasingManager now uses allocator for size queries - Compilation cache now stores compiled barriers, reducing memory usage - Improved comments, debug assertions, and removed redundant code Result: more maintainable, efficient, and robust render graph pipeline.
This commit is contained in:
@@ -7,7 +7,7 @@ using static TerraFX.Aliases.DXGI_Alias;
|
||||
|
||||
namespace Ghost.Graphics.D3D12.Utilities;
|
||||
|
||||
internal unsafe static class D3D12Utility
|
||||
internal static unsafe class D3D12Utility
|
||||
{
|
||||
public static void SetName<T>(ref this T obj, ReadOnlySpan<char> name)
|
||||
where T : unmanaged, ID3D12Object.Interface
|
||||
@@ -278,6 +278,102 @@ internal unsafe static class D3D12Utility
|
||||
};
|
||||
}
|
||||
|
||||
public static D3D12_RESOURCE_FLAGS ToD3D12ResourceFlag(this TextureUsage usage)
|
||||
{
|
||||
var flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
|
||||
if (usage.HasFlag(TextureUsage.RenderTarget))
|
||||
{
|
||||
flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||
}
|
||||
|
||||
if (usage.HasFlag(TextureUsage.DepthStencil))
|
||||
{
|
||||
flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
|
||||
}
|
||||
|
||||
if (usage.HasFlag(TextureUsage.UnorderedAccess))
|
||||
{
|
||||
flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
public static D3D12_RESOURCE_DESC ToD3D12ResourceDesc(this in TextureDesc desc)
|
||||
{
|
||||
var dxgiFormat = desc.Format.ToDXGIFormat();
|
||||
var maxDimension = Math.Max(desc.Width, Math.Max(desc.Height, desc.Slice));
|
||||
var mipLevels = desc.MipLevels == 0
|
||||
? (ushort)(1 + Math.Floor(Math.Log2(maxDimension)))
|
||||
: (ushort)desc.MipLevels;
|
||||
|
||||
var resourceFlags = desc.Usage.ToD3D12ResourceFlag();
|
||||
return desc.Dimension switch
|
||||
{
|
||||
TextureDimension.Texture2D => D3D12_RESOURCE_DESC.Tex2D(
|
||||
dxgiFormat,
|
||||
desc.Width,
|
||||
desc.Height,
|
||||
mipLevels: mipLevels,
|
||||
flags: resourceFlags),
|
||||
TextureDimension.Texture3D => D3D12_RESOURCE_DESC.Tex3D(
|
||||
dxgiFormat,
|
||||
desc.Width,
|
||||
desc.Height,
|
||||
(ushort)desc.Slice,
|
||||
flags: resourceFlags),
|
||||
TextureDimension.TextureCube => D3D12_RESOURCE_DESC.Tex2D(
|
||||
dxgiFormat,
|
||||
desc.Width,
|
||||
desc.Height,
|
||||
mipLevels: mipLevels,
|
||||
arraySize: 6,
|
||||
flags: resourceFlags),
|
||||
TextureDimension.Texture2DArray => D3D12_RESOURCE_DESC.Tex2D(
|
||||
dxgiFormat,
|
||||
desc.Width,
|
||||
desc.Height,
|
||||
mipLevels: mipLevels,
|
||||
arraySize: (ushort)desc.Slice,
|
||||
flags: resourceFlags),
|
||||
TextureDimension.TextureCubeArray => D3D12_RESOURCE_DESC.Tex2D(
|
||||
dxgiFormat,
|
||||
desc.Width,
|
||||
desc.Height,
|
||||
mipLevels: mipLevels,
|
||||
arraySize: (ushort)(desc.Slice * 6),
|
||||
flags: resourceFlags),
|
||||
_ => throw new ArgumentException($"Unsupported texture dimension: {desc.Dimension}"),
|
||||
};
|
||||
}
|
||||
|
||||
public static D3D12_RESOURCE_FLAGS ToD3D12ResourceFlag(this BufferUsage usage)
|
||||
{
|
||||
var flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
|
||||
if (usage.HasFlag(BufferUsage.Raw) || usage.HasFlag(BufferUsage.UnorderedAccess))
|
||||
{
|
||||
flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
public static D3D12_RESOURCE_DESC ToD3D12ResourceDesc(this in BufferDesc desc)
|
||||
{
|
||||
var alignedSize = desc.Size;
|
||||
if (desc.Usage.HasFlag(BufferUsage.Constant))
|
||||
{
|
||||
// D3D12 CBV size must be 256-byte aligned
|
||||
alignedSize = (uint)(desc.Size + 255) & ~255u;
|
||||
}
|
||||
|
||||
var resourceFlags = desc.Usage.ToD3D12ResourceFlag();
|
||||
return D3D12_RESOURCE_DESC.Buffer(alignedSize, resourceFlags);
|
||||
}
|
||||
|
||||
|
||||
public static ResourceDesc ToResourceDesc(this D3D12_RESOURCE_DESC desc)
|
||||
{
|
||||
if (desc.Dimension == D3D12_RESOURCE_DIMENSION.D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
|
||||
Reference in New Issue
Block a user