using Ghost.Graphics.Data; using Win32.Graphics.Direct3D12; using Win32.Graphics.Dxgi.Common; namespace Ghost.Graphics.RenderGraphModule; /// /// Represents different resource access types in the render graph /// public enum ResourceAccessType { Read, Write, ReadWrite } /// /// Resource lifetime within the render graph /// public enum ResourceLifetime { /// /// Resource is created and destroyed within a single frame /// Transient, /// /// Resource is imported from external source (e.g., history buffers, backbuffer) /// External, /// /// Resource persists across multiple frames (exported for next frame) /// Persistent } /// /// Base class for render graph resources /// public abstract class RenderGraphResource { public int FirstPassIndex { get; set; } internal int LastPassIndex { get; set; } public int Id { get; } public string Name { get; set; } public ResourceLifetime Lifetime { get; internal set; } public bool IsImported { get; init; } public bool IsCreated { get; protected set; } protected RenderGraphResource(int id, string name, ResourceLifetime lifetime) { Id = id; Name = name; Lifetime = lifetime; FirstPassIndex = -1; LastPassIndex = -1; } internal abstract void CreateResource(); internal abstract void ReleaseResource(); } /// /// Represents a texture resource in the render graph /// public sealed class RenderGraphTexture : RenderGraphResource { internal TextureHandle Handle { get; set; } internal TextureDescription Description { get; private set; } public RenderGraphTexture(int id, string name, ResourceLifetime lifetime, TextureDescription description) : base(id, name, lifetime) { Description = description; } public RenderGraphTexture(int id, string name, TextureHandle handle, TextureDescription description) : base(id, name, ResourceLifetime.External) { Handle = handle; Description = description; IsImported = true; IsCreated = true; } internal override void CreateResource() { if (IsCreated || IsImported) return; var allocFlags = Lifetime == ResourceLifetime.Transient ? Win32.Graphics.D3D12MemoryAllocator.AllocationFlags.CanAlias : Win32.Graphics.D3D12MemoryAllocator.AllocationFlags.None; Handle = GraphicsPipeline.ResourceAllocator.CreateTexture2D( Description.Width, Description.Height, Description.MipLevels, Description.Format, Description.Flags, allocFlags, Description.InitialState); IsCreated = true; } internal override void ReleaseResource() { if (!IsCreated || IsImported) return; Handle.Dispose(); IsCreated = false; } } /// /// Represents a buffer resource in the render graph /// public sealed class RenderGraphBuffer : RenderGraphResource { internal BufferHandle Handle { get; set; } internal BufferDescription Description { get; private set; } public RenderGraphBuffer(int id, string name, ResourceLifetime lifetime, BufferDescription description) : base(id, name, lifetime) { Description = description; } public RenderGraphBuffer(int id, string name, BufferHandle handle, BufferDescription description) : base(id, name, ResourceLifetime.External) { Handle = handle; Description = description; IsImported = true; IsCreated = true; } internal override void CreateResource() { if (IsCreated || IsImported) return; var allocFlags = Lifetime == ResourceLifetime.Transient ? Win32.Graphics.D3D12MemoryAllocator.AllocationFlags.CanAlias : Win32.Graphics.D3D12MemoryAllocator.AllocationFlags.None; Handle = GraphicsPipeline.ResourceAllocator.CreateBuffer( Description.SizeInBytes, Description.HeapType, Description.Flags, allocFlags, Description.InitialState); IsCreated = true; } internal override void ReleaseResource() { if (!IsCreated || IsImported) return; Handle.Dispose(); IsCreated = false; } } /// /// Texture description for render graph texture creation /// public readonly struct TextureDescription { public readonly uint Width { get; } public readonly uint Height { get; } public readonly ushort MipLevels { get; } public readonly Format Format { get; } public readonly ResourceFlags Flags { get; } public readonly ResourceStates InitialState { get; } public TextureDescription(uint width, uint height, ushort mipLevels = 1, Format format = Format.R8G8B8A8Unorm, ResourceFlags flags = ResourceFlags.None, ResourceStates initialState = ResourceStates.Common) { Width = width; Height = height; MipLevels = mipLevels; Format = format; Flags = flags; InitialState = initialState; } } /// /// Buffer description for render graph buffer creation /// public readonly struct BufferDescription { public readonly uint SizeInBytes { get; } public readonly HeapType HeapType { get; } public readonly ResourceFlags Flags { get; } public readonly ResourceStates InitialState { get; } public BufferDescription(uint sizeInBytes, HeapType heapType = HeapType.Default, ResourceFlags flags = ResourceFlags.None, ResourceStates initialState = ResourceStates.Common) { SizeInBytes = sizeInBytes; HeapType = heapType; Flags = flags; InitialState = initialState; } }