From 498a3285fdc9c5d8de4927165e3339f088c92749 Mon Sep 17 00:00:00 2001 From: U2A5F Date: Mon, 24 Feb 2025 16:11:58 +0800 Subject: [PATCH 01/23] save --- Coplt.Graphics.Core/Core/BufferRange.cs | 2 +- Coplt.Graphics.Core/Core/CommandList.cs | 18 +-- Coplt.Graphics.Core/Core/GpuBuffer.cs | 12 +- Coplt.Graphics.Core/Core/GpuOutput.cs | 6 +- Coplt.Graphics.Core/Core/GpuQueue.cs | 10 +- Coplt.Graphics.Core/Core/GpuResource.cs | 42 +----- Coplt.Graphics.Core/Core/GpuView.cs | 81 ++++++++++++ Coplt.Graphics.Core/Core/ResourceEnums.cs | 23 ---- Coplt.Graphics.Core/Core/Views.cs | 37 ++++-- Coplt.Graphics.Core/Native/Native.cs | 123 +++++++++++++----- Coplt.Graphics.Native/Api/FFI/Resource.h | 56 +++++--- Coplt.Graphics.Native/D3d12/Src/Buffer.cc | 14 +- Coplt.Graphics.sln | 2 +- Examples/{RotatingCube => Colorful}/App.xaml | 0 .../{RotatingCube => Colorful}/App.xaml.cs | 0 .../AssemblyInfo.cs | 0 .../Colorful.csproj} | 0 Examples/Colorful/Example.cs | 43 ++++++ .../MainWindow.xaml | 0 .../MainWindow.xaml.cs | 0 .../Properties/launchSettings.json | 0 Examples/Colorful/Shaders/Shader.hlsl | 31 +++++ Examples/ExampleBase/ExampleBase.cs | 21 ++- Examples/ExampleBase/Time.cs | 7 + Examples/HelloTriangle/Example.cs | 2 +- Examples/HelloTriangleVertex/Example.cs | 2 +- Examples/RotatingCube/Example.cs | 54 -------- Examples/RotatingCube/Shaders/Shader.hlsl | 27 ---- 28 files changed, 373 insertions(+), 240 deletions(-) create mode 100644 Coplt.Graphics.Core/Core/GpuView.cs rename Examples/{RotatingCube => Colorful}/App.xaml (100%) rename Examples/{RotatingCube => Colorful}/App.xaml.cs (100%) rename Examples/{RotatingCube => Colorful}/AssemblyInfo.cs (100%) rename Examples/{RotatingCube/RotatingCube.csproj => Colorful/Colorful.csproj} (100%) create mode 100644 Examples/Colorful/Example.cs rename Examples/{RotatingCube => Colorful}/MainWindow.xaml (100%) rename Examples/{RotatingCube => Colorful}/MainWindow.xaml.cs (100%) rename Examples/{RotatingCube => Colorful}/Properties/launchSettings.json (100%) create mode 100644 Examples/Colorful/Shaders/Shader.hlsl create mode 100644 Examples/ExampleBase/Time.cs delete mode 100644 Examples/RotatingCube/Example.cs delete mode 100644 Examples/RotatingCube/Shaders/Shader.hlsl diff --git a/Coplt.Graphics.Core/Core/BufferRange.cs b/Coplt.Graphics.Core/Core/BufferRange.cs index c095976..9575e5f 100644 --- a/Coplt.Graphics.Core/Core/BufferRange.cs +++ b/Coplt.Graphics.Core/Core/BufferRange.cs @@ -1,4 +1,4 @@ namespace Coplt.Graphics.Core; public record struct BufferRange(T Buffer, uint Offset = 0, uint Size = uint.MaxValue); -public record struct VertexBufferRange(uint Index, IVbv Buffer, uint Offset = 0, uint Size = uint.MaxValue); +public record struct VertexBufferRange(uint Index, IVbvRes Buffer, uint Offset = 0, uint Size = uint.MaxValue); diff --git a/Coplt.Graphics.Core/Core/CommandList.cs b/Coplt.Graphics.Core/Core/CommandList.cs index f164ab7..7f37469 100644 --- a/Coplt.Graphics.Core/Core/CommandList.cs +++ b/Coplt.Graphics.Core/Core/CommandList.cs @@ -64,7 +64,7 @@ internal void Reset() #region AddResource - private int AddResource(T resource) where T : IView + private int AddResource(T resource) where T : IGpuResource { if (resource.Queue != m_queue) throw new ArgumentException($"Resource {resource} does not belong to queue {m_queue}"); @@ -126,7 +126,7 @@ internal void Present(GpuOutput Output, CommandFlags Flags = CommandFlags.None) public void ClearColor( Rtv Image, ReadOnlySpan Rects = default, CommandFlags Flags = CommandFlags.None - ) where Rtv : IRtv => ClearColor(Image, new(0, 0, 0, 1), Rects, Flags); + ) where Rtv : IRtvRes => ClearColor(Image, new(0, 0, 0, 1), Rects, Flags); /// /// 使用指定的颜色清空 Rtv @@ -134,7 +134,7 @@ public void ClearColor( public void ClearColor( Rtv Image, float4 Color, ReadOnlySpan Rects = default, CommandFlags Flags = CommandFlags.None - ) where Rtv : IRtv + ) where Rtv : IRtvRes { if (!Image.TryRtv()) throw new ArgumentException($"Resource {Image} cannot be used as Rtv"); @@ -176,7 +176,7 @@ public void ClearDepthStencil( Dsv Image, ReadOnlySpan Rects = default, CommandFlags Flags = CommandFlags.None - ) where Dsv : IDsv => ClearDepthStencil(Image, 1, 0, DsvClear.All, Rects, Flags); + ) where Dsv : IDsvRes => ClearDepthStencil(Image, 1, 0, DsvClear.All, Rects, Flags); /// /// 使用指定的深度清空 Dsv @@ -185,7 +185,7 @@ public void ClearDepthStencil( Dsv Image, float Depth, ReadOnlySpan Rects = default, CommandFlags Flags = CommandFlags.None - ) where Dsv : IDsv => ClearDepthStencil(Image, Depth, 0, DsvClear.Depth, Rects, Flags); + ) where Dsv : IDsvRes => ClearDepthStencil(Image, Depth, 0, DsvClear.Depth, Rects, Flags); /// /// 使用指定的模板清空 Dsv @@ -194,7 +194,7 @@ public void ClearDepthStencil( Dsv Image, byte Stencil, ReadOnlySpan Rects = default, CommandFlags Flags = CommandFlags.None - ) where Dsv : IDsv => ClearDepthStencil(Image, 1, Stencil, DsvClear.Stencil, Rects, Flags); + ) where Dsv : IDsvRes => ClearDepthStencil(Image, 1, Stencil, DsvClear.Stencil, Rects, Flags); /// /// 使用指定的深度和模板清空 Dsv @@ -203,7 +203,7 @@ public void ClearDepthStencil( Dsv Image, float Depth, byte Stencil, DsvClear Clear = DsvClear.All, ReadOnlySpan Rects = default, CommandFlags Flags = CommandFlags.None - ) where Dsv : IDsv + ) where Dsv : IDsvRes { if (!Image.TryDsv()) throw new ArgumentException($"Resource {Image} cannot be used as Dsv"); @@ -238,7 +238,7 @@ public void ClearDepthStencil( #region SetRenderTargets public void SetRenderTargets( - ReadOnlySpan Rtvs, IDsv? Dsv = null, + ReadOnlySpan Rtvs, IDsvRes? Dsv = null, bool AutoViewportScissor = true, CommandFlags Flags = CommandFlags.None ) @@ -374,7 +374,7 @@ public void SetMeshBuffers( public void SetMeshBuffers( MeshLayout MeshLayout, FGraphicsFormat IndexFormat, - BufferRange? IndexBuffer, + BufferRange? IndexBuffer, uint VertexStartSlot, ReadOnlySpan VertexBuffers, CommandFlags Flags = CommandFlags.None diff --git a/Coplt.Graphics.Core/Core/GpuBuffer.cs b/Coplt.Graphics.Core/Core/GpuBuffer.cs index df8b0fc..6fcaa19 100644 --- a/Coplt.Graphics.Core/Core/GpuBuffer.cs +++ b/Coplt.Graphics.Core/Core/GpuBuffer.cs @@ -8,7 +8,6 @@ public record struct GpuBufferCreateOptions() public Str8or16 Name; public required ResourcePurpose Purpose; public CpuAccess CpuAccess = CpuAccess.None; - public LifeTime LifeTime = LifeTime.Common; public required ulong Size; public uint Count; public uint Stride; @@ -16,7 +15,8 @@ public record struct GpuBufferCreateOptions() } [Dropping(Unmanaged = true)] -public sealed unsafe partial class GpuBuffer : GpuResource, ICbv, ISrv, IUav, IRtv, IIbv, IVbv +public sealed unsafe partial class GpuBuffer + : GpuResource, ICbvRes, ISrvRes, IUavRes, IRtvRes, IIbvRes, IVbvRes { #region Fields @@ -28,8 +28,8 @@ public sealed unsafe partial class GpuBuffer : GpuResource, ICbv, ISrv, IUav, IR public new FGpuBuffer* Ptr => m_ptr; public ulong Size => m_ptr->m_size; - ulong IView.LongSize => Size; - uint3 IView.Size => new((uint)Size, 1, 1); + ulong IGpuView.LongSize => Size; + uint3 IGpuView.Size => new((uint)Size, 1, 1); public uint Count => m_ptr->m_count; public uint Stride => m_ptr->m_stride; public BufferUsage Usage => (BufferUsage)m_ptr->m_usage; @@ -66,13 +66,13 @@ m_name is null #region View - FResourceMeta IView.GetMeta() => new() + FResourceMeta IGpuResource.GetMeta() => new() { CurrentState = m_ptr->Base.m_state, Type = FResourceRefType.Buffer, Buffer = m_ptr, }; - void IView.UnsafeChangeState(FResourceState state) => UnsafeChangeState(state); + void IGpuResource.UnsafeChangeState(FResourceState state) => UnsafeChangeState(state); internal void UnsafeChangeState(FResourceState state) => m_ptr->Base.m_state.ChangeState(state); public bool TryVbv() => Purpose.HasFlags(ResourcePurpose.VertexBuffer); diff --git a/Coplt.Graphics.Core/Core/GpuOutput.cs b/Coplt.Graphics.Core/Core/GpuOutput.cs index 1d71d24..a9e4401 100644 --- a/Coplt.Graphics.Core/Core/GpuOutput.cs +++ b/Coplt.Graphics.Core/Core/GpuOutput.cs @@ -64,7 +64,7 @@ public record struct GpuOutputOptions() #endregion [Dropping(Unmanaged = true)] -public sealed unsafe partial class GpuOutput : IRtv, ISrv +public sealed unsafe partial class GpuOutput : IRtvRes, ISrvRes { #region Fields @@ -140,13 +140,13 @@ m_name is null #region Views - FResourceMeta IView.GetMeta() => new() + FResourceMeta IGpuResource.GetMeta() => new() { CurrentState = m_ptr->m_state, Type = FResourceRefType.Output, Output = m_ptr, }; - void IView.UnsafeChangeState(FResourceState state) => UnsafeChangeState(state); + void IGpuResource.UnsafeChangeState(FResourceState state) => UnsafeChangeState(state); internal void UnsafeChangeState(FResourceState state) => m_ptr->m_state.ChangeState(state); public bool TrySrv() => true; diff --git a/Coplt.Graphics.Core/Core/GpuQueue.cs b/Coplt.Graphics.Core/Core/GpuQueue.cs index 90c1de6..14c13df 100644 --- a/Coplt.Graphics.Core/Core/GpuQueue.cs +++ b/Coplt.Graphics.Core/Core/GpuQueue.cs @@ -143,12 +143,14 @@ public GpuBuffer CreateBuffer( { FGpuBufferCreateOptions f_options = new() { - Base = new() + Base = { - Name = new(Name, Name8, p_name, p_name8), - Purpose = options.Purpose.ToFFI(), + Base = + { + Name = new(Name, Name8, p_name, p_name8), + Purpose = options.Purpose.ToFFI(), + }, CpuAccess = options.CpuAccess.ToFFI(), - LifeTime = options.LifeTime.ToFFI(), }, Size = options.Size, Count = options.Count, diff --git a/Coplt.Graphics.Core/Core/GpuResource.cs b/Coplt.Graphics.Core/Core/GpuResource.cs index 2f981d0..5255273 100644 --- a/Coplt.Graphics.Core/Core/GpuResource.cs +++ b/Coplt.Graphics.Core/Core/GpuResource.cs @@ -5,35 +5,28 @@ namespace Coplt.Graphics.Core; [Dropping(Unmanaged = true)] -public abstract unsafe partial class GpuResource +public abstract unsafe partial class GpuResource : GpuView { #region Fields - internal FGpuResource* m_ptr; - internal string? m_name; - internal GpuQueue m_queue; + internal new FGpuResource* m_ptr; #endregion #region Props - public FGpuResource* Ptr => m_ptr; - public GpuDevice Device => m_queue.m_device; - public GpuQueue Queue => m_queue; + public new FGpuResource* Ptr => m_ptr; public ResourceState State => m_ptr->m_state.FromFFI(); - public ResourcePurpose Purpose => (ResourcePurpose)m_ptr->m_purpose; public CpuAccess CpuAccess => (CpuAccess)m_ptr->m_cpu_access; - public LifeTime LifeTime => (LifeTime)m_ptr->m_life_time; #endregion #region Ctor - internal GpuResource(FGpuResource* ptr, string? name, GpuQueue queue) + internal GpuResource(FGpuResource* ptr, string? name, GpuQueue queue) : base(&ptr->Base, name, queue) { m_ptr = ptr; m_name = name; - m_queue = queue; } #endregion @@ -43,32 +36,7 @@ internal GpuResource(FGpuResource* ptr, string? name, GpuQueue queue) [Drop] private void Drop() { - if (ExchangeUtils.ExchangePtr(ref m_ptr, null, out var ptr) is null) return; - ptr->Release(); - } - - #endregion - - #region SetName - - public void SetName(string name) - { - m_name = name; - fixed (char* ptr = name) - { - Str8or16 str = new() { str16 = ptr, len = name.Length }; - m_ptr->SetName(&str).TryThrow(); - } - } - - public void SetName(ReadOnlySpan name) - { - fixed (byte* ptr = name) - { - Str8or16 str = new() { str8 = ptr, len = name.Length }; - m_ptr->SetName(&str).TryThrow(); - } - m_name = null; + m_ptr = null; } #endregion diff --git a/Coplt.Graphics.Core/Core/GpuView.cs b/Coplt.Graphics.Core/Core/GpuView.cs new file mode 100644 index 0000000..0d12df7 --- /dev/null +++ b/Coplt.Graphics.Core/Core/GpuView.cs @@ -0,0 +1,81 @@ +using System.Runtime.CompilerServices; +using Coplt.Dropping; +using Coplt.Graphics.Native; + +namespace Coplt.Graphics.Core; + +[Dropping(Unmanaged = true)] +public abstract unsafe partial class GpuView +{ + #region Fields + + internal FGpuView* m_ptr; + internal string? m_name; + internal readonly GpuQueue m_queue; + + #endregion + + #region Props + + public FGpuView* Ptr => m_ptr; + public GpuDevice Device => m_queue.m_device; + public GpuQueue Queue => m_queue; + public ResourcePurpose Purpose => (ResourcePurpose)m_ptr->m_purpose; + + #endregion + + #region Ctor + + internal GpuView(FGpuView* ptr, string? name, GpuQueue queue) + { + m_ptr = ptr; + m_name = name; + m_queue = queue; + } + + #endregion + + #region Drop + + [Drop] + private void Drop() + { + if (ExchangeUtils.ExchangePtr(ref m_ptr, null, out var ptr) is null) return; + ptr->Release(); + } + + #endregion + + #region SetName + + public void SetName(string name) + { + m_name = name; + fixed (char* ptr = name) + { + Str8or16 str = new() { str16 = ptr, len = name.Length }; + m_ptr->SetName(&str).TryThrow(); + } + } + + public void SetName(ReadOnlySpan name) + { + fixed (byte* ptr = name) + { + Str8or16 str = new() { str8 = ptr, len = name.Length }; + m_ptr->SetName(&str).TryThrow(); + } + m_name = null; + } + + #endregion + + #region ToString + + public override string ToString() => + m_name is null + ? $"{nameof(GpuView)}(0x{(nuint)m_ptr:X})" + : $"{nameof(GpuView)}(0x{(nuint)m_ptr:X} \"{m_name}\")"; + + #endregion +} diff --git a/Coplt.Graphics.Core/Core/ResourceEnums.cs b/Coplt.Graphics.Core/Core/ResourceEnums.cs index 0672389..7d92d3f 100644 --- a/Coplt.Graphics.Core/Core/ResourceEnums.cs +++ b/Coplt.Graphics.Core/Core/ResourceEnums.cs @@ -19,22 +19,6 @@ public enum ResourcePurpose : uint IndirectDrawArgs = 1 << 10, } - public enum LifeTime : byte - { - /// - /// 一般资源 - /// - Common, - /// - /// 静态资源,一般比如静态加载的图片、材质的参数 - /// - Static, - /// - /// 瞬态资源,只在帧内使用,帧结束后将丢弃,同时每帧都会具有独立副本,类似交换链 - /// - Transient, - } - public enum CpuAccess : byte { None = 0, @@ -66,13 +50,6 @@ public static partial class GraphicsExtensions public static FResourcePurpose ToFFI(this ResourcePurpose value) => (FResourcePurpose)value; public static bool HasFlags(this ResourcePurpose purpose, ResourcePurpose flag) => (purpose & flag) == flag; public static bool HasAnyFlags(this ResourcePurpose purpose, ResourcePurpose flag) => (purpose & flag) != 0; - public static FLifeTime ToFFI(this LifeTime value) => value switch - { - LifeTime.Common => FLifeTime.Common, - LifeTime.Static => FLifeTime.Static, - LifeTime.Transient => FLifeTime.Transient, - _ => throw new ArgumentOutOfRangeException(nameof(value), value, null) - }; public static FCpuAccess ToFFI(this CpuAccess value) => value switch { CpuAccess.None => FCpuAccess.None, diff --git a/Coplt.Graphics.Core/Core/Views.cs b/Coplt.Graphics.Core/Core/Views.cs index a7938f6..b1e540b 100644 --- a/Coplt.Graphics.Core/Core/Views.cs +++ b/Coplt.Graphics.Core/Core/Views.cs @@ -2,12 +2,15 @@ namespace Coplt.Graphics.Core; -public interface IView +public interface IGpuView { public ulong LongSize => Size.x; public uint3 Size { get; } public GpuQueue Queue { get; } +} +public interface IGpuResource : IGpuView +{ public FResourceMeta GetMeta(); /// @@ -16,42 +19,58 @@ public interface IView public void UnsafeChangeState(FResourceState state); } -public interface ICbv : IView +public interface ICbv : IGpuView { public bool TryCbv(); } -public interface ISrv : IView +public interface ICbvRes : ICbv, IGpuResource; + +public interface ISrv : IGpuView { public bool TrySrv(); } -public interface IUav : IView +public interface ISrvRes : ISrv, IGpuResource; + +public interface IUav : IGpuView { public bool TryUav(); } -public interface IRtv : IView +public interface IUavRes : IUav, IGpuResource; + +public interface IRtv : IGpuView { public bool TryRtv(); } -public interface IDsv : IView +public interface IRtvRes : IRtv, IGpuResource; + +public interface IDsv : IGpuView { public bool TryDsv(); } -public interface IIbv : IView +public interface IDsvRes : IDsv, IGpuResource; + +public interface IIbv : IGpuView { public bool TryIbv(); } -public interface IVbv : IView +public interface IIbvRes : IIbv, IGpuResource; + +public interface IVbv : IGpuView { public bool TryVbv(); } -public interface ISov : IView +public interface IVbvRes : IVbv, IGpuResource; + +public interface ISov : IGpuView { public bool TrySov(); } + +public interface ISovRes : ISov, IGpuResource; diff --git a/Coplt.Graphics.Core/Native/Native.cs b/Coplt.Graphics.Core/Native/Native.cs index 2852b1a..70375ef 100644 --- a/Coplt.Graphics.Core/Native/Native.cs +++ b/Coplt.Graphics.Core/Native/Native.cs @@ -1430,14 +1430,6 @@ public enum FResourcePurpose : uint IndirectDrawArgs = 1 << 10, } - [NativeTypeName("Coplt::u8")] - public enum FLifeTime : byte - { - Common, - Static, - Transient, - } - [NativeTypeName("Coplt::u8")] public enum FCpuAccess : byte { @@ -1454,65 +1446,50 @@ public enum FBufferUsage : byte Raw, } - public partial struct FGpuResourceCreateOptions + public partial struct FGpuViewCreateOptions { [NativeTypeName("Coplt::Str8or16")] public Str8or16 Name; [NativeTypeName("Coplt::FResourcePurpose")] public FResourcePurpose Purpose; - - [NativeTypeName("Coplt::FCpuAccess")] - public FCpuAccess CpuAccess; - - [NativeTypeName("Coplt::FLifeTime")] - public FLifeTime LifeTime; } - [Guid("F99DCEEC-2F0C-4A28-B666-BEB7C35219D6")] - [NativeTypeName("struct FGpuResource : Coplt::FGpuObject")] - public unsafe partial struct FGpuResource : FGpuResource.Interface, INativeGuid + [Guid("B3AEB8A5-1FA6-4866-97EF-1A5FA401E18F")] + [NativeTypeName("struct FGpuView : Coplt::FGpuObject")] + public unsafe partial struct FGpuView : FGpuView.Interface, INativeGuid { - static Guid* INativeGuid.NativeGuid => (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in IID_FGpuResource)); + static Guid* INativeGuid.NativeGuid => (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in IID_FGpuView)); public void** lpVtbl; - [NativeTypeName("Coplt::FResourceState")] - public FResourceState m_state; - [NativeTypeName("Coplt::FResourcePurpose")] public FResourcePurpose m_purpose; - [NativeTypeName("Coplt::FCpuAccess")] - public FCpuAccess m_cpu_access; - - [NativeTypeName("Coplt::FLifeTime")] - public FLifeTime m_life_time; - [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { - ((delegate* unmanaged[Thiscall])(lpVtbl[0]))((FGpuResource*)Unsafe.AsPointer(ref this)); + ((delegate* unmanaged[Thiscall])(lpVtbl[0]))((FGpuView*)Unsafe.AsPointer(ref this)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("size_t")] public nuint Release() { - return ((delegate* unmanaged[Thiscall])(lpVtbl[1]))((FGpuResource*)Unsafe.AsPointer(ref this)); + return ((delegate* unmanaged[Thiscall])(lpVtbl[1]))((FGpuView*)Unsafe.AsPointer(ref this)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("size_t")] public nuint AddRef() { - return ((delegate* unmanaged[Thiscall])(lpVtbl[2]))((FGpuResource*)Unsafe.AsPointer(ref this)); + return ((delegate* unmanaged[Thiscall])(lpVtbl[2]))((FGpuView*)Unsafe.AsPointer(ref this)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void* QueryInterface([NativeTypeName("const Guid &")] Guid* id) { - return ((delegate* unmanaged[Thiscall])(lpVtbl[3]))((FGpuResource*)Unsafe.AsPointer(ref this), id); + return ((delegate* unmanaged[Thiscall])(lpVtbl[3]))((FGpuView*)Unsafe.AsPointer(ref this), id); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1520,7 +1497,7 @@ public nuint AddRef() public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGpuResource*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGpuView*)Unsafe.AsPointer(ref this), &result, name); } public interface Interface : FGpuObject.Interface @@ -1528,6 +1505,39 @@ public interface Interface : FGpuObject.Interface } } + [NativeTypeName("struct FGpuResourceCreateOptions : Coplt::FGpuViewCreateOptions")] + public partial struct FGpuResourceCreateOptions + { + public FGpuViewCreateOptions Base; + + [NativeTypeName("Coplt::FCpuAccess")] + public FCpuAccess CpuAccess; + } + + [Guid("F99DCEEC-2F0C-4A28-B666-BEB7C35219D6")] + [NativeTypeName("struct FGpuResource : Coplt::FGpuView")] + public unsafe partial struct FGpuResource : INativeGuid + { + static Guid* INativeGuid.NativeGuid => (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in IID_FGpuResource)); + + public FGpuView Base; + + [NativeTypeName("Coplt::FCpuAccess")] + public FCpuAccess m_cpu_access; + + [NativeTypeName("Coplt::FResourceState")] + public FResourceState m_state; + } + + [Guid("F7DFC622-972B-49B2-8999-8FB129C61AC6")] + [NativeTypeName("struct FGpuTransientView : Coplt::FGpuView")] + public unsafe partial struct FGpuTransientView : INativeGuid + { + static Guid* INativeGuid.NativeGuid => (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in IID_FGpuTransientView)); + + public FGpuView Base; + } + [NativeTypeName("struct FGpuBufferCreateOptions : Coplt::FGpuResourceCreateOptions")] public partial struct FGpuBufferCreateOptions { @@ -1567,6 +1577,45 @@ public unsafe partial struct FGpuBuffer : INativeGuid public FBufferUsage m_usage; } + [NativeTypeName("struct FGpuUploadBufferCreateOptions : Coplt::FGpuViewCreateOptions")] + public partial struct FGpuUploadBufferCreateOptions + { + public FGpuViewCreateOptions Base; + + [NativeTypeName("Coplt::u64")] + public ulong Size; + + [NativeTypeName("Coplt::u32")] + public uint Count; + + [NativeTypeName("Coplt::u32")] + public uint Stride; + + [NativeTypeName("Coplt::FBufferUsage")] + public FBufferUsage Usage; + } + + [Guid("3E85392D-8FD3-49EB-9872-CF7A0D7C8E4C")] + [NativeTypeName("struct FGpuUploadBuffer : Coplt::FGpuTransientView")] + public unsafe partial struct FGpuUploadBuffer : INativeGuid + { + static Guid* INativeGuid.NativeGuid => (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in IID_FGpuUploadBuffer)); + + public FGpuTransientView Base; + + [NativeTypeName("Coplt::u64")] + public ulong m_size; + + [NativeTypeName("Coplt::u32")] + public uint m_count; + + [NativeTypeName("Coplt::u32")] + public uint m_stride; + + [NativeTypeName("Coplt::FBufferUsage")] + public FBufferUsage m_usage; + } + [StructLayout(LayoutKind.Explicit)] public partial struct FOptimizedClearColor { @@ -1575,7 +1624,7 @@ public partial struct FOptimizedClearColor public _Color_e__FixedBuffer Color; [FieldOffset(0)] - [NativeTypeName("__AnonymousRecord_Resource_L119_C9")] + [NativeTypeName("__AnonymousRecord_Resource_L143_C9")] public _Anonymous_e__Struct Anonymous; [UnscopedRef] @@ -3420,10 +3469,16 @@ public static partial class Native public static readonly Guid IID_FGpuQueue = new Guid(0x95E60E28, 0xE387, 0x4055, 0x9B, 0x33, 0x2D, 0x23, 0xAF, 0x90, 0x1F, 0x8A); + public static readonly Guid IID_FGpuView = new Guid(0xB3AEB8A5, 0x1FA6, 0x4866, 0x97, 0xEF, 0x1A, 0x5F, 0xA4, 0x01, 0xE1, 0x8F); + public static readonly Guid IID_FGpuResource = new Guid(0xF99DCEEC, 0x2F0C, 0x4A28, 0xB6, 0x66, 0xBE, 0xB7, 0xC3, 0x52, 0x19, 0xD6); + public static readonly Guid IID_FGpuTransientView = new Guid(0xF7DFC622, 0x972B, 0x49B2, 0x89, 0x99, 0x8F, 0xB1, 0x29, 0xC6, 0x1A, 0xC6); + public static readonly Guid IID_FGpuBuffer = new Guid(0x283740E3, 0xFE96, 0x41D0, 0x83, 0x0A, 0x0A, 0x4C, 0x6A, 0x72, 0x53, 0x36); + public static readonly Guid IID_FGpuUploadBuffer = new Guid(0x3E85392D, 0x8FD3, 0x49EB, 0x98, 0x72, 0xCF, 0x7A, 0x0D, 0x7C, 0x8E, 0x4C); + public static readonly Guid IID_FGpuImage = new Guid(0x667EFA36, 0x21C7, 0x4561, 0xAB, 0xAD, 0x85, 0x78, 0x0F, 0xA4, 0x92, 0x9E); public static readonly Guid IID_FGpuOutput = new Guid(0xF1C59CB4, 0x7EE6, 0x4EE2, 0x80, 0xF4, 0x07, 0xCC, 0x56, 0x89, 0x20, 0xD2); diff --git a/Coplt.Graphics.Native/Api/FFI/Resource.h b/Coplt.Graphics.Native/Api/FFI/Resource.h index 68ce347..41dffcd 100644 --- a/Coplt.Graphics.Native/Api/FFI/Resource.h +++ b/Coplt.Graphics.Native/Api/FFI/Resource.h @@ -45,16 +45,6 @@ namespace Coplt IndirectDrawArgs = 1 << 10, }; - enum class FLifeTime : u8 - { - // 一般资源 - Common, - // 静态资源,一般比如静态加载的图片、材质的参数 - Static, - // 瞬态资源,只在帧内使用,帧结束后将丢弃,同时每帧都会具有独立副本,类似交换链 - Transient, - }; - enum class FCpuAccess : u8 { None = 0, @@ -72,20 +62,30 @@ namespace Coplt Raw, }; - struct FGpuResourceCreateOptions + struct FGpuViewCreateOptions { Str8or16 Name{}; FResourcePurpose Purpose{}; - FCpuAccess CpuAccess{}; - FLifeTime LifeTime{}; }; - COPLT_INTERFACE_DEFINE(FGpuResource, "f99dceec-2f0c-4a28-b666-beb7c35219d6", FGpuObject) + COPLT_INTERFACE_DEFINE(FGpuView, "b3aeb8a5-1fa6-4866-97ef-1a5fa401e18f", FGpuObject) { - FResourceState m_state{}; FResourcePurpose m_purpose{}; + }; + + struct FGpuResourceCreateOptions : FGpuViewCreateOptions + { + FCpuAccess CpuAccess{}; + }; + + COPLT_INTERFACE_DEFINE(FGpuResource, "f99dceec-2f0c-4a28-b666-beb7c35219d6", FGpuView) + { FCpuAccess m_cpu_access{}; - FLifeTime m_life_time{}; + FResourceState m_state{}; + }; + + COPLT_INTERFACE_DEFINE(FGpuTransientView, "f7dfc622-972b-49b2-8999-8fb129c61ac6", FGpuView) + { }; struct FGpuBufferCreateOptions : FGpuResourceCreateOptions @@ -112,6 +112,30 @@ namespace Coplt FBufferUsage m_usage{}; }; + struct FGpuUploadBufferCreateOptions : FGpuViewCreateOptions + { + // 字节大小 + u64 Size{}; + // 默认的 Structured Buffer 元素数量 + u32 Count{}; + // 默认的 Structured Buffer 元素步幅 + u32 Stride{}; + // 指示默认用法 + FBufferUsage Usage{}; + }; + + COPLT_INTERFACE_DEFINE(FGpuUploadBuffer, "3e85392d-8fd3-49eb-9872-cf7a0d7c8e4c", FGpuTransientView) + { + // 字节大小 + u64 m_size{}; + // 默认的 Structured Buffer 元素数量 + u32 m_count{}; + // 默认的 Structured Buffer 元素步幅 + u32 m_stride{}; + // 指示默认用法 + FBufferUsage m_usage{}; + }; + union FOptimizedClearColor { f32 Color[4]; diff --git a/Coplt.Graphics.Native/D3d12/Src/Buffer.cc b/Coplt.Graphics.Native/D3d12/Src/Buffer.cc index e621e0b..bc5c1b3 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Buffer.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Buffer.cc @@ -10,7 +10,6 @@ D3d12GpuBuffer::D3d12GpuBuffer(Rc&& device, const FGpuBufferCrea m_state = FResourceState::Common; m_purpose = options.Purpose; m_cpu_access = options.CpuAccess; - m_life_time = options.LifeTime; m_size = options.Size; m_count = options.Count; m_stride = options.Stride; @@ -33,15 +32,11 @@ D3d12GpuBuffer::D3d12GpuBuffer(Rc&& device, const FGpuBufferCrea if (HasAnyFlags(m_purpose, FResourcePurpose::UnorderedAccess)) m_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS; - // 瞬态资源不会立即创建 - if (m_life_time != FLifeTime::Transient) - { - m_resource = box(m_allocator.Get(), m_cpu_access, m_state, &m_desc, nullptr); + m_resource = box(m_allocator.Get(), m_cpu_access, m_state, &m_desc, nullptr); - if (m_device->Debug()) - { - chr | m_resource->m_resource >> SetNameEx(options.Name); - } + if (m_device->Debug()) + { + chr | m_resource->m_resource >> SetNameEx(options.Name); } } @@ -50,7 +45,6 @@ FResult D3d12GpuBuffer::SetName(const Str8or16& name) noexcept return feb([&] { if (!m_device->Debug()) return; - if (m_life_time == FLifeTime::Transient) return; chr | m_resource->m_resource >> SetNameEx(name); }); } diff --git a/Coplt.Graphics.sln b/Coplt.Graphics.sln index 397a044..907f620 100644 --- a/Coplt.Graphics.sln +++ b/Coplt.Graphics.sln @@ -12,7 +12,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExampleBase", "Examples\Exa EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloTriangleVertex", "Examples\HelloTriangleVertex\HelloTriangleVertex.csproj", "{1173C015-4D34-4DD1-85F6-98C68FDC50BB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RotatingCube", "Examples\RotatingCube\RotatingCube.csproj", "{C4C82737-D197-447B-B663-2DEFE3CE6679}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Colorful", "Examples\Colorful\Colorful.csproj", "{C4C82737-D197-447B-B663-2DEFE3CE6679}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/Examples/RotatingCube/App.xaml b/Examples/Colorful/App.xaml similarity index 100% rename from Examples/RotatingCube/App.xaml rename to Examples/Colorful/App.xaml diff --git a/Examples/RotatingCube/App.xaml.cs b/Examples/Colorful/App.xaml.cs similarity index 100% rename from Examples/RotatingCube/App.xaml.cs rename to Examples/Colorful/App.xaml.cs diff --git a/Examples/RotatingCube/AssemblyInfo.cs b/Examples/Colorful/AssemblyInfo.cs similarity index 100% rename from Examples/RotatingCube/AssemblyInfo.cs rename to Examples/Colorful/AssemblyInfo.cs diff --git a/Examples/RotatingCube/RotatingCube.csproj b/Examples/Colorful/Colorful.csproj similarity index 100% rename from Examples/RotatingCube/RotatingCube.csproj rename to Examples/Colorful/Colorful.csproj diff --git a/Examples/Colorful/Example.cs b/Examples/Colorful/Example.cs new file mode 100644 index 0000000..99515b6 --- /dev/null +++ b/Examples/Colorful/Example.cs @@ -0,0 +1,43 @@ +using Coplt.Graphics; +using Coplt.Graphics.Core; +using Coplt.Graphics.States; +using Coplt.Mathematics; + +namespace Examples; + +public class Example(IntPtr Handle, uint Width, uint Height) : ExampleBase(Handle, Width, Height) +{ + private Shader Shader = null!; + private GraphicsShaderPipeline Pipeline = null!; + + public override string Name => "Colorful"; + protected override async Task LoadResources(CommandList cmd) + { + var modules = await LoadShaderModules("Shader", [ShaderStage.Vertex, ShaderStage.Pixel]); + Shader = Device.CreateShader( + modules, null, Device.CreateShaderInputLayout([]) + ); + Pipeline = Device.CreateGraphicsShaderPipeline( + Shader, new() + { + DsvFormat = GraphicsFormat.Unknown, + BlendState = + { + Rt0 = + { + Src = BlendType.SrcAlpha, + Dst = BlendType.InvSrcAlpha, + Op = BlendOp.Add, + } + }, + Topology = PrimitiveTopologyType.TriangleStrip, + }, Name: Name + ); + } + protected override void Render(CommandList cmd, Time time) + { + cmd.SetRenderTargets([Output]); + cmd.ClearColor(Output, new float4(0.83f, 0.8f, 0.97f, 1f)); + cmd.Draw(Pipeline, 4); + } +} diff --git a/Examples/RotatingCube/MainWindow.xaml b/Examples/Colorful/MainWindow.xaml similarity index 100% rename from Examples/RotatingCube/MainWindow.xaml rename to Examples/Colorful/MainWindow.xaml diff --git a/Examples/RotatingCube/MainWindow.xaml.cs b/Examples/Colorful/MainWindow.xaml.cs similarity index 100% rename from Examples/RotatingCube/MainWindow.xaml.cs rename to Examples/Colorful/MainWindow.xaml.cs diff --git a/Examples/RotatingCube/Properties/launchSettings.json b/Examples/Colorful/Properties/launchSettings.json similarity index 100% rename from Examples/RotatingCube/Properties/launchSettings.json rename to Examples/Colorful/Properties/launchSettings.json diff --git a/Examples/Colorful/Shaders/Shader.hlsl b/Examples/Colorful/Shaders/Shader.hlsl new file mode 100644 index 0000000..a7fad12 --- /dev/null +++ b/Examples/Colorful/Shaders/Shader.hlsl @@ -0,0 +1,31 @@ +struct Attribute +{ + uint VertexID : SV_VertexID; +}; + +struct Varying +{ + float4 PositionCS : SV_Position; + float2 Uv : UV; +}; + +float4 GetQuadVertexPosition(out float2 uv, uint vid, float z = 1) +{ + float2 uv_ = float2((vid << 1) & 2, vid & 2); + uv = uv_ * 0.5f; + return float4(uv_ * float2(1, -1) + float2(-1, 1), z, 1); +} + +[shader("vertex")] +Varying Vertex(Attribute input) +{ + Varying output; + output.PositionCS = GetQuadVertexPosition(output.Uv, input.VertexID); + return output; +} + +[shader("pixel")] +float4 Pixel(Varying input) : SV_Target +{ + return float4(input.Uv, 0, 1); +} diff --git a/Examples/ExampleBase/ExampleBase.cs b/Examples/ExampleBase/ExampleBase.cs index e1d7234..90abbab 100644 --- a/Examples/ExampleBase/ExampleBase.cs +++ b/Examples/ExampleBase/ExampleBase.cs @@ -1,4 +1,5 @@ -using Coplt.Graphics; +using System.Diagnostics; +using Coplt.Graphics; using Coplt.Graphics.Core; using Serilog; @@ -11,7 +12,7 @@ public abstract class ExampleBase(IntPtr Handle, uint Width, uint Height) public GpuDevice Device = null!; public GpuOutput Output = null!; public IntPtr Handle = Handle; - + public abstract string Name { get; } #region InitGraphics @@ -48,11 +49,23 @@ public void DoInitGraphics() Thread.CurrentThread.Name = "Render Thread"; var cmd = Device.MainCommandList; LoadResources(cmd).Wait(); + var start_time = Stopwatch.GetTimestamp(); + var last_time = start_time; while (!IsClosed) { try { - Render(cmd); + var now_time = Stopwatch.GetTimestamp(); + var total_time = Stopwatch.GetElapsedTime(start_time, now_time); + var delta_time = Stopwatch.GetElapsedTime(last_time, now_time); + last_time = now_time; + var time = new Time + { + Total = total_time, + Delta = delta_time + }; + + Render(cmd, time); Output.Present(); } catch (Exception e) @@ -94,7 +107,7 @@ protected Task LoadShaderModules(string name, ReadOnlySpan "Rotating Cube"; - protected override async Task LoadResources(CommandList cmd) - { - var SlotId_Position = Graphics.GetSlotId("Position"); - var modules = await LoadShaderModules("Shader", [ShaderStage.Vertex, ShaderStage.Pixel]); - Shader = Device.CreateShader( - modules, null, - Device.CreateShaderInputLayout([new("Position", SlotId: SlotId_Position)]) - ); - MeshLayout = Device.CreateMeshLayout( - [new(sizeof(float) * 4)], - [new(SlotId_Position, GraphicsFormat.R32G32B32A32_Float)], - Name: "Cube" - ); - Pipeline = Device.CreateGraphicsShaderPipeline( - Shader, new() { DsvFormat = GraphicsFormat.Unknown, }, MeshLayout, Name: Name - ); - MeshBuffer = Device.CreateBuffer( - new() - { - Purpose = ResourcePurpose.VertexBuffer, - Size = sizeof(float) * 4 * 3 * 2, - }, "Cube Mesh" - ); - cmd.Upload( - MeshBuffer, [ - new float4(0.0f, 0.5f * 1.7f, 0f, 1f), - new float4(0.5f, -0.5f * 1.7f, 0f, 1f), - new float4(-0.5f, -0.5f * 1.7f, 0f, 1f), - ] - ); - } - protected override void Render(CommandList cmd) - { - cmd.SetRenderTargets([Output]); - cmd.ClearColor(Output, new float4(0.83f, 0.8f, 0.97f, 1f)); - cmd.SetMeshBuffers(MeshLayout, [new(0, MeshBuffer)]); - cmd.Draw(Pipeline, 3); - } -} diff --git a/Examples/RotatingCube/Shaders/Shader.hlsl b/Examples/RotatingCube/Shaders/Shader.hlsl deleted file mode 100644 index ac203b0..0000000 --- a/Examples/RotatingCube/Shaders/Shader.hlsl +++ /dev/null @@ -1,27 +0,0 @@ -struct Attribute -{ - float4 PositionCS : Position; -}; - -struct Varying -{ - float4 PositionCS : SV_Position; - // float4 Color : Color; - // float2 Uv : Uv; -}; - -[shader("vertex")] -Varying Vertex(Attribute input) -{ - Varying output; - output.PositionCS = input.PositionCS; - // output.Color = Colors[input.VertexID % 3]; - // output.Uv = Uvs[input.VertexID % 3]; - return output; -} - -[shader("pixel")] -float4 Pixel(Varying input) : SV_Target -{ - return float4(1, 1, 1, 1); -} From 3b045f367fad5e30a3d445277afbbe69d7d5e646 Mon Sep 17 00:00:00 2001 From: U2A5F Date: Mon, 24 Feb 2025 17:32:38 +0800 Subject: [PATCH 02/23] save --- Coplt.Graphics.Core/Native/Native.D3d12.cs | 71 +++++++++++++- Coplt.Graphics.Core/Native/Native.cs | 94 ++++++++++++++++++- Coplt.Graphics.Native/Api/CMakeLists.txt | 1 + Coplt.Graphics.Native/Api/FFI/Binding.h | 25 +++++ Coplt.Graphics.Native/Api/FFI/Device.h | 4 + Coplt.Graphics.Native/D3d12/CMakeLists.txt | 5 + Coplt.Graphics.Native/D3d12/FFI/Binding.h | 10 ++ Coplt.Graphics.Native/D3d12/Src/Binding.cc | 49 ++++++++++ Coplt.Graphics.Native/D3d12/Src/Binding.h | 27 ++++++ .../D3d12/Src/DescriptorManager.cc | 39 ++++++++ .../D3d12/Src/DescriptorManager.h | 38 ++++++++ Coplt.Graphics.Native/D3d12/Src/Device.cc | 12 +++ Coplt.Graphics.Native/D3d12/Src/Device.h | 5 +- Coplt.Graphics.Native/D3d12/Src/Layout.cc | 10 ++ Coplt.Graphics.Native/D3d12/Src/Layout.h | 12 ++- 15 files changed, 394 insertions(+), 8 deletions(-) create mode 100644 Coplt.Graphics.Native/Api/FFI/Binding.h create mode 100644 Coplt.Graphics.Native/D3d12/FFI/Binding.h create mode 100644 Coplt.Graphics.Native/D3d12/Src/Binding.cc create mode 100644 Coplt.Graphics.Native/D3d12/Src/Binding.h create mode 100644 Coplt.Graphics.Native/D3d12/Src/DescriptorManager.cc create mode 100644 Coplt.Graphics.Native/D3d12/Src/DescriptorManager.h diff --git a/Coplt.Graphics.Core/Native/Native.D3d12.cs b/Coplt.Graphics.Core/Native/Native.D3d12.cs index 74911f5..a590ee4 100644 --- a/Coplt.Graphics.Core/Native/Native.D3d12.cs +++ b/Coplt.Graphics.Core/Native/Native.D3d12.cs @@ -102,12 +102,20 @@ public FResult CreateShader([NativeTypeName("const FShaderCreateOptions &")] FSh return *((delegate* unmanaged[Thiscall])(lpVtbl[10]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FResult")] + public FResult CreateShaderBinding([NativeTypeName("const FShaderBindingCreateOptions &")] FShaderBindingCreateOptions* options, FShaderBinding** @out) + { + FResult result; + return *((delegate* unmanaged[Thiscall])(lpVtbl[11]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] public FResult CreateMeshLayout([NativeTypeName("const FMeshLayoutCreateOptions &")] FMeshLayoutCreateOptions* options, FMeshLayout** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[11]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[12]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -115,7 +123,7 @@ public FResult CreateMeshLayout([NativeTypeName("const FMeshLayoutCreateOptions public FResult CreateGraphicsPipeline([NativeTypeName("const FGraphicsShaderPipelineCreateOptions &")] FGraphicsShaderPipelineCreateOptions* options, FGraphicsShaderPipeline** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[12]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[13]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -123,7 +131,7 @@ public FResult CreateGraphicsPipeline([NativeTypeName("const FGraphicsShaderPipe public FResult CreateBuffer([NativeTypeName("const FGpuBufferCreateOptions &")] FGpuBufferCreateOptions* options, FGpuBuffer** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[13]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[14]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } public interface Interface : FGpuDevice.Interface @@ -444,6 +452,61 @@ public interface Interface : FMeshLayout.Interface } } + [Guid("AACE0F36-A59E-45EA-88C7-7807D20D2750")] + [NativeTypeName("struct FD3d12ShaderBinding : Coplt::FShaderBinding")] + public unsafe partial struct FD3d12ShaderBinding : FD3d12ShaderBinding.Interface, INativeGuid + { + static Guid* INativeGuid.NativeGuid => (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in IID_FD3d12ShaderBinding)); + + public void** lpVtbl; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + ((delegate* unmanaged[Thiscall])(lpVtbl[0]))((FD3d12ShaderBinding*)Unsafe.AsPointer(ref this)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("size_t")] + public nuint Release() + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[1]))((FD3d12ShaderBinding*)Unsafe.AsPointer(ref this)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("size_t")] + public nuint AddRef() + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[2]))((FD3d12ShaderBinding*)Unsafe.AsPointer(ref this)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void* QueryInterface([NativeTypeName("const Guid &")] Guid* id) + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[3]))((FD3d12ShaderBinding*)Unsafe.AsPointer(ref this), id); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FResult")] + public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + { + FResult result; + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12ShaderBinding*)Unsafe.AsPointer(ref this), &result, name); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FResult")] + public FResult Set([NativeTypeName("Coplt::u32")] uint count, [NativeTypeName("const FShaderBindingBatchSet *")] FShaderBindingBatchSet* bindings) + { + FResult result; + return *((delegate* unmanaged[Thiscall])(lpVtbl[5]))((FD3d12ShaderBinding*)Unsafe.AsPointer(ref this), &result, count, bindings); + } + + public interface Interface : FShaderBinding.Interface + { + } + } + [Guid("6D9C7DB7-3261-4D79-BD21-1F1BB5E01E4D")] [NativeTypeName("struct FD3d12PipelineState : Coplt::FShaderPipeline")] public unsafe partial struct FD3d12PipelineState : FD3d12PipelineState.Interface, INativeGuid @@ -630,6 +693,8 @@ public static unsafe partial class D3d12Native public static readonly Guid IID_FD3d12MeshLayout = new Guid(0x2C6E52E9, 0x6FA1, 0x457A, 0x8F, 0x99, 0xA7, 0x34, 0xD6, 0x3B, 0x62, 0xC2); + public static readonly Guid IID_FD3d12ShaderBinding = new Guid(0xAACE0F36, 0xA59E, 0x45EA, 0x88, 0xC7, 0x78, 0x07, 0xD2, 0x0D, 0x27, 0x50); + public static readonly Guid IID_FD3d12PipelineState = new Guid(0x6D9C7DB7, 0x3261, 0x4D79, 0xBD, 0x21, 0x1F, 0x1B, 0xB5, 0xE0, 0x1E, 0x4D); public static readonly Guid IID_FD3d12GraphicsShaderPipeline = new Guid(0xA1C6B8A9, 0x1E4C, 0x4E6C, 0x85, 0xEA, 0x2E, 0x64, 0xAC, 0x89, 0xAF, 0xC6); diff --git a/Coplt.Graphics.Core/Native/Native.cs b/Coplt.Graphics.Core/Native/Native.cs index 70375ef..36267a2 100644 --- a/Coplt.Graphics.Core/Native/Native.cs +++ b/Coplt.Graphics.Core/Native/Native.cs @@ -697,12 +697,20 @@ public FResult CreateShader([NativeTypeName("const FShaderCreateOptions &")] FSh return *((delegate* unmanaged[Thiscall])(lpVtbl[10]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FResult")] + public FResult CreateShaderBinding([NativeTypeName("const FShaderBindingCreateOptions &")] FShaderBindingCreateOptions* options, FShaderBinding** @out) + { + FResult result; + return *((delegate* unmanaged[Thiscall])(lpVtbl[11]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] public FResult CreateMeshLayout([NativeTypeName("const FMeshLayoutCreateOptions &")] FMeshLayoutCreateOptions* options, FMeshLayout** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[11]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[12]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -710,7 +718,7 @@ public FResult CreateMeshLayout([NativeTypeName("const FMeshLayoutCreateOptions public FResult CreateGraphicsPipeline([NativeTypeName("const FGraphicsShaderPipelineCreateOptions &")] FGraphicsShaderPipelineCreateOptions* options, FGraphicsShaderPipeline** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[12]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[13]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -718,7 +726,7 @@ public FResult CreateGraphicsPipeline([NativeTypeName("const FGraphicsShaderPipe public FResult CreateBuffer([NativeTypeName("const FGpuBufferCreateOptions &")] FGpuBufferCreateOptions* options, FGpuBuffer** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[13]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[14]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } public interface Interface : FGpuObject.Interface @@ -740,6 +748,9 @@ public interface Interface : FGpuObject.Interface [return: NativeTypeName("Coplt::FResult")] FResult CreateShader([NativeTypeName("const FShaderCreateOptions &")] FShaderCreateOptions* options, FShader** @out); + [return: NativeTypeName("Coplt::FResult")] + FResult CreateShaderBinding([NativeTypeName("const FShaderBindingCreateOptions &")] FShaderBindingCreateOptions* options, FShaderBinding** @out); + [return: NativeTypeName("Coplt::FResult")] FResult CreateMeshLayout([NativeTypeName("const FMeshLayoutCreateOptions &")] FMeshLayoutCreateOptions* options, FMeshLayout** @out); @@ -1237,6 +1248,81 @@ public interface Interface : FGpuObject.Interface } } + public unsafe partial struct FShaderBindingCreateOptions + { + [NativeTypeName("Coplt::Str8or16")] + public Str8or16 Name; + + [NativeTypeName("Coplt::FShaderLayout *")] + public FShaderLayout* Layout; + } + + public unsafe partial struct FShaderBindingBatchSet + { + [NativeTypeName("Coplt::FGpuView *")] + public FGpuView* View; + + [NativeTypeName("Coplt::u32")] + public uint Index; + } + + [Guid("A3CA644A-0E02-4D25-9A18-8835D66600F7")] + [NativeTypeName("struct FShaderBinding : Coplt::FGpuObject")] + public unsafe partial struct FShaderBinding : FShaderBinding.Interface, INativeGuid + { + static Guid* INativeGuid.NativeGuid => (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in IID_FShaderBinding)); + + public void** lpVtbl; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + ((delegate* unmanaged[Thiscall])(lpVtbl[0]))((FShaderBinding*)Unsafe.AsPointer(ref this)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("size_t")] + public nuint Release() + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[1]))((FShaderBinding*)Unsafe.AsPointer(ref this)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("size_t")] + public nuint AddRef() + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[2]))((FShaderBinding*)Unsafe.AsPointer(ref this)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void* QueryInterface([NativeTypeName("const Guid &")] Guid* id) + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[3]))((FShaderBinding*)Unsafe.AsPointer(ref this), id); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FResult")] + public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + { + FResult result; + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FShaderBinding*)Unsafe.AsPointer(ref this), &result, name); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FResult")] + public FResult Set([NativeTypeName("Coplt::u32")] uint count, [NativeTypeName("const FShaderBindingBatchSet *")] FShaderBindingBatchSet* bindings) + { + FResult result; + return *((delegate* unmanaged[Thiscall])(lpVtbl[5]))((FShaderBinding*)Unsafe.AsPointer(ref this), &result, count, bindings); + } + + public interface Interface : FGpuObject.Interface + { + [return: NativeTypeName("Coplt::FResult")] + FResult Set([NativeTypeName("Coplt::u32")] uint count, [NativeTypeName("const FShaderBindingBatchSet *")] FShaderBindingBatchSet* bindings); + } + } + public unsafe partial struct FUploadBufferBlock { [NativeTypeName("Coplt::u8 *")] @@ -3465,6 +3551,8 @@ public static partial class Native public static readonly Guid IID_FShader = new Guid(0xDE1352D5, 0x023D, 0x42B0, 0xBE, 0xAC, 0x12, 0x2B, 0x3B, 0x29, 0x6C, 0x9C); + public static readonly Guid IID_FShaderBinding = new Guid(0xA3CA644A, 0x0E02, 0x4D25, 0x9A, 0x18, 0x88, 0x35, 0xD6, 0x66, 0x00, 0xF7); + public static readonly Guid IID_FFrameContext = new Guid(0x3A22DE68, 0x8377, 0x4E57, 0xA1, 0x67, 0x3E, 0xFD, 0xB9, 0x7C, 0x10, 0x2A); public static readonly Guid IID_FGpuQueue = new Guid(0x95E60E28, 0xE387, 0x4055, 0x9B, 0x33, 0x2D, 0x23, 0xAF, 0x90, 0x1F, 0x8A); diff --git a/Coplt.Graphics.Native/Api/CMakeLists.txt b/Coplt.Graphics.Native/Api/CMakeLists.txt index e0b15b2..484172b 100644 --- a/Coplt.Graphics.Native/Api/CMakeLists.txt +++ b/Coplt.Graphics.Native/Api/CMakeLists.txt @@ -43,6 +43,7 @@ add_library(${target_name} STATIC FFI/Blob.h Src/Blob.cc FFI/Context.h + FFI/Binding.h ) set_target_properties(${target_name} PROPERTIES LINKER_LANGUAGE CXX) add_library(Coplt::Graphics::Api ALIAS ${target_name}) diff --git a/Coplt.Graphics.Native/Api/FFI/Binding.h b/Coplt.Graphics.Native/Api/FFI/Binding.h new file mode 100644 index 0000000..f500909 --- /dev/null +++ b/Coplt.Graphics.Native/Api/FFI/Binding.h @@ -0,0 +1,25 @@ +#pragma once + +#include "GpuObject.h" +#include "Layout.h" +#include "Resource.h" + +namespace Coplt +{ + struct FShaderBindingCreateOptions + { + Str8or16 Name{}; + FShaderLayout* Layout{}; + }; + + struct FShaderBindingBatchSet + { + FGpuView* View{}; + u32 Index{}; + }; + + COPLT_INTERFACE_DEFINE(FShaderBinding, "a3ca644a-0e02-4d25-9a18-8835d66600f7", FGpuObject) + { + virtual FResult Set(u32 count, const FShaderBindingBatchSet* bindings) noexcept = 0; + }; +} diff --git a/Coplt.Graphics.Native/Api/FFI/Device.h b/Coplt.Graphics.Native/Api/FFI/Device.h index db253bc..af6920e 100644 --- a/Coplt.Graphics.Native/Api/FFI/Device.h +++ b/Coplt.Graphics.Native/Api/FFI/Device.h @@ -1,5 +1,6 @@ #pragma once +#include "Binding.h" #include "GpuObject.h" #include "Layout.h" #include "Queue.h" @@ -57,6 +58,9 @@ namespace Coplt const FShaderInputLayoutCreateOptions& options, FShaderInputLayout** out ) noexcept = 0; virtual FResult CreateShader(const FShaderCreateOptions& options, FShader** out) noexcept = 0; + virtual FResult CreateShaderBinding( + const FShaderBindingCreateOptions& options, FShaderBinding** out + ) noexcept = 0; virtual FResult CreateMeshLayout(const FMeshLayoutCreateOptions& options, FMeshLayout** out) noexcept = 0; diff --git a/Coplt.Graphics.Native/D3d12/CMakeLists.txt b/Coplt.Graphics.Native/D3d12/CMakeLists.txt index 2e09304..9c0cc11 100644 --- a/Coplt.Graphics.Native/D3d12/CMakeLists.txt +++ b/Coplt.Graphics.Native/D3d12/CMakeLists.txt @@ -37,6 +37,11 @@ add_library(${target_name} SHARED Src/Context.h Src/Context.cc Include/States.h + FFI/Binding.h + Src/Binding.h + Src/Binding.cc + Src/DescriptorManager.h + Src/DescriptorManager.cc ) set_target_properties(${target_name} PROPERTIES LINKER_LANGUAGE CXX) set_target_properties(${target_name} PROPERTIES OUTPUT_NAME "Coplt.Graphics.Native.D3d12") diff --git a/Coplt.Graphics.Native/D3d12/FFI/Binding.h b/Coplt.Graphics.Native/D3d12/FFI/Binding.h new file mode 100644 index 0000000..92a58a8 --- /dev/null +++ b/Coplt.Graphics.Native/D3d12/FFI/Binding.h @@ -0,0 +1,10 @@ +#pragma once + +#include "../../Api/FFI/Binding.h" + +namespace Coplt +{ + COPLT_INTERFACE_DEFINE(FD3d12ShaderBinding, "aace0f36-a59e-45ea-88c7-7807d20d2750", FShaderBinding) + { + }; +} diff --git a/Coplt.Graphics.Native/D3d12/Src/Binding.cc b/Coplt.Graphics.Native/D3d12/Src/Binding.cc new file mode 100644 index 0000000..e5f54c2 --- /dev/null +++ b/Coplt.Graphics.Native/D3d12/Src/Binding.cc @@ -0,0 +1,49 @@ +#include "Binding.h" + +#include "Layout.h" +#include "../../Api/Include/Error.h" +#include "../FFI/Layout.h" + +using namespace Coplt; + +D3d12ShaderBinding::D3d12ShaderBinding( + Rc&& device, const FShaderBindingCreateOptions& options +) : m_device(std::move(device)) +{ + m_dx_device = m_device->m_device; + + m_layout = Rc::UnsafeClone(options.Layout->QueryInterface()); + if (m_layout == nullptr) throw WRuntimeException(L"Layout from different backends"); + + const auto item_metas = m_layout->GetItemMeta(); + m_views = std::vector>(item_metas.size(), {}); +} + +FResult D3d12ShaderBinding::SetName(const Str8or16& name) noexcept +{ + return FResult::None(); +} + +FResult D3d12ShaderBinding::Set(const u32 count, const FShaderBindingBatchSet* bindings) noexcept +{ + return feb([&] + { + Set(std::span(bindings, count)); + }); +} + +void D3d12ShaderBinding::Set(const std::span bindings) +{ + for (const auto& [View, Index] : bindings) + { + if (Index >= m_views.size()) throw WRuntimeException(L"Index out of bounds"); + if (View == nullptr) + { + m_views[Index] = nullptr; + continue; + } + Rc view = Rc::UnsafeClone(View); + // todo check + m_views[Index] = std::move(view); + } +} diff --git a/Coplt.Graphics.Native/D3d12/Src/Binding.h b/Coplt.Graphics.Native/D3d12/Src/Binding.h new file mode 100644 index 0000000..1f5ff45 --- /dev/null +++ b/Coplt.Graphics.Native/D3d12/Src/Binding.h @@ -0,0 +1,27 @@ +#pragma once + +#include "Device.h" +#include "Layout.h" +#include "../../Api/Include/Object.h" +#include "../FFI/Binding.h" +#include "../FFI/Layout.h" + +namespace Coplt +{ + struct D3d12ShaderBinding final : Object + { + Rc m_device{}; + ComPtr m_dx_device{}; + Rc m_layout{}; + std::vector> m_views{}; + std::vector m_changed{}; + + explicit D3d12ShaderBinding(Rc&& device, const FShaderBindingCreateOptions& options); + + FResult SetName(const Str8or16& name) noexcept override; + + FResult Set(u32 count, const FShaderBindingBatchSet* bindings) noexcept override; + + void Set(std::span bindings); + }; +} diff --git a/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.cc b/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.cc new file mode 100644 index 0000000..1bb0b33 --- /dev/null +++ b/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.cc @@ -0,0 +1,39 @@ +#include "DescriptorManager.h" + +using namespace Coplt; + +DescriptorManager::DescriptorManager(D3d12GpuDevice* device) : m_device(device) +{ + m_dx_device = m_device->m_device; + + { + D3D12_DESCRIPTOR_HEAP_DESC desc{}; + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + desc.NumDescriptors = m_rtv_cap = RtvDsvInitCap; + chr | m_dx_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_rtv_heap)); + } + { + D3D12_DESCRIPTOR_HEAP_DESC desc{}; + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; + desc.NumDescriptors = m_dsv_cap = RtvDsvInitCap; + chr | m_dx_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_dsv_heap)); + } + + { + D3D12_DESCRIPTOR_HEAP_DESC desc{}; + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + desc.NumDescriptors = m_cbv_srv_uav_cap = CbvSrvUavInitCap; + chr | m_dx_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_cbv_srv_uav_Cpu_heap)); + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + chr | m_dx_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_cbv_srv_uav_Gpu_heap)); + } + + { + D3D12_DESCRIPTOR_HEAP_DESC desc{}; + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; + desc.NumDescriptors = m_sampler_cap = SamplerInitCap; + chr | m_dx_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_sampler_Cpu_heap)); + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + chr | m_dx_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_sampler_Gpu_heap)); + } +} diff --git a/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.h b/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.h new file mode 100644 index 0000000..f84cab5 --- /dev/null +++ b/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.h @@ -0,0 +1,38 @@ +#pragma once +#include "Device.h" + +namespace Coplt +{ + struct DescriptorManager final + { + constexpr static u32 RtvDsvInitCap = 128; + constexpr static u32 SamplerInitCap = 128; + constexpr static u32 CbvSrvUavInitCap = 1024; + + D3d12GpuDevice* m_device; + ComPtr m_dx_device{}; + + ComPtr m_rtv_heap{}; + ComPtr m_dsv_heap{}; + + ComPtr m_cbv_srv_uav_Cpu_heap{}; + ComPtr m_sampler_Cpu_heap{}; + + ComPtr m_cbv_srv_uav_Gpu_heap{}; + ComPtr m_sampler_Gpu_heap{}; + + u32 m_rtv_used{}; + u32 m_rtv_cap{}; + + u32 m_dsv_used{}; + u32 m_dsv_cap{}; + + u32 m_cbv_srv_uav_used{}; + u32 m_cbv_srv_uav_cap{}; + + u32 m_sampler_used{}; + u32 m_sampler_cap{}; + + explicit DescriptorManager(D3d12GpuDevice* device); + }; +} diff --git a/Coplt.Graphics.Native/D3d12/Src/Device.cc b/Coplt.Graphics.Native/D3d12/Src/Device.cc index cb19cab..8c3d979 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Device.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Device.cc @@ -1,7 +1,9 @@ #include "Device.h" +#include "Binding.h" #include "dxgi1_6.h" +#include "DescriptorManager.h" #include "../../Api/Src/Shader.h" #include "Buffer.h" #include "GraphicsPipeline.h" @@ -173,6 +175,8 @@ D3d12GpuDevice::D3d12GpuDevice( } chr | m_device->QueryInterface(IID_PPV_ARGS(&m_device0)); + + m_descriptor_manager = box(this); } D3d12GpuDevice::~D3d12GpuDevice() @@ -263,6 +267,14 @@ FResult D3d12GpuDevice::CreateShader(const FShaderCreateOptions& options, FShade }); } +FResult D3d12GpuDevice::CreateShaderBinding(const FShaderBindingCreateOptions& options, FShaderBinding** out) noexcept +{ + return feb([&] + { + *out = new D3d12ShaderBinding(this->CloneThis(), options); + }); +} + FResult D3d12GpuDevice::CreateMeshLayout(const FMeshLayoutCreateOptions& options, FMeshLayout** out) noexcept { return feb([&] diff --git a/Coplt.Graphics.Native/D3d12/Src/Device.h b/Coplt.Graphics.Native/D3d12/Src/Device.h index ccb7901..b79616c 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Device.h +++ b/Coplt.Graphics.Native/D3d12/Src/Device.h @@ -9,6 +9,7 @@ namespace Coplt { + struct DescriptorManager; struct D3d12ShaderLayout; struct D3d12MeshLayout; @@ -24,7 +25,8 @@ namespace Coplt ComPtr m_device0{}; ComPtr m_info_queue{}; ComPtr m_gpu_allocator{}; - std::unique_ptr m_empty_layouts{}; + Box m_descriptor_manager{}; + Box m_empty_layouts{}; Rc m_empty_mesh_layout{}; DWORD m_callback_cookie{}; @@ -60,6 +62,7 @@ namespace Coplt const FShaderInputLayoutCreateOptions& options, FShaderInputLayout** out ) noexcept override; FResult CreateShader(const FShaderCreateOptions& options, FShader** out) noexcept override; + FResult CreateShaderBinding(const FShaderBindingCreateOptions& options, FShaderBinding** out) noexcept override; FResult CreateMeshLayout(const FMeshLayoutCreateOptions& options, FMeshLayout** out) noexcept override; diff --git a/Coplt.Graphics.Native/D3d12/Src/Layout.cc b/Coplt.Graphics.Native/D3d12/Src/Layout.cc index f37db41..35edd5e 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Layout.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Layout.cc @@ -217,6 +217,16 @@ const FShaderLayoutItemDefine* D3d12ShaderLayout::GetItemDefines(u32* out_count) return m_layout_item_defines.data(); } +std::span D3d12ShaderLayout::GetItemMeta() noexcept +{ + return m_item_metas; +} + +std::array, 2> D3d12ShaderLayout::GetTableMetas() noexcept +{ + return std::array, 2>{m_table_metas[0], m_table_metas[1]}; +} + D3d12ShaderInputLayout::D3d12ShaderInputLayout( Rc&& device, const FShaderInputLayoutCreateOptions& options ) : m_device(std::move(device)) diff --git a/Coplt.Graphics.Native/D3d12/Src/Layout.h b/Coplt.Graphics.Native/D3d12/Src/Layout.h index bf9ab46..9449b85 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Layout.h +++ b/Coplt.Graphics.Native/D3d12/Src/Layout.h @@ -11,7 +11,7 @@ namespace Coplt { - struct D3d12ShaderLayout final : Object + COPLT_INTERFACE_DEFINE(ID3d12ShaderLayout, "d8cea40e-7b0c-4a5f-98a9-88fd3abf9ddc", FD3d12ShaderLayout) { enum class ItemType : u8 { @@ -90,10 +90,17 @@ namespace Coplt RangeType RangeType{}; }; + virtual std::span GetItemMeta() noexcept = 0; + virtual std::array, 2> GetTableMetas() noexcept = 0; + }; + + struct D3d12ShaderLayout final : Object + { Rc m_device{}; ComPtr m_dx_device{}; ComPtr m_root_signature{}; std::vector m_layout_item_defines{}; + // 长度和 m_layout_item_defines 相同 std::vector m_item_metas{}; // [Common, Material] std::vector m_table_metas[2]{}; @@ -105,6 +112,9 @@ namespace Coplt void* GetRootSignaturePtr() noexcept override; const FShaderLayoutItemDefine* GetItemDefines(u32* out_count) noexcept override; + + std::span GetItemMeta() noexcept override; + std::array, 2> GetTableMetas() noexcept override; }; struct D3d12ShaderInputLayout final : Object From 2c1977886b4f60a408b9038b59d257c94e0a5ae4 Mon Sep 17 00:00:00 2001 From: U2A5F Date: Mon, 24 Feb 2025 21:03:06 +0800 Subject: [PATCH 03/23] save --- Coplt.Graphics.Native/D3d12/Src/Command.cc | 9 +++ .../D3d12/Src/DescriptorManager.cc | 56 +++++++++---------- .../D3d12/Src/DescriptorManager.h | 51 ++++++++++------- 3 files changed, 66 insertions(+), 50 deletions(-) diff --git a/Coplt.Graphics.Native/D3d12/Src/Command.cc b/Coplt.Graphics.Native/D3d12/Src/Command.cc index 9a44db8..f86f683 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Command.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Command.cc @@ -2,6 +2,7 @@ #include "../../Api/FFI/Command.h" #include "Context.h" +#include "DescriptorManager.h" #include "fmt/format.h" #include "fmt/xchar.h" @@ -306,6 +307,14 @@ void D3d12CommandInterpreter::Translate(const FCommandSubmit& submit) { m_context.ResetPipeline(); const auto& cmd_pack = m_queue->m_cmd; + { + const auto& descriptor_manager = *m_queue->m_device->m_descriptor_manager; + ID3D12DescriptorHeap* heaps[] = { + descriptor_manager.m_cbv_srv_uav_set->m_Gpu_heap.Get(), + descriptor_manager.m_sampler_set->m_Gpu_heap.Get() + }; + cmd_pack->SetDescriptorHeaps(2, heaps); + } for (const auto& cmd_item : m_items) { if (cmd_item.BarrierCount > 0) diff --git a/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.cc b/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.cc index 1bb0b33..7d1ed40 100644 --- a/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.cc +++ b/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.cc @@ -2,38 +2,34 @@ using namespace Coplt; -DescriptorManager::DescriptorManager(D3d12GpuDevice* device) : m_device(device) +CpuDescriptorSet::CpuDescriptorSet( + ComPtr device, const D3D12_DESCRIPTOR_HEAP_TYPE type, const u32 init_cap +) : m_device(std::move(device)), m_type(type), m_cap(init_cap) { - m_dx_device = m_device->m_device; + D3D12_DESCRIPTOR_HEAP_DESC desc{}; + desc.Type = type; + desc.NumDescriptors = init_cap; + chr | m_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_heap)); +} - { - D3D12_DESCRIPTOR_HEAP_DESC desc{}; - desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; - desc.NumDescriptors = m_rtv_cap = RtvDsvInitCap; - chr | m_dx_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_rtv_heap)); - } - { - D3D12_DESCRIPTOR_HEAP_DESC desc{}; - desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; - desc.NumDescriptors = m_dsv_cap = RtvDsvInitCap; - chr | m_dx_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_dsv_heap)); - } +GpuDescriptorSet::GpuDescriptorSet( + ComPtr device, const D3D12_DESCRIPTOR_HEAP_TYPE type, const u32 init_cap +) : m_device(std::move(device)), m_type(type), m_cap(init_cap) +{ + D3D12_DESCRIPTOR_HEAP_DESC desc{}; + desc.Type = type; + desc.NumDescriptors = init_cap; + chr | m_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_Cpu_heap)); + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + chr | m_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_Gpu_heap)); +} - { - D3D12_DESCRIPTOR_HEAP_DESC desc{}; - desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - desc.NumDescriptors = m_cbv_srv_uav_cap = CbvSrvUavInitCap; - chr | m_dx_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_cbv_srv_uav_Cpu_heap)); - desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - chr | m_dx_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_cbv_srv_uav_Gpu_heap)); - } +DescriptorManager::DescriptorManager(D3d12GpuDevice* device) : m_device(device) +{ + m_dx_device = m_device->m_device; - { - D3D12_DESCRIPTOR_HEAP_DESC desc{}; - desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; - desc.NumDescriptors = m_sampler_cap = SamplerInitCap; - chr | m_dx_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_sampler_Cpu_heap)); - desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; - chr | m_dx_device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_sampler_Gpu_heap)); - } + m_rtv_set = box(m_dx_device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, RtvDsvInitCap); + m_dsv_set = box(m_dx_device, D3D12_DESCRIPTOR_HEAP_TYPE_DSV, RtvDsvInitCap); + m_cbv_srv_uav_set = box(m_dx_device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, CbvSrvUavInitCap); + m_sampler_set = box(m_dx_device, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, SamplerInitCap); } diff --git a/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.h b/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.h index f84cab5..4025a48 100644 --- a/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.h +++ b/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.h @@ -3,35 +3,46 @@ namespace Coplt { - struct DescriptorManager final + struct CpuDescriptorSet { - constexpr static u32 RtvDsvInitCap = 128; - constexpr static u32 SamplerInitCap = 128; - constexpr static u32 CbvSrvUavInitCap = 1024; + ComPtr m_device{}; - D3d12GpuDevice* m_device; - ComPtr m_dx_device{}; + D3D12_DESCRIPTOR_HEAP_TYPE m_type{}; + ComPtr m_heap{}; + + u32 m_used{}; + u32 m_cap{}; + + explicit CpuDescriptorSet(ComPtr device, D3D12_DESCRIPTOR_HEAP_TYPE type, u32 init_cap); + }; - ComPtr m_rtv_heap{}; - ComPtr m_dsv_heap{}; + struct GpuDescriptorSet + { + ComPtr m_device{}; - ComPtr m_cbv_srv_uav_Cpu_heap{}; - ComPtr m_sampler_Cpu_heap{}; + D3D12_DESCRIPTOR_HEAP_TYPE m_type{}; + ComPtr m_Cpu_heap{}; + ComPtr m_Gpu_heap{}; - ComPtr m_cbv_srv_uav_Gpu_heap{}; - ComPtr m_sampler_Gpu_heap{}; + u32 m_used{}; + u32 m_cap{}; - u32 m_rtv_used{}; - u32 m_rtv_cap{}; + explicit GpuDescriptorSet(ComPtr device, D3D12_DESCRIPTOR_HEAP_TYPE type, u32 init_cap); + }; - u32 m_dsv_used{}; - u32 m_dsv_cap{}; + struct DescriptorManager final + { + constexpr static u32 RtvDsvInitCap = 128; + constexpr static u32 SamplerInitCap = 128; + constexpr static u32 CbvSrvUavInitCap = 1024; - u32 m_cbv_srv_uav_used{}; - u32 m_cbv_srv_uav_cap{}; + D3d12GpuDevice* m_device; + ComPtr m_dx_device{}; - u32 m_sampler_used{}; - u32 m_sampler_cap{}; + Box m_rtv_set{}; + Box m_dsv_set{}; + Box m_cbv_srv_uav_set{}; + Box m_sampler_set{}; explicit DescriptorManager(D3d12GpuDevice* device); }; From 8141ee6fda1197a2bf5b7a94c887bc7d8708be6b Mon Sep 17 00:00:00 2001 From: U2A5F Date: Tue, 25 Feb 2025 11:49:41 +0800 Subject: [PATCH 04/23] concurrent queue --- .gitmodules | 3 +++ ThirdParty/concurrentqueue | 1 + 2 files changed, 4 insertions(+) create mode 160000 ThirdParty/concurrentqueue diff --git a/.gitmodules b/.gitmodules index 3e4be6c..dfcf513 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,6 @@ [submodule "ThirdParty/emhash"] path = ThirdParty/emhash url = https://github.com/ktprime/emhash +[submodule "ThirdParty/concurrentqueue"] + path = ThirdParty/concurrentqueue + url = https://github.com/cameron314/concurrentqueue diff --git a/ThirdParty/concurrentqueue b/ThirdParty/concurrentqueue new file mode 160000 index 0000000..0d54c67 --- /dev/null +++ b/ThirdParty/concurrentqueue @@ -0,0 +1 @@ +Subproject commit 0d54c6794510018f42b1b987f55c313dd1358320 From 8f3a6d3dbeb0932d4723586ffa7ca36b533f7458 Mon Sep 17 00:00:00 2001 From: U2A5F Date: Tue, 25 Feb 2025 11:51:01 +0800 Subject: [PATCH 05/23] remove emhash --- .gitmodules | 5 +---- ThirdParty/emhash | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) delete mode 160000 ThirdParty/emhash diff --git a/.gitmodules b/.gitmodules index dfcf513..b8d7467 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,9 +19,6 @@ [submodule "Coplt.Graphics.Native/D3d12/ThirdParty/DirectX-Headers"] path = Coplt.Graphics.Native/D3d12/ThirdParty/DirectX-Headers url = https://github.com/Microsoft/DirectX-Headers -[submodule "ThirdParty/emhash"] - path = ThirdParty/emhash - url = https://github.com/ktprime/emhash [submodule "ThirdParty/concurrentqueue"] path = ThirdParty/concurrentqueue - url = https://github.com/cameron314/concurrentqueue + url = https://github.com/cameron314/concurrentqueue \ No newline at end of file diff --git a/ThirdParty/emhash b/ThirdParty/emhash deleted file mode 160000 index e2987ec..0000000 --- a/ThirdParty/emhash +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e2987ec7c0d35b2e0e3d5a2a2727d208ddbba468 From 44ac1346a378149f267f6cb0c753d40f8074a307 Mon Sep 17 00:00:00 2001 From: U2A5F Date: Tue, 25 Feb 2025 11:57:14 +0800 Subject: [PATCH 06/23] update deps --- CMakeLists.txt | 1 + Coplt.Graphics.Native/D3d12/ThirdParty/DirectX-Headers | 2 +- Coplt.Graphics.Native/D3d12/ThirdParty/DirectXTK12 | 2 +- ThirdParty/cpptrace | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a61cf67..9aea6db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ add_subdirectory(ThirdParty/cpptrace) add_subdirectory(ThirdParty/glm) add_subdirectory(ThirdParty/fmt) add_subdirectory(ThirdParty/mimalloc) +add_subdirectory(ThirdParty/concurrentqueue) add_subdirectory(Coplt.Graphics.Native/Api) add_subdirectory(Coplt.Graphics.Native/D3d12) diff --git a/Coplt.Graphics.Native/D3d12/ThirdParty/DirectX-Headers b/Coplt.Graphics.Native/D3d12/ThirdParty/DirectX-Headers index 44432a5..1b3e307 160000 --- a/Coplt.Graphics.Native/D3d12/ThirdParty/DirectX-Headers +++ b/Coplt.Graphics.Native/D3d12/ThirdParty/DirectX-Headers @@ -1 +1 @@ -Subproject commit 44432a5fb04c566ccda7a6079488bd84b7b61ec8 +Subproject commit 1b3e307de44806825dbad2fc66762b61d7df4ec4 diff --git a/Coplt.Graphics.Native/D3d12/ThirdParty/DirectXTK12 b/Coplt.Graphics.Native/D3d12/ThirdParty/DirectXTK12 index 67f9877..72a6c4b 160000 --- a/Coplt.Graphics.Native/D3d12/ThirdParty/DirectXTK12 +++ b/Coplt.Graphics.Native/D3d12/ThirdParty/DirectXTK12 @@ -1 +1 @@ -Subproject commit 67f987722b9eef4c2af96a4bb9abe1cc602d869c +Subproject commit 72a6c4bbf122c603f2090a7afa4c72fadb797656 diff --git a/ThirdParty/cpptrace b/ThirdParty/cpptrace index 6689d14..1940dc6 160000 --- a/ThirdParty/cpptrace +++ b/ThirdParty/cpptrace @@ -1 +1 @@ -Subproject commit 6689d14c203eed390ae7bb64f56a983cfd7dff9c +Subproject commit 1940dc607aa09fd9014c650aa305f363284919fa From ae19d33d94cce032162ec64f3304a55c36a7407a Mon Sep 17 00:00:00 2001 From: U2A5F Date: Tue, 25 Feb 2025 14:04:44 +0800 Subject: [PATCH 07/23] rewrite str8or16 to union --- Coplt.Graphics.Core/Core/GpuBuffer.cs | 1 - Coplt.Graphics.Core/Core/GpuDevice.cs | 44 +++- Coplt.Graphics.Core/Core/GpuOutput.cs | 4 +- Coplt.Graphics.Core/Core/GpuQueue.cs | 6 +- Coplt.Graphics.Core/Core/GpuView.cs | 6 +- Coplt.Graphics.Core/Core/MeshLayout.cs | 6 +- Coplt.Graphics.Core/Core/Shader.cs | 6 +- Coplt.Graphics.Core/Core/ShaderBinding.cs | 81 +++++++ Coplt.Graphics.Core/Core/ShaderInputLayout.cs | 6 +- Coplt.Graphics.Core/Core/ShaderLayout.cs | 6 +- Coplt.Graphics.Core/Core/ShaderModule.cs | 6 +- Coplt.Graphics.Core/Core/ShaderPipeline.cs | 6 +- Coplt.Graphics.Core/Native/Message.cs | 8 +- Coplt.Graphics.Core/Native/Native.D3d12.cs | 52 +++-- Coplt.Graphics.Core/Native/Native.cs | 214 +++++++++++------- Coplt.Graphics.Core/Native/Str8or16.cs | 33 ++- Coplt.Graphics.Native/Api/CMakeLists.txt | 1 + Coplt.Graphics.Native/Api/FFI/Binding.h | 2 +- Coplt.Graphics.Native/Api/FFI/Device.h | 3 +- Coplt.Graphics.Native/Api/FFI/GpuObject.h | 2 +- Coplt.Graphics.Native/Api/FFI/Layout.h | 11 +- Coplt.Graphics.Native/Api/FFI/Output.h | 2 +- Coplt.Graphics.Native/Api/FFI/Pipeline.h | 2 +- Coplt.Graphics.Native/Api/FFI/Queue.h | 2 +- Coplt.Graphics.Native/Api/FFI/Resource.h | 2 +- Coplt.Graphics.Native/Api/FFI/Shader.h | 4 +- Coplt.Graphics.Native/Api/FFI/String.h | 71 ++++-- Coplt.Graphics.Native/Api/Include/Object.h | 12 +- Coplt.Graphics.Native/Api/Src/Shader.cc | 4 +- Coplt.Graphics.Native/Api/Src/Shader.h | 4 +- Coplt.Graphics.Native/Api/Src/String.cc | 11 +- Coplt.Graphics.Native/Api/Src/String.h | 16 +- Coplt.Graphics.Native/D3d12/Include/Utils.h | 11 +- Coplt.Graphics.Native/D3d12/Src/Binding.cc | 2 +- Coplt.Graphics.Native/D3d12/Src/Binding.h | 2 +- Coplt.Graphics.Native/D3d12/Src/Buffer.cc | 2 +- Coplt.Graphics.Native/D3d12/Src/Buffer.h | 2 +- Coplt.Graphics.Native/D3d12/Src/Context.cc | 4 +- .../D3d12/Src/DescriptorManager.h | 3 + Coplt.Graphics.Native/D3d12/Src/Device.cc | 15 +- Coplt.Graphics.Native/D3d12/Src/Device.h | 5 +- .../D3d12/Src/GraphicsPipeline.cc | 2 +- .../D3d12/Src/GraphicsPipeline.h | 2 +- Coplt.Graphics.Native/D3d12/Src/Layout.cc | 6 +- Coplt.Graphics.Native/D3d12/Src/Layout.h | 6 +- Coplt.Graphics.Native/D3d12/Src/Output.cc | 2 +- Coplt.Graphics.Native/D3d12/Src/Output.h | 2 +- Coplt.Graphics.Native/D3d12/Src/Queue.cc | 2 +- Coplt.Graphics.Native/D3d12/Src/Queue.h | 2 +- Examples/Colorful/Example.cs | 4 +- 50 files changed, 484 insertions(+), 224 deletions(-) create mode 100644 Coplt.Graphics.Core/Core/ShaderBinding.cs diff --git a/Coplt.Graphics.Core/Core/GpuBuffer.cs b/Coplt.Graphics.Core/Core/GpuBuffer.cs index 6fcaa19..2143ba5 100644 --- a/Coplt.Graphics.Core/Core/GpuBuffer.cs +++ b/Coplt.Graphics.Core/Core/GpuBuffer.cs @@ -5,7 +5,6 @@ namespace Coplt.Graphics.Core; public record struct GpuBufferCreateOptions() { - public Str8or16 Name; public required ResourcePurpose Purpose; public CpuAccess CpuAccess = CpuAccess.None; public required ulong Size; diff --git a/Coplt.Graphics.Core/Core/GpuDevice.cs b/Coplt.Graphics.Core/Core/GpuDevice.cs index 4278104..e3debec 100644 --- a/Coplt.Graphics.Core/Core/GpuDevice.cs +++ b/Coplt.Graphics.Core/Core/GpuDevice.cs @@ -1,4 +1,5 @@ using System.Buffers; +using System.Collections.Concurrent; using System.Diagnostics; using System.Text; using Coplt.Dropping; @@ -99,7 +100,7 @@ public void SetName(string name) m_name = name; fixed (char* ptr = name) { - Str8or16 str = new() { str16 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } } @@ -109,7 +110,7 @@ public void SetName(ReadOnlySpan name) m_name = null; fixed (byte* ptr = name) { - Str8or16 str = new() { str8 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } } @@ -213,6 +214,22 @@ public ShaderLayout CreateShaderLayout( } } + private readonly ConcurrentDictionary m_empty_shader_layouts = new(); + + public ShaderLayout GetEmptyShaderLayout(ShaderLayoutFlags Flags = ShaderLayoutFlags.None) => + m_empty_shader_layouts.GetOrAdd( + Flags, static (flags, self) => + { + FGetEmptyShaderLayoutOptions f_options = new() + { + Flags = (FShaderLayoutFlags)flags, + }; + FShaderLayout* ptr; + self.m_ptr->GetEmptyShaderLayout(&f_options, &ptr).TryThrow(); + return new(ptr, $"Empty Shader Layout ({flags})"); + }, this + ); + #endregion #region CreateShaderInputLayout @@ -308,6 +325,29 @@ public Shader CreateShader( #endregion + #region CreateShaderBinding + + public ShaderBinding CreateShaderBinding( + ShaderLayout Layout, + string? Name = null, ReadOnlySpan Name8 = default + ) + { + fixed (char* p_name = Name) + fixed (byte* p_name8 = Name8) + { + FShaderBindingCreateOptions f_options = new() + { + Name = new(Name, Name8, p_name, p_name8), + Layout = Layout.m_ptr, + }; + FShaderBinding* ptr; + m_ptr->CreateShaderBinding(&f_options, &ptr).TryThrow(); + return new(ptr, Name, this, Layout); + } + } + + #endregion + #region CreateMeshLayout public MeshLayout CreateMeshLayout( diff --git a/Coplt.Graphics.Core/Core/GpuOutput.cs b/Coplt.Graphics.Core/Core/GpuOutput.cs index a9e4401..692f620 100644 --- a/Coplt.Graphics.Core/Core/GpuOutput.cs +++ b/Coplt.Graphics.Core/Core/GpuOutput.cs @@ -112,7 +112,7 @@ public void SetName(string name) m_name = name; fixed (char* ptr = name) { - Str8or16 str = new() { str16 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } } @@ -122,7 +122,7 @@ public void SetName(ReadOnlySpan name) m_name = null; fixed (byte* ptr = name) { - Str8or16 str = new() { str8 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } } diff --git a/Coplt.Graphics.Core/Core/GpuQueue.cs b/Coplt.Graphics.Core/Core/GpuQueue.cs index 14c13df..0aeb939 100644 --- a/Coplt.Graphics.Core/Core/GpuQueue.cs +++ b/Coplt.Graphics.Core/Core/GpuQueue.cs @@ -71,19 +71,19 @@ public void SetName(string name) m_name = name; fixed (char* ptr = name) { - Str8or16 str = new() { str16 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } } public void SetName(ReadOnlySpan name) { + m_name = null; fixed (byte* ptr = name) { - Str8or16 str = new() { str8 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } - m_name = null; } #endregion diff --git a/Coplt.Graphics.Core/Core/GpuView.cs b/Coplt.Graphics.Core/Core/GpuView.cs index 0d12df7..54c0625 100644 --- a/Coplt.Graphics.Core/Core/GpuView.cs +++ b/Coplt.Graphics.Core/Core/GpuView.cs @@ -53,19 +53,19 @@ public void SetName(string name) m_name = name; fixed (char* ptr = name) { - Str8or16 str = new() { str16 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } } public void SetName(ReadOnlySpan name) { + m_name = null; fixed (byte* ptr = name) { - Str8or16 str = new() { str8 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } - m_name = null; } #endregion diff --git a/Coplt.Graphics.Core/Core/MeshLayout.cs b/Coplt.Graphics.Core/Core/MeshLayout.cs index 6f2ccb0..82702e4 100644 --- a/Coplt.Graphics.Core/Core/MeshLayout.cs +++ b/Coplt.Graphics.Core/Core/MeshLayout.cs @@ -122,19 +122,19 @@ public void SetName(string name) m_name = name; fixed (char* ptr = name) { - Str8or16 str = new() { str16 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } } public void SetName(ReadOnlySpan name) { + m_name = null; fixed (byte* ptr = name) { - Str8or16 str = new() { str8 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } - m_name = null; } #endregion diff --git a/Coplt.Graphics.Core/Core/Shader.cs b/Coplt.Graphics.Core/Core/Shader.cs index f2915b6..7980f1f 100644 --- a/Coplt.Graphics.Core/Core/Shader.cs +++ b/Coplt.Graphics.Core/Core/Shader.cs @@ -72,19 +72,19 @@ public void SetName(string name) m_name = name; fixed (char* ptr = name) { - Str8or16 str = new() { str16 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } } public void SetName(ReadOnlySpan name) { + m_name = null; fixed (byte* ptr = name) { - Str8or16 str = new() { str8 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } - m_name = null; } #endregion diff --git a/Coplt.Graphics.Core/Core/ShaderBinding.cs b/Coplt.Graphics.Core/Core/ShaderBinding.cs new file mode 100644 index 0000000..41e6723 --- /dev/null +++ b/Coplt.Graphics.Core/Core/ShaderBinding.cs @@ -0,0 +1,81 @@ +using Coplt.Dropping; +using Coplt.Graphics.Native; + +namespace Coplt.Graphics.Core; + +[Dropping(Unmanaged = true)] +public sealed unsafe partial class ShaderBinding +{ + #region Fields + + internal FShaderBinding* m_ptr; + internal string? m_name; + internal readonly GpuDevice m_device; + internal readonly ShaderLayout m_layout; + + #endregion + + #region Props + + public FShaderBinding* Ptr => m_ptr; + public GpuDevice Device => m_device; + public ShaderLayout Layout => m_layout; + + #endregion + + #region Ctor + + internal ShaderBinding(FShaderBinding* ptr, string? name, GpuDevice device, ShaderLayout layout) + { + m_name = name; + m_ptr = ptr; + m_device = device; + m_layout = layout; + } + + #endregion + + #region Drop + + [Drop] + private void Drop() + { + if (ExchangeUtils.ExchangePtr(ref m_ptr, null, out var ptr) is null) return; + ptr->Release(); + } + + #endregion + + #region SetName + + public void SetName(string name) + { + m_name = name; + fixed (char* ptr = name) + { + FStr8or16 str = new(ptr, name.Length); + m_ptr->SetName(&str).TryThrow(); + } + } + + public void SetName(ReadOnlySpan name) + { + m_name = null; + fixed (byte* ptr = name) + { + FStr8or16 str = new(ptr, name.Length); + m_ptr->SetName(&str).TryThrow(); + } + } + + #endregion + + #region ToString + + public override string ToString() => + m_name is null + ? $"0x{nameof(ShaderBinding)}({(nuint)m_ptr:X})" + : $"0x{nameof(ShaderBinding)}({(nuint)m_ptr:X} \"{m_name}\")"; + + #endregion +} diff --git a/Coplt.Graphics.Core/Core/ShaderInputLayout.cs b/Coplt.Graphics.Core/Core/ShaderInputLayout.cs index f4526f8..de6491b 100644 --- a/Coplt.Graphics.Core/Core/ShaderInputLayout.cs +++ b/Coplt.Graphics.Core/Core/ShaderInputLayout.cs @@ -136,19 +136,19 @@ public void SetName(string name) m_name = name; fixed (char* ptr = name) { - Str8or16 str = new() { str16 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } } public void SetName(ReadOnlySpan name) { + m_name = null; fixed (byte* ptr = name) { - Str8or16 str = new() { str8 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } - m_name = null; } #endregion diff --git a/Coplt.Graphics.Core/Core/ShaderLayout.cs b/Coplt.Graphics.Core/Core/ShaderLayout.cs index 50cfcc9..38a3166 100644 --- a/Coplt.Graphics.Core/Core/ShaderLayout.cs +++ b/Coplt.Graphics.Core/Core/ShaderLayout.cs @@ -148,19 +148,19 @@ public void SetName(string name) m_name = name; fixed (char* ptr = name) { - Str8or16 str = new() { str16 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } } public void SetName(ReadOnlySpan name) { + m_name = null; fixed (byte* ptr = name) { - Str8or16 str = new() { str8 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } - m_name = null; } #endregion diff --git a/Coplt.Graphics.Core/Core/ShaderModule.cs b/Coplt.Graphics.Core/Core/ShaderModule.cs index 20fdd1a..0d931e4 100644 --- a/Coplt.Graphics.Core/Core/ShaderModule.cs +++ b/Coplt.Graphics.Core/Core/ShaderModule.cs @@ -52,19 +52,19 @@ public void SetName(string name) m_name = name; fixed (char* ptr = name) { - Str8or16 str = new() { str16 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } } public void SetName(ReadOnlySpan name) { + m_name = null; fixed (byte* ptr = name) { - Str8or16 str = new() { str8 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } - m_name = null; } #endregion diff --git a/Coplt.Graphics.Core/Core/ShaderPipeline.cs b/Coplt.Graphics.Core/Core/ShaderPipeline.cs index 4341818..31d0055 100644 --- a/Coplt.Graphics.Core/Core/ShaderPipeline.cs +++ b/Coplt.Graphics.Core/Core/ShaderPipeline.cs @@ -50,19 +50,19 @@ public void SetName(string name) m_name = name; fixed (char* ptr = name) { - Str8or16 str = new() { str16 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } } public void SetName(ReadOnlySpan name) { + m_name = null; fixed (byte* ptr = name) { - Str8or16 str = new() { str8 = ptr, len = name.Length }; + FStr8or16 str = new(ptr, name.Length); m_ptr->SetName(&str).TryThrow(); } - m_name = null; } #endregion diff --git a/Coplt.Graphics.Core/Native/Message.cs b/Coplt.Graphics.Core/Native/Message.cs index 1a198bd..47543dd 100644 --- a/Coplt.Graphics.Core/Native/Message.cs +++ b/Coplt.Graphics.Core/Native/Message.cs @@ -1,4 +1,6 @@ -using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; using Coplt.Graphics.Utilities; namespace Coplt.Graphics.Native; @@ -9,9 +11,9 @@ public string GetString() => msg.str == null ? "" : type switch { - FMessageType.CStr8 => Marshal.PtrToStringUTF8((nint)msg.str)!, + FMessageType.CStr8 => Encoding.UTF8.GetString(MemoryMarshal.CreateReadOnlySpanFromNullTerminated(msg.str)), FMessageType.CStr16 => new string((char*)msg.str), - FMessageType.Slice8 => Marshal.PtrToStringUTF8((nint)msg.str, len)!, + FMessageType.Slice8 => Encoding.UTF8.GetString(new ReadOnlySpan(msg.str, len)), FMessageType.Slice16 => new string((char*)msg.str, 0, len), FMessageType.String8 => new String8(msg.string8).TakeString(), FMessageType.String16 => new String16(msg.string16).TakeString(), diff --git a/Coplt.Graphics.Core/Native/Native.D3d12.cs b/Coplt.Graphics.Core/Native/Native.D3d12.cs index a590ee4..3f5614e 100644 --- a/Coplt.Graphics.Core/Native/Native.D3d12.cs +++ b/Coplt.Graphics.Core/Native/Native.D3d12.cs @@ -50,10 +50,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -86,12 +86,20 @@ public FResult CreateShaderLayout([NativeTypeName("const FShaderLayoutCreateOpti return *((delegate* unmanaged[Thiscall])(lpVtbl[8]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FResult")] + public FResult GetEmptyShaderLayout([NativeTypeName("const FGetEmptyShaderLayoutOptions &")] FGetEmptyShaderLayoutOptions* options, FShaderLayout** @out) + { + FResult result; + return *((delegate* unmanaged[Thiscall])(lpVtbl[9]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] public FResult CreateShaderInputLayout([NativeTypeName("const FShaderInputLayoutCreateOptions &")] FShaderInputLayoutCreateOptions* options, FShaderInputLayout** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[9]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[10]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -99,7 +107,7 @@ public FResult CreateShaderInputLayout([NativeTypeName("const FShaderInputLayout public FResult CreateShader([NativeTypeName("const FShaderCreateOptions &")] FShaderCreateOptions* options, FShader** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[10]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[11]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -107,7 +115,7 @@ public FResult CreateShader([NativeTypeName("const FShaderCreateOptions &")] FSh public FResult CreateShaderBinding([NativeTypeName("const FShaderBindingCreateOptions &")] FShaderBindingCreateOptions* options, FShaderBinding** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[11]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[12]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -115,7 +123,7 @@ public FResult CreateShaderBinding([NativeTypeName("const FShaderBindingCreateOp public FResult CreateMeshLayout([NativeTypeName("const FMeshLayoutCreateOptions &")] FMeshLayoutCreateOptions* options, FMeshLayout** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[12]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[13]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -123,7 +131,7 @@ public FResult CreateMeshLayout([NativeTypeName("const FMeshLayoutCreateOptions public FResult CreateGraphicsPipeline([NativeTypeName("const FGraphicsShaderPipelineCreateOptions &")] FGraphicsShaderPipelineCreateOptions* options, FGraphicsShaderPipeline** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[13]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[14]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -131,7 +139,7 @@ public FResult CreateGraphicsPipeline([NativeTypeName("const FGraphicsShaderPipe public FResult CreateBuffer([NativeTypeName("const FGpuBufferCreateOptions &")] FGpuBufferCreateOptions* options, FGpuBuffer** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[14]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[15]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } public interface Interface : FGpuDevice.Interface @@ -186,10 +194,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12GpuOutput*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12GpuOutput*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -305,10 +313,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12ShaderLayout*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12ShaderLayout*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -366,10 +374,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12ShaderInputLayout*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12ShaderInputLayout*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -420,10 +428,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12MeshLayout*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12MeshLayout*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -488,10 +496,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12ShaderBinding*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12ShaderBinding*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -543,10 +551,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12PipelineState*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12PipelineState*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -618,10 +626,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12GraphicsShaderPipeline*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12GraphicsShaderPipeline*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Coplt.Graphics.Core/Native/Native.cs b/Coplt.Graphics.Core/Native/Native.cs index 36267a2..05feed7 100644 --- a/Coplt.Graphics.Core/Native/Native.cs +++ b/Coplt.Graphics.Core/Native/Native.cs @@ -142,17 +142,17 @@ public nuint AddRef() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - [return: NativeTypeName("Coplt::Str8or16")] - public Str8or16 GetStr() + [return: NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 GetStr() { - Str8or16 result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FString*)Unsafe.AsPointer(ref this), &result); + FStr8or16 result; + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FString*)Unsafe.AsPointer(ref this), &result); } public interface Interface : FUnknown.Interface { - [return: NativeTypeName("Coplt::Str8or16")] - Str8or16 GetStr(); + [return: NativeTypeName("Coplt::FStr8or16")] + FStr8or16 GetStr(); } } @@ -197,11 +197,11 @@ public nuint AddRef() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - [return: NativeTypeName("Coplt::Str8or16")] - public Str8or16 GetStr() + [return: NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 GetStr() { - Str8or16 result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FString8*)Unsafe.AsPointer(ref this), &result); + FStr8or16 result; + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FString8*)Unsafe.AsPointer(ref this), &result); } public interface Interface : FString.Interface @@ -250,11 +250,11 @@ public nuint AddRef() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - [return: NativeTypeName("Coplt::Str8or16")] - public Str8or16 GetStr() + [return: NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 GetStr() { - Str8or16 result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FString16*)Unsafe.AsPointer(ref this), &result); + FStr8or16 result; + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FString16*)Unsafe.AsPointer(ref this), &result); } public interface Interface : FString.Interface @@ -313,7 +313,7 @@ public partial struct FMessage public FMessageType type; } - public unsafe partial struct Str8 + public unsafe partial struct FStr8 { [NativeTypeName("const char *")] public byte* str; @@ -322,7 +322,7 @@ public unsafe partial struct Str8 public int len; } - public unsafe partial struct Str16 + public unsafe partial struct FStr16 { [NativeTypeName("const Char16 *")] public char* str; @@ -331,19 +331,58 @@ public unsafe partial struct Str16 public int len; } - public unsafe partial struct Str8or16 + [NativeTypeName("Coplt::u8")] + public enum FStrType : byte { - [NativeTypeName("const char *")] - public byte* str8; + Str16, + Str8, + } - [NativeTypeName("const Char16 *")] - public char* str16; + public unsafe partial struct FStr8or16 + { + [NativeTypeName("__AnonymousRecord_String_L77_C9")] + public _Anonymous_e__Union Anonymous; [NativeTypeName("Coplt::i32")] public int len; + + [NativeTypeName("Coplt::FStrType")] + public FStrType type; + + [UnscopedRef] + public ref char* str16 + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.str16; + } + } + + [UnscopedRef] + public ref byte* str8 + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.str8; + } + } + + [StructLayout(LayoutKind.Explicit)] + public unsafe partial struct _Anonymous_e__Union + { + [FieldOffset(0)] + [NativeTypeName("const Char16 *")] + public char* str16; + + [FieldOffset(0)] + [NativeTypeName("const char *")] + public byte* str8; + } } - public unsafe partial struct CStr8or16 + public unsafe partial struct FCStr8or16 { [NativeTypeName("const char *")] public byte* str8; @@ -481,16 +520,16 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGpuObject*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGpuObject*)Unsafe.AsPointer(ref this), &result, name); } public interface Interface : FUnknown.Interface { [return: NativeTypeName("Coplt::FResult")] - FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name); + FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name); } } @@ -586,8 +625,8 @@ public partial struct FGpuDeviceCreateOptions public partial struct FGpuDeviceCreateOptions { - [NativeTypeName("Coplt::Str8or16")] - public Str8or16 Name; + [NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 Name; [NativeTypeName("Coplt::FD3dFeatureLevel")] public FD3dFeatureLevel D3dFeatureLevel; @@ -645,10 +684,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -681,12 +720,20 @@ public FResult CreateShaderLayout([NativeTypeName("const FShaderLayoutCreateOpti return *((delegate* unmanaged[Thiscall])(lpVtbl[8]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FResult")] + public FResult GetEmptyShaderLayout([NativeTypeName("const FGetEmptyShaderLayoutOptions &")] FGetEmptyShaderLayoutOptions* options, FShaderLayout** @out) + { + FResult result; + return *((delegate* unmanaged[Thiscall])(lpVtbl[9]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] public FResult CreateShaderInputLayout([NativeTypeName("const FShaderInputLayoutCreateOptions &")] FShaderInputLayoutCreateOptions* options, FShaderInputLayout** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[9]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[10]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -694,7 +741,7 @@ public FResult CreateShaderInputLayout([NativeTypeName("const FShaderInputLayout public FResult CreateShader([NativeTypeName("const FShaderCreateOptions &")] FShaderCreateOptions* options, FShader** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[10]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[11]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -702,7 +749,7 @@ public FResult CreateShader([NativeTypeName("const FShaderCreateOptions &")] FSh public FResult CreateShaderBinding([NativeTypeName("const FShaderBindingCreateOptions &")] FShaderBindingCreateOptions* options, FShaderBinding** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[11]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[12]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -710,7 +757,7 @@ public FResult CreateShaderBinding([NativeTypeName("const FShaderBindingCreateOp public FResult CreateMeshLayout([NativeTypeName("const FMeshLayoutCreateOptions &")] FMeshLayoutCreateOptions* options, FMeshLayout** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[12]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[13]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -718,7 +765,7 @@ public FResult CreateMeshLayout([NativeTypeName("const FMeshLayoutCreateOptions public FResult CreateGraphicsPipeline([NativeTypeName("const FGraphicsShaderPipelineCreateOptions &")] FGraphicsShaderPipelineCreateOptions* options, FGraphicsShaderPipeline** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[13]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[14]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -726,7 +773,7 @@ public FResult CreateGraphicsPipeline([NativeTypeName("const FGraphicsShaderPipe public FResult CreateBuffer([NativeTypeName("const FGpuBufferCreateOptions &")] FGpuBufferCreateOptions* options, FGpuBuffer** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[14]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[15]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } public interface Interface : FGpuObject.Interface @@ -742,6 +789,9 @@ public interface Interface : FGpuObject.Interface [return: NativeTypeName("Coplt::FResult")] FResult CreateShaderLayout([NativeTypeName("const FShaderLayoutCreateOptions &")] FShaderLayoutCreateOptions* options, FShaderLayout** @out); + [return: NativeTypeName("Coplt::FResult")] + FResult GetEmptyShaderLayout([NativeTypeName("const FGetEmptyShaderLayoutOptions &")] FGetEmptyShaderLayoutOptions* options, FShaderLayout** @out); + [return: NativeTypeName("Coplt::FResult")] FResult CreateShaderInputLayout([NativeTypeName("const FShaderInputLayoutCreateOptions &")] FShaderInputLayoutCreateOptions* options, FShaderInputLayout** @out); @@ -906,8 +956,8 @@ public enum FShaderStageFlags : byte public unsafe partial struct FShaderModuleCreateOptions { - [NativeTypeName("Coplt::Str8or16")] - public Str8or16 Name; + [NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 Name; [NativeTypeName("Coplt::FString8 *")] public FString8* EntryPoint; @@ -966,10 +1016,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FShaderModule*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FShaderModule*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1029,10 +1079,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FShaderLayout*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FShaderLayout*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1089,10 +1139,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FShaderInputLayout*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FShaderInputLayout*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1111,8 +1161,8 @@ public interface Interface : FGpuObject.Interface public unsafe partial struct FShaderCreateOptions { - [NativeTypeName("Coplt::Str8or16")] - public Str8or16 Name; + [NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 Name; [NativeTypeName("Coplt::FShaderLayout *")] public FShaderLayout* Layout; @@ -1168,10 +1218,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FShader*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FShader*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1250,8 +1300,8 @@ public interface Interface : FGpuObject.Interface public unsafe partial struct FShaderBindingCreateOptions { - [NativeTypeName("Coplt::Str8or16")] - public Str8or16 Name; + [NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 Name; [NativeTypeName("Coplt::FShaderLayout *")] public FShaderLayout* Layout; @@ -1302,10 +1352,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FShaderBinding*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FShaderBinding*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1388,8 +1438,8 @@ public interface Interface : FUnknown.Interface public partial struct FMainQueueCreateOptions { - [NativeTypeName("Coplt::Str8or16")] - public Str8or16 Name; + [NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 Name; } [NativeTypeName("Coplt::u8")] @@ -1445,10 +1495,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGpuQueue*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGpuQueue*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -1534,8 +1584,8 @@ public enum FBufferUsage : byte public partial struct FGpuViewCreateOptions { - [NativeTypeName("Coplt::Str8or16")] - public Str8or16 Name; + [NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 Name; [NativeTypeName("Coplt::FResourcePurpose")] public FResourcePurpose Purpose; @@ -1580,10 +1630,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGpuView*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGpuView*)Unsafe.AsPointer(ref this), &result, name); } public interface Interface : FGpuObject.Interface @@ -1880,8 +1930,8 @@ public partial struct FGpuOutputFromSwapChainCreateOptions public partial struct FGpuOutputCreateOptions { - [NativeTypeName("Coplt::Str8or16")] - public Str8or16 Name; + [NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 Name; [NativeTypeName("Coplt::u32")] public uint Width; @@ -1975,10 +2025,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGpuOutput*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGpuOutput*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -2812,8 +2862,8 @@ public enum FShaderLayoutFlags : byte public unsafe partial struct FShaderLayoutCreateOptions { - [NativeTypeName("Coplt::Str8or16")] - public Str8or16 Name; + [NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 Name; [NativeTypeName("Coplt::u32")] public uint Count; @@ -2825,10 +2875,16 @@ public unsafe partial struct FShaderLayoutCreateOptions public FShaderLayoutFlags Flags; } + public partial struct FGetEmptyShaderLayoutOptions + { + [NativeTypeName("Coplt::FShaderLayoutFlags")] + public FShaderLayoutFlags Flags; + } + public unsafe partial struct FShaderInputLayoutCreateOptions { - [NativeTypeName("Coplt::Str8or16")] - public Str8or16 Name; + [NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 Name; [NativeTypeName("Coplt::FShaderInputLayoutElement *")] public FShaderInputLayoutElement* Element; @@ -2839,8 +2895,8 @@ public unsafe partial struct FShaderInputLayoutCreateOptions public unsafe partial struct FMeshLayoutCreateOptions { - [NativeTypeName("Coplt::Str8or16")] - public Str8or16 Name; + [NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 Name; [NativeTypeName("Coplt::FMeshBufferDefine *")] public FMeshBufferDefine* Buffers; @@ -2891,10 +2947,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FMeshLayout*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FMeshLayout*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -2933,8 +2989,8 @@ public interface Interface : FGpuObject.Interface public unsafe partial struct FShaderPipelineCreateOptions { - [NativeTypeName("Coplt::Str8or16")] - public Str8or16 Name; + [NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 Name; [NativeTypeName("Coplt::FShader *")] public FShader* Shader; @@ -2976,10 +3032,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FShaderPipeline*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FShaderPipeline*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -3052,10 +3108,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FComputeShaderPipeline*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FComputeShaderPipeline*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -3132,10 +3188,10 @@ public nuint AddRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetName([NativeTypeName("const Str8or16 &")] Str8or16* name) + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGraphicsShaderPipeline*)Unsafe.AsPointer(ref this), &result, name); + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGraphicsShaderPipeline*)Unsafe.AsPointer(ref this), &result, name); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Coplt.Graphics.Core/Native/Str8or16.cs b/Coplt.Graphics.Core/Native/Str8or16.cs index 38472da..7524373 100644 --- a/Coplt.Graphics.Core/Native/Str8or16.cs +++ b/Coplt.Graphics.Core/Native/Str8or16.cs @@ -1,11 +1,36 @@ namespace Coplt.Graphics.Native; -public unsafe partial struct Str8or16 +public unsafe partial struct FStr8or16 { - public Str8or16(string? name, ReadOnlySpan name8, char* p_name, byte* p_name8) + public FStr8or16(byte* p_name8, int size) { - str8 = name != null ? null : name8.Length > 0 ? p_name8 : null; + type = FStrType.Str8; + str8 = p_name8; + len = size; + } + + public FStr8or16(char* p_name, int size) + { + type = FStrType.Str16; str16 = p_name; - len = name?.Length ?? name8.Length; + len = size; + } + + public FStr8or16(string? name, ReadOnlySpan name8, char* p_name, byte* p_name8) + { + type = name == null && name8.Length > 0 ? FStrType.Str8 : FStrType.Str16; + switch (type) + { + case FStrType.Str16: + str16 = p_name; + len = name?.Length ?? 0; + break; + case FStrType.Str8: + str8 = p_name8; + len = name8.Length; + break; + default: + throw new ArgumentOutOfRangeException(); + } } } diff --git a/Coplt.Graphics.Native/Api/CMakeLists.txt b/Coplt.Graphics.Native/Api/CMakeLists.txt index 484172b..fd6f952 100644 --- a/Coplt.Graphics.Native/Api/CMakeLists.txt +++ b/Coplt.Graphics.Native/Api/CMakeLists.txt @@ -54,4 +54,5 @@ target_link_libraries(${target_name} glm::glm mimalloc-static fmt::fmt + concurrentqueue ) diff --git a/Coplt.Graphics.Native/Api/FFI/Binding.h b/Coplt.Graphics.Native/Api/FFI/Binding.h index f500909..8ca85ad 100644 --- a/Coplt.Graphics.Native/Api/FFI/Binding.h +++ b/Coplt.Graphics.Native/Api/FFI/Binding.h @@ -8,7 +8,7 @@ namespace Coplt { struct FShaderBindingCreateOptions { - Str8or16 Name{}; + FStr8or16 Name{}; FShaderLayout* Layout{}; }; diff --git a/Coplt.Graphics.Native/Api/FFI/Device.h b/Coplt.Graphics.Native/Api/FFI/Device.h index af6920e..fabc56e 100644 --- a/Coplt.Graphics.Native/Api/FFI/Device.h +++ b/Coplt.Graphics.Native/Api/FFI/Device.h @@ -35,7 +35,7 @@ namespace Coplt struct FGpuDeviceCreateOptions { // 可选 - Str8or16 Name{}; + FStr8or16 Name{}; // 仅 dx 后端时可用 FD3dFeatureLevel D3dFeatureLevel{}; // 仅 vk 后端时可用 @@ -54,6 +54,7 @@ namespace Coplt virtual FResult CreateShaderModule(const FShaderModuleCreateOptions& options, FShaderModule** out) noexcept = 0; virtual FResult CreateShaderLayout(const FShaderLayoutCreateOptions& options, FShaderLayout** out) noexcept = 0; + virtual FResult GetEmptyShaderLayout(const FGetEmptyShaderLayoutOptions& options, FShaderLayout** out) noexcept = 0; virtual FResult CreateShaderInputLayout( const FShaderInputLayoutCreateOptions& options, FShaderInputLayout** out ) noexcept = 0; diff --git a/Coplt.Graphics.Native/Api/FFI/GpuObject.h b/Coplt.Graphics.Native/Api/FFI/GpuObject.h index d8c3f2b..bb365e2 100644 --- a/Coplt.Graphics.Native/Api/FFI/GpuObject.h +++ b/Coplt.Graphics.Native/Api/FFI/GpuObject.h @@ -8,6 +8,6 @@ namespace Coplt { COPLT_INTERFACE_DEFINE(FGpuObject, "9fc6890b-e9a2-4f4a-9217-a14a4223a715", FUnknown) { - virtual FResult SetName(const Str8or16& name) noexcept = 0; + virtual FResult SetName(const FStr8or16& name) noexcept = 0; }; } diff --git a/Coplt.Graphics.Native/Api/FFI/Layout.h b/Coplt.Graphics.Native/Api/FFI/Layout.h index cc407b6..fd91869 100644 --- a/Coplt.Graphics.Native/Api/FFI/Layout.h +++ b/Coplt.Graphics.Native/Api/FFI/Layout.h @@ -76,7 +76,7 @@ namespace Coplt struct FShaderLayoutCreateOptions { - Str8or16 Name{}; + FStr8or16 Name{}; u32 Count{}; FShaderLayoutItemDefine* Items{}; // todo 静态采样器 @@ -84,6 +84,11 @@ namespace Coplt FShaderLayoutFlags Flags{}; }; + struct FGetEmptyShaderLayoutOptions + { + FShaderLayoutFlags Flags{}; + }; + COPLT_INTERFACE_DEFINE(FShaderLayout, "552a498e-8f3a-47ff-a335-7af2de0901e8", FGpuObject) { FShaderLayoutFlags Flags{}; @@ -101,7 +106,7 @@ namespace Coplt struct FShaderInputLayoutCreateOptions { - Str8or16 Name{}; + FStr8or16 Name{}; FShaderInputLayoutElement* Element{}; u32 Count{}; }; @@ -121,7 +126,7 @@ namespace Coplt struct FMeshLayoutCreateOptions { - Str8or16 Name{}; + FStr8or16 Name{}; // Buffers 按顺序定义到 InputSlot,不允许随机隔空的 InputSlot FMeshBufferDefine* Buffers{}; FMeshBufferElement* Elements{}; diff --git a/Coplt.Graphics.Native/Api/FFI/Output.h b/Coplt.Graphics.Native/Api/FFI/Output.h index 98fcde3..7024011 100644 --- a/Coplt.Graphics.Native/Api/FFI/Output.h +++ b/Coplt.Graphics.Native/Api/FFI/Output.h @@ -46,7 +46,7 @@ namespace Coplt struct FGpuOutputCreateOptions { - Str8or16 Name{}; + FStr8or16 Name{}; u32 Width{}; u32 Height{}; FGraphicsFormat Format{}; diff --git a/Coplt.Graphics.Native/Api/FFI/Pipeline.h b/Coplt.Graphics.Native/Api/FFI/Pipeline.h index c48594e..03dad7b 100644 --- a/Coplt.Graphics.Native/Api/FFI/Pipeline.h +++ b/Coplt.Graphics.Native/Api/FFI/Pipeline.h @@ -8,7 +8,7 @@ namespace Coplt { struct FShaderPipelineCreateOptions { - Str8or16 Name{}; + FStr8or16 Name{}; FShader* Shader{}; }; diff --git a/Coplt.Graphics.Native/Api/FFI/Queue.h b/Coplt.Graphics.Native/Api/FFI/Queue.h index d3c845a..81f7f69 100644 --- a/Coplt.Graphics.Native/Api/FFI/Queue.h +++ b/Coplt.Graphics.Native/Api/FFI/Queue.h @@ -10,7 +10,7 @@ namespace Coplt struct FMainQueueCreateOptions { // 可选 - Str8or16 Name{}; + FStr8or16 Name{}; }; enum class FGpuQueueType : u8 diff --git a/Coplt.Graphics.Native/Api/FFI/Resource.h b/Coplt.Graphics.Native/Api/FFI/Resource.h index 41dffcd..2365f82 100644 --- a/Coplt.Graphics.Native/Api/FFI/Resource.h +++ b/Coplt.Graphics.Native/Api/FFI/Resource.h @@ -64,7 +64,7 @@ namespace Coplt struct FGpuViewCreateOptions { - Str8or16 Name{}; + FStr8or16 Name{}; FResourcePurpose Purpose{}; }; diff --git a/Coplt.Graphics.Native/Api/FFI/Shader.h b/Coplt.Graphics.Native/Api/FFI/Shader.h index a5371ad..6ae15f6 100644 --- a/Coplt.Graphics.Native/Api/FFI/Shader.h +++ b/Coplt.Graphics.Native/Api/FFI/Shader.h @@ -26,7 +26,7 @@ namespace Coplt struct FShaderModuleCreateOptions { - Str8or16 Name{}; + FStr8or16 Name{}; // 可选 FString8* EntryPoint{}; // 需要自己保证数据内容符合当前使用的后端,比如 dx 使用的 dxil,vk 使用的 spv @@ -53,7 +53,7 @@ namespace Coplt struct FShaderCreateOptions { - Str8or16 Name{}; + FStr8or16 Name{}; // 此处是借用,不传递所有权 FShaderLayout* Layout{}; // 此处是借用,不传递所有权 diff --git a/Coplt.Graphics.Native/Api/FFI/String.h b/Coplt.Graphics.Native/Api/FFI/String.h index c00989f..637776d 100644 --- a/Coplt.Graphics.Native/Api/FFI/String.h +++ b/Coplt.Graphics.Native/Api/FFI/String.h @@ -8,11 +8,11 @@ namespace Coplt { - struct Str8or16; + struct FStr8or16; COPLT_INTERFACE_DEFINE(FString, "5a478800-e7da-4a6b-b428-1e3fda55997f", FUnknown) { - virtual Str8or16 GetStr() const noexcept = 0; + virtual FStr8or16 GetStr() const noexcept = 0; }; COPLT_INTERFACE_DEFINE(FString8, "63c7fc71-d775-42bb-891a-69dbb26e75c5", FString) @@ -54,87 +54,108 @@ namespace Coplt FMessageType type; }; - struct Str8 + struct FStr8 { const char* str; i32 len; }; - struct Str16 + struct FStr16 { const Char16* str; i32 len; }; - struct Str8or16 + enum class FStrType : u8 { - const char* str8; - const Char16* str16; + Str16, + Str8, + }; + + struct FStr8or16 + { + union + { + const Char16* str16; + const char* str8; + }; + i32 len; + FStrType type; #ifdef FFI_SRC - Str8or16() = default; + FStr8or16() = default; - explicit Str8or16(const char* ptr, const usize len) : str8(ptr), str16(nullptr), len(len) + explicit FStr8or16(const char* ptr, const usize len) + : str8(ptr), len(static_cast(static_cast(len))), type(FStrType::Str8) { } - explicit Str8or16(const Char8* ptr, const usize len) - : str8(reinterpret_cast(ptr)), str16(nullptr), len(len) + explicit FStr8or16(const Char8* ptr, const usize len) + : str8(reinterpret_cast(ptr)), + len(static_cast(static_cast(len))), type(FStrType::Str8) { } - explicit Str8or16(const Char16* ptr, const usize len) : str8(nullptr), str16(ptr), len(len) + explicit FStr8or16(const Char16* ptr, const usize len) + : str16(ptr), len(static_cast(static_cast(len))), type(FStrType::Str16) { } - explicit Str8or16(const std::string& str) : str8(str.c_str()), str16(nullptr), len(str.length()) + explicit FStr8or16(const std::string& str) + : str8(str.c_str()), len(static_cast(static_cast(str.length()))), type(FStrType::Str8) { } template - explicit Str8or16(const char (&str)[N]) : str8(str), str16(nullptr), len(N) + explicit FStr8or16(const char (&str)[N]) + : str8(str), len(static_cast(static_cast(N))), type(FStrType::Str8) { } #ifdef _WINDOWS - explicit Str8or16(const wchar_t* ptr, const usize len) - : str8(nullptr), str16(reinterpret_cast(ptr)), len(len) + explicit FStr8or16(const wchar_t* ptr, const usize len) + : str16(reinterpret_cast(ptr)), + len(static_cast(static_cast(len))), type(FStrType::Str16) { } - explicit Str8or16(const std::wstring& str) - : str8(nullptr), str16(reinterpret_cast(str.c_str())), len(str.length()) + explicit FStr8or16(const std::wstring& str) + : str16(reinterpret_cast(str.c_str())), + len(static_cast(static_cast(str.length()))), type(FStrType::Str16) { } template - explicit Str8or16(const wchar_t (&str)[N]) : str8(nullptr), str16(reinterpret_cast(str)), len(N) + explicit FStr8or16(const wchar_t (&str)[N]) : + str16(reinterpret_cast(str)), + len(static_cast(static_cast(N))), type(FStrType::Str16) { } + #endif - bool has8() const + bool is8() const { - return str8 != nullptr; + return type == FStrType::Str8; } - bool has16() const + bool is16() const { - return str16 != nullptr; + return type == FStrType::Str16; } bool is_null() const { - return str8 == nullptr && str16 == nullptr; + return str16 == nullptr; } FString* ToString() const; #endif }; - struct CStr8or16 + struct FCStr8or16 { const char* str8; const Char16* str16; diff --git a/Coplt.Graphics.Native/Api/Include/Object.h b/Coplt.Graphics.Native/Api/Include/Object.h index 6894250..537922c 100644 --- a/Coplt.Graphics.Native/Api/Include/Object.h +++ b/Coplt.Graphics.Native/Api/Include/Object.h @@ -438,10 +438,10 @@ namespace Coplt mutable std::atomic_size_t m_strong{1}; mutable std::atomic_size_t m_weak{1}; - COPLT_NO_INLINE void DropSlow(void* self, void* object_start, void (*free)(void*, void*)) const noexcept + COPLT_NO_INLINE void DropSlow(void* self, void* object_start, void (*p_free)(void*, void*)) const noexcept { this->~ObjectRcPartialImpl(); - ReleaseWeak(self, object_start, free); + ReleaseWeak(self, object_start, p_free); } size_t AddRef() const noexcept @@ -449,11 +449,11 @@ namespace Coplt return m_strong.fetch_add(1, std::memory_order_relaxed); } - size_t Release(void* self, void* object_start, void (*free)(void*, void*)) const noexcept + size_t Release(void* self, void* object_start, void (*p_free)(void*, void*)) const noexcept { const size_t r = m_strong.fetch_sub(1, std::memory_order_release); if (r != 1) return r; - DropSlow(self, object_start, free); + DropSlow(self, object_start, p_free); return r; } @@ -462,11 +462,11 @@ namespace Coplt return m_weak.fetch_add(1, std::memory_order_relaxed); } - size_t ReleaseWeak(void* self, void* object_start, void (*free)(void*, void*)) const noexcept + size_t ReleaseWeak(void* self, void* object_start, void (*p_free)(void*, void*)) const noexcept { const size_t r = m_weak.fetch_sub(1, std::memory_order_release); if (r != 1) return r; - free(self, object_start); + p_free(self, object_start); return r; } diff --git a/Coplt.Graphics.Native/Api/Src/Shader.cc b/Coplt.Graphics.Native/Api/Src/Shader.cc index 7f0acd4..2bedaa0 100644 --- a/Coplt.Graphics.Native/Api/Src/Shader.cc +++ b/Coplt.Graphics.Native/Api/Src/Shader.cc @@ -28,7 +28,7 @@ void ShaderModule::Free(void* self) mi_free_aligned(self, alignof(Self)); } -FResult ShaderModule::SetName(const Str8or16& name) noexcept +FResult ShaderModule::SetName(const FStr8or16& name) noexcept { return FResult::None(); } @@ -95,7 +95,7 @@ Shader::Shader(Rc&& device, const FShaderCreateOptions& options) : m throw RuntimeException("Having a task stage must also have a mesh stage"); } -FResult Shader::SetName(const Str8or16& name) noexcept +FResult Shader::SetName(const FStr8or16& name) noexcept { return FResult::None(); } diff --git a/Coplt.Graphics.Native/Api/Src/Shader.h b/Coplt.Graphics.Native/Api/Src/Shader.h index 03e6b18..fafc575 100644 --- a/Coplt.Graphics.Native/Api/Src/Shader.h +++ b/Coplt.Graphics.Native/Api/Src/Shader.h @@ -22,7 +22,7 @@ namespace Coplt void Free(void* self) override; - FResult SetName(const Str8or16& name) noexcept override; + FResult SetName(const FStr8or16& name) noexcept override; // 可空 FString8* GetEntryPoint() noexcept override; @@ -40,7 +40,7 @@ namespace Coplt explicit Shader(Rc&& device, const FShaderCreateOptions& options); - FResult SetName(const Str8or16& name) noexcept override; + FResult SetName(const FStr8or16& name) noexcept override; FShaderLayout* Layout() noexcept override; diff --git a/Coplt.Graphics.Native/Api/Src/String.cc b/Coplt.Graphics.Native/Api/Src/String.cc index 3d1ea40..8112967 100644 --- a/Coplt.Graphics.Native/Api/Src/String.cc +++ b/Coplt.Graphics.Native/Api/Src/String.cc @@ -2,9 +2,14 @@ using namespace Coplt; -FString* Str8or16::ToString() const +FString* FStr8or16::ToString() const { - if (has16()) return String16::Create(str16, len); - if (has8()) return String8::Create(str8, len); + switch (type) + { + case FStrType::Str16: + return String16::Create(str16, len); + case FStrType::Str8: + return String8::Create(str8, len); + } return nullptr; } diff --git a/Coplt.Graphics.Native/Api/Src/String.h b/Coplt.Graphics.Native/Api/Src/String.h index 90ad662..8f7a374 100644 --- a/Coplt.Graphics.Native/Api/Src/String.h +++ b/Coplt.Graphics.Native/Api/Src/String.h @@ -151,9 +151,9 @@ namespace Coplt return std::string(c_str(), m_size); } - Str8or16 GetStr() const noexcept override + FStr8or16 GetStr() const noexcept override { - return Str8or16(c_str(), size()); + return FStr8or16(c_str(), size()); } }; @@ -199,9 +199,9 @@ namespace Coplt } #endif - Str8or16 GetStr() const noexcept override + FStr8or16 GetStr() const noexcept override { - return Str8or16(data(), size()); + return FStr8or16(data(), size()); } }; @@ -216,9 +216,9 @@ namespace Coplt { } - Str8or16 GetStr() const noexcept override + FStr8or16 GetStr() const noexcept override { - return Str8or16(data(), size()); + return FStr8or16(data(), size()); } }; @@ -234,9 +234,9 @@ namespace Coplt { } - Str8or16 GetStr() const noexcept override + FStr8or16 GetStr() const noexcept override { - return Str8or16(data(), size()); + return FStr8or16(data(), size()); } }; #endif diff --git a/Coplt.Graphics.Native/D3d12/Include/Utils.h b/Coplt.Graphics.Native/D3d12/Include/Utils.h index 3957a54..b09fecd 100644 --- a/Coplt.Graphics.Native/D3d12/Include/Utils.h +++ b/Coplt.Graphics.Native/D3d12/Include/Utils.h @@ -53,7 +53,7 @@ namespace Coplt T str; }; - inline auto SetNameEx(const Str8or16& str) + inline auto SetNameEx(const FStr8or16& str) { return SetName_t{&str}; } @@ -64,14 +64,13 @@ namespace Coplt return obj.Get() >> arg; } - inline HRESULT operator >>(ID3D12Object* obj, const SetName_t arg) + inline HRESULT operator >>(ID3D12Object* obj, const SetName_t arg) { - if (arg.str->has16()) + switch (arg.str->type) { + case FStrType::Str16: return obj->SetPrivateData(WKPDID_D3DDebugObjectNameW, static_cast(arg.str->len * 2), arg.str->str16); - } - else if (arg.str->has8()) - { + case FStrType::Str8: return obj->SetPrivateData(WKPDID_D3DDebugObjectName, static_cast(arg.str->len), arg.str->str8); } return S_OK; diff --git a/Coplt.Graphics.Native/D3d12/Src/Binding.cc b/Coplt.Graphics.Native/D3d12/Src/Binding.cc index e5f54c2..164d0d0 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Binding.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Binding.cc @@ -19,7 +19,7 @@ D3d12ShaderBinding::D3d12ShaderBinding( m_views = std::vector>(item_metas.size(), {}); } -FResult D3d12ShaderBinding::SetName(const Str8or16& name) noexcept +FResult D3d12ShaderBinding::SetName(const FStr8or16& name) noexcept { return FResult::None(); } diff --git a/Coplt.Graphics.Native/D3d12/Src/Binding.h b/Coplt.Graphics.Native/D3d12/Src/Binding.h index 1f5ff45..45c0b45 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Binding.h +++ b/Coplt.Graphics.Native/D3d12/Src/Binding.h @@ -18,7 +18,7 @@ namespace Coplt explicit D3d12ShaderBinding(Rc&& device, const FShaderBindingCreateOptions& options); - FResult SetName(const Str8or16& name) noexcept override; + FResult SetName(const FStr8or16& name) noexcept override; FResult Set(u32 count, const FShaderBindingBatchSet* bindings) noexcept override; diff --git a/Coplt.Graphics.Native/D3d12/Src/Buffer.cc b/Coplt.Graphics.Native/D3d12/Src/Buffer.cc index bc5c1b3..46e3f37 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Buffer.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Buffer.cc @@ -40,7 +40,7 @@ D3d12GpuBuffer::D3d12GpuBuffer(Rc&& device, const FGpuBufferCrea } } -FResult D3d12GpuBuffer::SetName(const Str8or16& name) noexcept +FResult D3d12GpuBuffer::SetName(const FStr8or16& name) noexcept { return feb([&] { diff --git a/Coplt.Graphics.Native/D3d12/Src/Buffer.h b/Coplt.Graphics.Native/D3d12/Src/Buffer.h index 4ba6e3c..253d0fe 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Buffer.h +++ b/Coplt.Graphics.Native/D3d12/Src/Buffer.h @@ -16,7 +16,7 @@ namespace Coplt explicit D3d12GpuBuffer(Rc&& device, const FGpuBufferCreateOptions& options); - FResult SetName(const Str8or16& name) noexcept override; + FResult SetName(const FStr8or16& name) noexcept override; FResult GetCurrentResourcePtr(void* out) const noexcept override; }; diff --git a/Coplt.Graphics.Native/D3d12/Src/Context.cc b/Coplt.Graphics.Native/D3d12/Src/Context.cc index af3f589..ff428e3 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Context.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Context.cc @@ -18,7 +18,7 @@ D3d12FrameContext::D3d12FrameContext(Rc&& queue) : m_queue(std::m ); if (m_device->Debug()) { - chr | m_command_allocator >> SetNameEx(Str8or16(fmt::format(L"Frame Context ({}) Command Allocator", m_id))); + chr | m_command_allocator >> SetNameEx(FStr8or16(fmt::format(L"Frame Context ({}) Command Allocator", m_id))); } } @@ -43,7 +43,7 @@ FResult D3d12FrameContext::GrowUploadBuffer(const u64 min_required_size) noexcep const auto name = fmt::format( L"Frame Context ({}) Upload Buffer ({})", m_id, upload_buffer.m_size ); - chr | upload_buffer.m_resource.m_resource >> SetNameEx(Str8or16(name)); + chr | upload_buffer.m_resource.m_resource >> SetNameEx(FStr8or16(name)); } constexpr D3D12_RANGE read_range{.Begin = 0, .End = 0}; chr | upload_buffer.m_resource.m_resource->Map(0, &read_range, &mapped_ptr); diff --git a/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.h b/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.h index 4025a48..0a59129 100644 --- a/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.h +++ b/Coplt.Graphics.Native/D3d12/Src/DescriptorManager.h @@ -1,4 +1,7 @@ #pragma once + +#include + #include "Device.h" namespace Coplt diff --git a/Coplt.Graphics.Native/D3d12/Src/Device.cc b/Coplt.Graphics.Native/D3d12/Src/Device.cc index 8c3d979..3b3da96 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Device.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Device.cc @@ -187,7 +187,7 @@ D3d12GpuDevice::~D3d12GpuDevice() } } -FResult D3d12GpuDevice::SetName(const Str8or16& name) noexcept +FResult D3d12GpuDevice::SetName(const FStr8or16& name) noexcept { return feb([&] { @@ -209,7 +209,7 @@ const Rc& D3d12GpuDevice::GetEmptyLayout(FShaderLayoutFlags f { const auto name = fmt::format(L"Empty Layout {}", static_cast(flags)); FShaderLayoutCreateOptions options{}; - options.Name = Str8or16(name); + options.Name = FStr8or16(name); options.Flags = flags; p = Rc(new D3d12ShaderLayout(this->CloneThis(), options)); }); @@ -220,7 +220,7 @@ const Rc& D3d12GpuDevice::GetEmptyMeshLayout() if (m_empty_mesh_layout == nullptr) { FMeshLayoutCreateOptions options{}; - options.Name = Str8or16(L"Empty Mesh Layout"); + options.Name = FStr8or16(L"Empty Mesh Layout"); m_empty_mesh_layout = Rc(new D3d12MeshLayout(this->CloneThis(), options)); } return m_empty_mesh_layout; @@ -250,6 +250,15 @@ FResult D3d12GpuDevice::CreateShaderLayout(const FShaderLayoutCreateOptions& opt }); } +FResult D3d12GpuDevice::GetEmptyShaderLayout(const FGetEmptyShaderLayoutOptions& options, FShaderLayout** out) noexcept +{ + return feb([&] + { + Rc r = GetEmptyLayout(options.Flags); + *out = r.leak(); + }); +} + FResult D3d12GpuDevice::CreateShaderInputLayout(const FShaderInputLayoutCreateOptions& options, FShaderInputLayout** out) noexcept { diff --git a/Coplt.Graphics.Native/D3d12/Src/Device.h b/Coplt.Graphics.Native/D3d12/Src/Device.h index b79616c..19f0f72 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Device.h +++ b/Coplt.Graphics.Native/D3d12/Src/Device.h @@ -47,7 +47,7 @@ namespace Coplt return m_debug_controller != nullptr; } - FResult SetName(const Str8or16& name) noexcept override; + FResult SetName(const FStr8or16& name) noexcept override; void* GetRawDevice() noexcept override; @@ -58,6 +58,9 @@ namespace Coplt FResult CreateShaderModule(const FShaderModuleCreateOptions& options, FShaderModule** out) noexcept override; FResult CreateShaderLayout(const FShaderLayoutCreateOptions& options, FShaderLayout** out) noexcept override; + FResult GetEmptyShaderLayout( + const FGetEmptyShaderLayoutOptions& options, FShaderLayout** out + ) noexcept override; FResult CreateShaderInputLayout( const FShaderInputLayoutCreateOptions& options, FShaderInputLayout** out ) noexcept override; diff --git a/Coplt.Graphics.Native/D3d12/Src/GraphicsPipeline.cc b/Coplt.Graphics.Native/D3d12/Src/GraphicsPipeline.cc index 69da5f2..bc9867b 100644 --- a/Coplt.Graphics.Native/D3d12/Src/GraphicsPipeline.cc +++ b/Coplt.Graphics.Native/D3d12/Src/GraphicsPipeline.cc @@ -219,7 +219,7 @@ D3d12GraphicsShaderPipeline::D3d12GraphicsShaderPipeline( m_input_slots = std::move(input_slots); } -FResult D3d12GraphicsShaderPipeline::SetName(const Str8or16& name) noexcept +FResult D3d12GraphicsShaderPipeline::SetName(const FStr8or16& name) noexcept { return feb([&] { diff --git a/Coplt.Graphics.Native/D3d12/Src/GraphicsPipeline.h b/Coplt.Graphics.Native/D3d12/Src/GraphicsPipeline.h index 9050ffc..4ae8b3d 100644 --- a/Coplt.Graphics.Native/D3d12/Src/GraphicsPipeline.h +++ b/Coplt.Graphics.Native/D3d12/Src/GraphicsPipeline.h @@ -28,7 +28,7 @@ namespace Coplt Rc&& device, const FGraphicsShaderPipelineCreateOptions& options ); - FResult SetName(const Str8or16& name) noexcept override; + FResult SetName(const FStr8or16& name) noexcept override; void* GetPipelineStatePtr() noexcept override; diff --git a/Coplt.Graphics.Native/D3d12/Src/Layout.cc b/Coplt.Graphics.Native/D3d12/Src/Layout.cc index 35edd5e..6e72d2b 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Layout.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Layout.cc @@ -197,7 +197,7 @@ D3d12ShaderLayout::D3d12ShaderLayout(Rc&& device, const FShaderL } } -FResult D3d12ShaderLayout::SetName(const Str8or16& name) noexcept +FResult D3d12ShaderLayout::SetName(const FStr8or16& name) noexcept { return feb([&] { @@ -241,7 +241,7 @@ D3d12ShaderInputLayout::D3d12ShaderInputLayout( } } -FResult D3d12ShaderInputLayout::SetName(const Str8or16& name) noexcept +FResult D3d12ShaderInputLayout::SetName(const FStr8or16& name) noexcept { return FResult::None(); } @@ -275,7 +275,7 @@ D3d12MeshLayout::D3d12MeshLayout(Rc&& device, const FMeshLayoutC } } -FResult D3d12MeshLayout::SetName(const Str8or16& name) noexcept +FResult D3d12MeshLayout::SetName(const FStr8or16& name) noexcept { return FResult::None(); } diff --git a/Coplt.Graphics.Native/D3d12/Src/Layout.h b/Coplt.Graphics.Native/D3d12/Src/Layout.h index 9449b85..d22fdaf 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Layout.h +++ b/Coplt.Graphics.Native/D3d12/Src/Layout.h @@ -107,7 +107,7 @@ namespace Coplt explicit D3d12ShaderLayout(Rc&& device, const FShaderLayoutCreateOptions& options); - FResult SetName(const Str8or16& name) noexcept override; + FResult SetName(const FStr8or16& name) noexcept override; void* GetRootSignaturePtr() noexcept override; @@ -125,7 +125,7 @@ namespace Coplt explicit D3d12ShaderInputLayout(Rc&& device, const FShaderInputLayoutCreateOptions& options); - FResult SetName(const Str8or16& name) noexcept override; + FResult SetName(const FStr8or16& name) noexcept override; const FShaderInputLayoutElement* GetElements(u32* out_count) noexcept override; }; @@ -139,7 +139,7 @@ namespace Coplt explicit D3d12MeshLayout(Rc&& device, const FMeshLayoutCreateOptions& options); - FResult SetName(const Str8or16& name) noexcept override; + FResult SetName(const FStr8or16& name) noexcept override; const FMeshBufferDefine* GetBuffers(u32* out_count) const noexcept override; const FMeshBufferElement* GetElements(u32* out_count) const noexcept override; diff --git a/Coplt.Graphics.Native/D3d12/Src/Output.cc b/Coplt.Graphics.Native/D3d12/Src/Output.cc index 803f64b..fec418b 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Output.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Output.cc @@ -174,7 +174,7 @@ FGraphicsFormat D3d12GpuSwapChainOutput::SelectFormat( return FGraphicsFormat::R8G8B8A8_UNorm; } -FResult D3d12GpuSwapChainOutput::SetName(const Str8or16& name) noexcept +FResult D3d12GpuSwapChainOutput::SetName(const FStr8or16& name) noexcept { return feb([&] { diff --git a/Coplt.Graphics.Native/D3d12/Src/Output.h b/Coplt.Graphics.Native/D3d12/Src/Output.h index d1e5e1c..231395e 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Output.h +++ b/Coplt.Graphics.Native/D3d12/Src/Output.h @@ -55,7 +55,7 @@ namespace Coplt static FGraphicsFormat SelectFormat(const FGpuOutputCreateOptions& options, bool& is_hdr); - FResult SetName(const Str8or16& name) noexcept override; + FResult SetName(const FStr8or16& name) noexcept override; FResult SetVSync(b8 Enable) noexcept override; diff --git a/Coplt.Graphics.Native/D3d12/Src/Queue.cc b/Coplt.Graphics.Native/D3d12/Src/Queue.cc index a247320..1a22f12 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Queue.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Queue.cc @@ -41,7 +41,7 @@ D3d12GpuQueue::D3d12GpuQueue( } } -FResult D3d12GpuQueue::SetName(const Str8or16& name) noexcept +FResult D3d12GpuQueue::SetName(const FStr8or16& name) noexcept { return feb([&] { diff --git a/Coplt.Graphics.Native/D3d12/Src/Queue.h b/Coplt.Graphics.Native/D3d12/Src/Queue.h index fcee695..a9c759f 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Queue.h +++ b/Coplt.Graphics.Native/D3d12/Src/Queue.h @@ -27,7 +27,7 @@ namespace Coplt explicit D3d12GpuQueue(Rc&& device, const FMainQueueCreateOptions& options); - FResult SetName(const Str8or16& name) noexcept override; + FResult SetName(const FStr8or16& name) noexcept override; void* GetRawQueue() noexcept override; diff --git a/Examples/Colorful/Example.cs b/Examples/Colorful/Example.cs index 99515b6..7e0b572 100644 --- a/Examples/Colorful/Example.cs +++ b/Examples/Colorful/Example.cs @@ -9,14 +9,16 @@ public class Example(IntPtr Handle, uint Width, uint Height) : ExampleBase(Handl { private Shader Shader = null!; private GraphicsShaderPipeline Pipeline = null!; + private ShaderBinding ShaderBinding = null!; public override string Name => "Colorful"; protected override async Task LoadResources(CommandList cmd) { var modules = await LoadShaderModules("Shader", [ShaderStage.Vertex, ShaderStage.Pixel]); Shader = Device.CreateShader( - modules, null, Device.CreateShaderInputLayout([]) + modules, Device.CreateShaderLayout([]), Device.CreateShaderInputLayout([]) ); + ShaderBinding = Device.CreateShaderBinding(Shader.Layout!, Name: Name); Pipeline = Device.CreateGraphicsShaderPipeline( Shader, new() { From 8aaa3294d74ad7cb1f4444c301a00f0292cca256 Mon Sep 17 00:00:00 2001 From: U2A5F Date: Tue, 25 Feb 2025 16:13:05 +0800 Subject: [PATCH 08/23] save --- .../Coplt.Graphics.Core.csproj | 1 + Coplt.Graphics.Core/Core/GpuDevice.cs | 4 + Coplt.Graphics.Core/Core/ShaderBinding.cs | 56 +++++++- Coplt.Graphics.Core/Core/View.cs | 26 ++++ Coplt.Graphics.Core/Native/Native.D3d12.cs | 9 +- Coplt.Graphics.Core/Native/Native.cs | 52 ++++++- Coplt.Graphics.Native/Api/FFI/Binding.h | 4 +- Coplt.Graphics.Native/Api/FFI/Layout.h | 43 +++++- Coplt.Graphics.Native/Api/FFI/Resource.h | 15 ++ Coplt.Graphics.Native/Api/Include/Error.h | 8 ++ Coplt.Graphics.Native/Api/Src/Shader.cc | 33 +++-- Coplt.Graphics.Native/D3d12/CMakeLists.txt | 1 + Coplt.Graphics.Native/D3d12/Include/View.h | 135 ++++++++++++++++++ Coplt.Graphics.Native/D3d12/Src/Binding.cc | 35 +++-- Coplt.Graphics.Native/D3d12/Src/Binding.h | 6 +- Coplt.Graphics.Native/D3d12/Src/Buffer.cc | 2 +- Coplt.Graphics.Native/D3d12/Src/Command.cc | 79 +++++----- Coplt.Graphics.Native/D3d12/Src/Device.cc | 2 +- .../D3d12/Src/GraphicsPipeline.cc | 17 ++- Coplt.Graphics.Native/D3d12/Src/Layout.cc | 32 ++--- Coplt.Graphics.Native/D3d12/Src/Layout.h | 4 +- Coplt.Graphics.Native/D3d12/Src/Output.cc | 2 +- Examples/Colorful/Example.cs | 29 +++- Examples/Colorful/Shaders/Shader.hlsl | 7 +- 24 files changed, 497 insertions(+), 105 deletions(-) create mode 100644 Coplt.Graphics.Core/Core/View.cs create mode 100644 Coplt.Graphics.Native/D3d12/Include/View.h diff --git a/Coplt.Graphics.Core/Coplt.Graphics.Core.csproj b/Coplt.Graphics.Core/Coplt.Graphics.Core.csproj index c43780f..6ce33f6 100644 --- a/Coplt.Graphics.Core/Coplt.Graphics.Core.csproj +++ b/Coplt.Graphics.Core/Coplt.Graphics.Core.csproj @@ -15,6 +15,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Coplt.Graphics.Core/Core/GpuDevice.cs b/Coplt.Graphics.Core/Core/GpuDevice.cs index e3debec..595d446 100644 --- a/Coplt.Graphics.Core/Core/GpuDevice.cs +++ b/Coplt.Graphics.Core/Core/GpuDevice.cs @@ -284,6 +284,10 @@ public ShaderInputLayout CreateShaderInputLayout( } } + private ShaderInputLayout? m_empty_shader_input_layout; + public ShaderInputLayout EmptyShaderInputLayout => + m_empty_shader_input_layout ??= CreateShaderInputLayout([], "Empty Shader Input Layout"); + #endregion #region CreateShader diff --git a/Coplt.Graphics.Core/Core/ShaderBinding.cs b/Coplt.Graphics.Core/Core/ShaderBinding.cs index 41e6723..70e6ad7 100644 --- a/Coplt.Graphics.Core/Core/ShaderBinding.cs +++ b/Coplt.Graphics.Core/Core/ShaderBinding.cs @@ -1,8 +1,11 @@ -using Coplt.Dropping; +using System.Buffers; +using Coplt.Dropping; using Coplt.Graphics.Native; namespace Coplt.Graphics.Core; +public record struct ShaderBindingSetItem(uint Index, View View); + [Dropping(Unmanaged = true)] public sealed unsafe partial class ShaderBinding { @@ -78,4 +81,55 @@ m_name is null : $"0x{nameof(ShaderBinding)}({(nuint)m_ptr:X} \"{m_name}\")"; #endregion + + #region Set + + public void Set(ReadOnlySpan Items) + { + if (Items.Length < 32) + { + var p = stackalloc FShaderBindingBatchSet[Items.Length]; + DoSet(m_ptr, p, Items); + } + else + { + var arr = ArrayPool.Shared.Rent(Items.Length); + try + { + fixed (FShaderBindingBatchSet* p = arr) + { + DoSet(m_ptr, p, Items); + } + } + finally + { + ArrayPool.Shared.Return(arr); + } + } + return; + + static void DoSet(FShaderBinding* ptr, FShaderBindingBatchSet* p, ReadOnlySpan Items) + { + for (var i = 0; i < Items.Length; i++) + { + ref readonly var item = ref Items[i]; + p[i] = new() + { + Index = item.Index, + View = item.View.ToFFI(), + }; + } + ptr->Set((uint)Items.Length, p).TryThrow(); + } + } + + public void UnsafeSet(ReadOnlySpan Items) + { + fixed (FShaderBindingBatchSet* ptr = Items) + { + m_ptr->Set((uint)Items.Length, ptr).TryThrow(); + } + } + + #endregion } diff --git a/Coplt.Graphics.Core/Core/View.cs b/Coplt.Graphics.Core/Core/View.cs new file mode 100644 index 0000000..14b0508 --- /dev/null +++ b/Coplt.Graphics.Core/Core/View.cs @@ -0,0 +1,26 @@ +using Coplt.Graphics.Native; +using Coplt.Union; + +namespace Coplt.Graphics.Core; + +[Union] +public unsafe partial struct View +{ + [UnionTemplate] + private interface Template + { + void None(); + GpuBuffer Buffer(); + } + + public static View None => default; + + public static implicit operator View(GpuBuffer buffer) => MakeBuffer(buffer); + + public FView ToFFI() => Tag switch + { + Tags.None => new FView { Type = FViewType.None }, + Tags.Buffer => new FView { Type = FViewType.Buffer, Buffer = Buffer.m_ptr }, + _ => throw new ArgumentOutOfRangeException() + }; +} diff --git a/Coplt.Graphics.Core/Native/Native.D3d12.cs b/Coplt.Graphics.Core/Native/Native.D3d12.cs index 3f5614e..47aa19f 100644 --- a/Coplt.Graphics.Core/Native/Native.D3d12.cs +++ b/Coplt.Graphics.Core/Native/Native.D3d12.cs @@ -502,12 +502,19 @@ public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12ShaderBinding*)Unsafe.AsPointer(ref this), &result, name); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FView *")] + public FView* GetViews([NativeTypeName("Coplt::u32 *")] uint* out_size) + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[5]))((FD3d12ShaderBinding*)Unsafe.AsPointer(ref this), out_size); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] public FResult Set([NativeTypeName("Coplt::u32")] uint count, [NativeTypeName("const FShaderBindingBatchSet *")] FShaderBindingBatchSet* bindings) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[5]))((FD3d12ShaderBinding*)Unsafe.AsPointer(ref this), &result, count, bindings); + return *((delegate* unmanaged[Thiscall])(lpVtbl[6]))((FD3d12ShaderBinding*)Unsafe.AsPointer(ref this), &result, count, bindings); } public interface Interface : FShaderBinding.Interface diff --git a/Coplt.Graphics.Core/Native/Native.cs b/Coplt.Graphics.Core/Native/Native.cs index 05feed7..d72879c 100644 --- a/Coplt.Graphics.Core/Native/Native.cs +++ b/Coplt.Graphics.Core/Native/Native.cs @@ -1307,10 +1307,10 @@ public unsafe partial struct FShaderBindingCreateOptions public FShaderLayout* Layout; } - public unsafe partial struct FShaderBindingBatchSet + public partial struct FShaderBindingBatchSet { - [NativeTypeName("Coplt::FGpuView *")] - public FGpuView* View; + [NativeTypeName("Coplt::FView")] + public FView View; [NativeTypeName("Coplt::u32")] public uint Index; @@ -1358,16 +1358,26 @@ public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FShaderBinding*)Unsafe.AsPointer(ref this), &result, name); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FView *")] + public FView* GetViews([NativeTypeName("Coplt::u32 *")] uint* out_size) + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[5]))((FShaderBinding*)Unsafe.AsPointer(ref this), out_size); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] public FResult Set([NativeTypeName("Coplt::u32")] uint count, [NativeTypeName("const FShaderBindingBatchSet *")] FShaderBindingBatchSet* bindings) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[5]))((FShaderBinding*)Unsafe.AsPointer(ref this), &result, count, bindings); + return *((delegate* unmanaged[Thiscall])(lpVtbl[6]))((FShaderBinding*)Unsafe.AsPointer(ref this), &result, count, bindings); } public interface Interface : FGpuObject.Interface { + [return: NativeTypeName("Coplt::FView *")] + FView* GetViews([NativeTypeName("Coplt::u32 *")] uint* out_size); + [return: NativeTypeName("Coplt::FResult")] FResult Set([NativeTypeName("Coplt::u32")] uint count, [NativeTypeName("const FShaderBindingBatchSet *")] FShaderBindingBatchSet* bindings); } @@ -1886,6 +1896,40 @@ public unsafe partial struct FGpuImage : INativeGuid public FImageLayout m_layout; } + [NativeTypeName("Coplt::u8")] + public enum FViewType : byte + { + None, + Buffer, + } + + public unsafe partial struct FView + { + [NativeTypeName("__AnonymousRecord_Resource_L222_C9")] + public _Anonymous_e__Union Anonymous; + + [NativeTypeName("Coplt::FViewType")] + public FViewType Type; + + [UnscopedRef] + public ref FGpuBuffer* Buffer + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.Buffer; + } + } + + [StructLayout(LayoutKind.Explicit)] + public unsafe partial struct _Anonymous_e__Union + { + [FieldOffset(0)] + [NativeTypeName("Coplt::FGpuBuffer *")] + public FGpuBuffer* Buffer; + } + } + [NativeTypeName("Coplt::u8")] public enum FPresentMode : byte { diff --git a/Coplt.Graphics.Native/Api/FFI/Binding.h b/Coplt.Graphics.Native/Api/FFI/Binding.h index 8ca85ad..d14b574 100644 --- a/Coplt.Graphics.Native/Api/FFI/Binding.h +++ b/Coplt.Graphics.Native/Api/FFI/Binding.h @@ -14,12 +14,14 @@ namespace Coplt struct FShaderBindingBatchSet { - FGpuView* View{}; + FView View{}; u32 Index{}; }; COPLT_INTERFACE_DEFINE(FShaderBinding, "a3ca644a-0e02-4d25-9a18-8835d66600f7", FGpuObject) { + virtual FView* GetViews(u32* out_size) noexcept = 0; + virtual FResult Set(u32 count, const FShaderBindingBatchSet* bindings) noexcept = 0; }; } diff --git a/Coplt.Graphics.Native/Api/FFI/Layout.h b/Coplt.Graphics.Native/Api/FFI/Layout.h index fd91869..d278ca8 100644 --- a/Coplt.Graphics.Native/Api/FFI/Layout.h +++ b/Coplt.Graphics.Native/Api/FFI/Layout.h @@ -61,6 +61,41 @@ namespace Coplt FShaderLayoutItemView View{}; FShaderLayoutItemType Type{}; FShaderLayoutItemUsage Usage{}; + +#ifdef FFI_SRC + bool IsAllowBuffer() const + { + switch (Type) + { + case FShaderLayoutItemType::ConstantBuffer: + case FShaderLayoutItemType::RawBuffer: + case FShaderLayoutItemType::StructureBuffer: + case FShaderLayoutItemType::StructureBufferWithCounter: + return true; + default: + return false; + } + } + + bool IsAllowTexture() const + { + switch (Type) + { + case FShaderLayoutItemType::Texture1D: + case FShaderLayoutItemType::Texture1DArray: + case FShaderLayoutItemType::Texture2D: + case FShaderLayoutItemType::Texture2DArray: + case FShaderLayoutItemType::Texture2DMultisample: + case FShaderLayoutItemType::Texture2DArrayMultisample: + case FShaderLayoutItemType::Texture3D: + case FShaderLayoutItemType::TextureCube: + case FShaderLayoutItemType::TextureCubeArray: + return true; + default: + return false; + } + } +#endif }; COPLT_ENUM_FLAGS(FShaderLayoutFlags, u8) @@ -136,10 +171,10 @@ namespace Coplt COPLT_INTERFACE_DEFINE(FMeshLayout, "8fe5121f-c2ce-46f5-aa14-f28595f35361", FGpuObject) { - virtual const FMeshBufferDefine* GetBuffers(u32* out_count) const noexcept = 0; - virtual const FMeshBufferElement* GetElements(u32* out_count) const noexcept = 0; + virtual const FMeshBufferDefine* GetBuffers(u32* out_count) const noexcept = 0; + virtual const FMeshBufferElement* GetElements(u32* out_count) const noexcept = 0; - virtual const FMeshBufferElement* TryGetElement(u32 SlotId, u32 SlotIndex) const noexcept = 0; + virtual const FMeshBufferElement* TryGetElement(u32 SlotId, u32 SlotIndex) const noexcept = 0; #if FFI_SRC std::span GetBuffers() const noexcept @@ -148,7 +183,7 @@ namespace Coplt return std::span{GetBuffers(&count), static_cast(count)}; } - std::span GetElements() const noexcept + std::span GetElements() const noexcept { u32 count{}; return std::span{GetElements(&count), static_cast(count)}; diff --git a/Coplt.Graphics.Native/Api/FFI/Resource.h b/Coplt.Graphics.Native/Api/FFI/Resource.h index 2365f82..7739e17 100644 --- a/Coplt.Graphics.Native/Api/FFI/Resource.h +++ b/Coplt.Graphics.Native/Api/FFI/Resource.h @@ -210,4 +210,19 @@ namespace Coplt // 纹理布局 FImageLayout m_layout{}; }; + + enum class FViewType : u8 + { + None, + Buffer, + }; + + struct FView + { + union + { + FGpuBuffer* Buffer; + }; + FViewType Type; + }; } diff --git a/Coplt.Graphics.Native/Api/Include/Error.h b/Coplt.Graphics.Native/Api/Include/Error.h index b5a4c43..33d868a 100644 --- a/Coplt.Graphics.Native/Api/Include/Error.h +++ b/Coplt.Graphics.Native/Api/Include/Error.h @@ -374,4 +374,12 @@ namespace Coplt } return r; } + +#ifdef _WINDOWS +#define COPLT_THROW(msg) throw WRuntimeException(L##msg) +#define COPLT_THROW_FMT(msg, ...) throw WRuntimeException(fmt::format(L##msg, __VA_ARGS__)) +#else +#define COPLT_THROW(msg) throw RuntimeException(msg) +#define COPLT_THROW_FMT(msg, ...) throw RuntimeException(fmt::format(msg, __VA_ARGS__)) +#endif } diff --git a/Coplt.Graphics.Native/Api/Src/Shader.cc b/Coplt.Graphics.Native/Api/Src/Shader.cc index 2bedaa0..e398374 100644 --- a/Coplt.Graphics.Native/Api/Src/Shader.cc +++ b/Coplt.Graphics.Native/Api/Src/Shader.cc @@ -43,56 +43,63 @@ Shader::Shader(Rc&& device, const FShaderCreateOptions& options) : m m_layout = Rc::UnsafeClone(options.Layout); m_input_layout = Rc::UnsafeClone(options.InputLayout); - if (options.Count == 0) throw RuntimeException("options.Count cannot be 0"); + if (options.Count == 0) + COPLT_THROW("options.Count cannot be 0"); if (options.Count > MaxShaderModuleCount) - throw RuntimeException( - fmt::format("Too many shader modules, there can be a maximum of {}", MaxShaderModuleCount) + { + COPLT_THROW_FMT( + "Too many shader modules, there can be a maximum of {}", MaxShaderModuleCount ); - if (options.Modules == nullptr) throw RuntimeException("options.Modules is null"); + } + if (options.Modules == nullptr) + COPLT_THROW("options.Modules is null"); for (u32 i = 0; i < options.Count; i++) { const auto module = options.Modules[i]; - if (module == nullptr) throw RuntimeException(fmt::format("options.Modules[{}] is null", i)); + if (module == nullptr) + COPLT_THROW_FMT("options.Modules[{}] is null", i); switch (module->Stage) { case FShaderStage::Compute: - if (options.Count != 1) throw RuntimeException("The compute stage cannot be combined with other stage"); + if (options.Count != 1) + COPLT_THROW("The compute stage cannot be combined with other stage"); Stages = FShaderStageFlags::Compute; m_modules[0] = Rc::UnsafeClone(module); return; case FShaderStage::Pixel: - if (options.Count == 1) throw RuntimeException("The pixel stage cannot exist alone"); + if (options.Count == 1) + COPLT_THROW("The pixel stage cannot exist alone"); Stages |= FShaderStageFlags::Pixel; m_modules[0] = Rc::UnsafeClone(module); break; case FShaderStage::Vertex: if (HasAnyFlags(Stages, FShaderStageFlags::Mesh | FShaderStageFlags::Task)) - throw RuntimeException("The vertex stage and the mesh/task stage are mutually exclusive"); + COPLT_THROW("The vertex stage and the mesh/task stage are mutually exclusive"); Stages |= FShaderStageFlags::Vertex; m_modules[1] = Rc::UnsafeClone(module); break; case FShaderStage::Mesh: if (HasFlags(Stages, FShaderStageFlags::Vertex)) - throw RuntimeException("The vertex stage and the mesh/task stage are mutually exclusive"); + COPLT_THROW("The vertex stage and the mesh/task stage are mutually exclusive"); Stages |= FShaderStageFlags::Mesh; m_modules[1] = Rc::UnsafeClone(module); break; case FShaderStage::Task: if (HasFlags(Stages, FShaderStageFlags::Vertex)) - throw RuntimeException("The vertex stage and the mesh/task stage are mutually exclusive"); + COPLT_THROW("The vertex stage and the mesh/task stage are mutually exclusive"); Stages |= FShaderStageFlags::Task; m_modules[2] = Rc::UnsafeClone(module); break; default: - throw RuntimeException( - fmt::format("Unknown shader stage {}", static_cast(module->Stage)) + COPLT_THROW_FMT( + "Unknown shader stage {}", static_cast(module->Stage) ); } } if (HasFlags(Stages, FShaderStageFlags::Task) && !HasFlags(Stages, FShaderStageFlags::Mesh)) - throw RuntimeException("Having a task stage must also have a mesh stage"); + COPLT_THROW("Having a task stage must also have a mesh stage"); } FResult Shader::SetName(const FStr8or16& name) noexcept diff --git a/Coplt.Graphics.Native/D3d12/CMakeLists.txt b/Coplt.Graphics.Native/D3d12/CMakeLists.txt index 9c0cc11..cfb43eb 100644 --- a/Coplt.Graphics.Native/D3d12/CMakeLists.txt +++ b/Coplt.Graphics.Native/D3d12/CMakeLists.txt @@ -42,6 +42,7 @@ add_library(${target_name} SHARED Src/Binding.cc Src/DescriptorManager.h Src/DescriptorManager.cc + Include/View.h ) set_target_properties(${target_name} PROPERTIES LINKER_LANGUAGE CXX) set_target_properties(${target_name} PROPERTIES OUTPUT_NAME "Coplt.Graphics.Native.D3d12") diff --git a/Coplt.Graphics.Native/D3d12/Include/View.h b/Coplt.Graphics.Native/D3d12/Include/View.h new file mode 100644 index 0000000..2ac5adb --- /dev/null +++ b/Coplt.Graphics.Native/D3d12/Include/View.h @@ -0,0 +1,135 @@ +#pragma once + +#include + +#include "../../Api/FFI/Resource.h" +#include "../Src/Buffer.h" + +namespace Coplt +{ + struct View + { + enum class Type : u8 + { + None, + Buffer, + }; + + private: + union + { + Rc m_buffer; + }; + + Type m_type; + + public: + Type Type() const { return m_type; } + Rc* Buffer() { return m_type == Type::Buffer ? std::addressof(m_buffer) : nullptr; } + + ~View() + { + // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement + switch (m_type) + { + case Type::None: + return; + case Type::Buffer: + m_buffer.~Rc(); + return; + } + std::unreachable(); + } + + View() : m_type(Type::None) + { + } + + View(const View& other) : m_type(other.m_type) + { + switch (m_type) + { + case Type::None: + break; + case Type::Buffer: + new(std::addressof(m_buffer)) Rc(other.m_buffer); + break; + } + } + + View(View&& other) noexcept : m_type(std::exchange(other.m_type, Type::None)) + { + switch (m_type) + { + case Type::None: + break; + case Type::Buffer: + new(std::addressof(m_buffer)) Rc(std::move(other.m_buffer)); + break; + } + } + + View& operator=(const View& view) noexcept + { + this->~View(); + new(this) View(view); + return *this; + } + + View& operator=(View&& view) noexcept + { + this->~View(); + new(this) View(std::forward(view)); + return *this; + } + + View(const FView& view) + { + switch (view.Type) + { + case FViewType::None: + m_type = Type::None; + break; + case FViewType::Buffer: + m_type = Type::Buffer; + if (view.Buffer == nullptr) new(std::addressof(m_buffer)) Rc(); + const auto db = view.Buffer->QueryInterface(); + if (db == nullptr) + COPLT_THROW("GpuBuffer from different backends."); + new(std::addressof(m_buffer)) Rc(Rc::UnsafeClone(db)); + break; + } + } + + View& operator=(const FView& view) + { + this->~View(); + new(this) View(view); + return *this; + } + + View(const Rc& buffer) : m_type(Type::Buffer) + { + new(std::addressof(m_buffer)) Rc(buffer); + } + + View(Rc&& buffer) : m_type(Type::Buffer) + { + new(std::addressof(m_buffer)) Rc(std::move(buffer)); + } + + View& operator=(const Rc& buffer) + { + this->~View(); + new(this) View(buffer); + return *this; + } + + View& operator=(Rc&& buffer) + { + this->~View(); + new(this) View(std::forward>(buffer)); + return *this; + } + }; +} diff --git a/Coplt.Graphics.Native/D3d12/Src/Binding.cc b/Coplt.Graphics.Native/D3d12/Src/Binding.cc index 164d0d0..8fe6524 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Binding.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Binding.cc @@ -13,10 +13,12 @@ D3d12ShaderBinding::D3d12ShaderBinding( m_dx_device = m_device->m_device; m_layout = Rc::UnsafeClone(options.Layout->QueryInterface()); - if (m_layout == nullptr) throw WRuntimeException(L"Layout from different backends"); + if (m_layout == nullptr) + COPLT_THROW("Layout from different backends"); - const auto item_metas = m_layout->GetItemMeta(); - m_views = std::vector>(item_metas.size(), {}); + const auto item_metas = m_layout->GetItemMetas(); + m_f_views = std::vector(item_metas.size(), {}); + m_views = std::vector(item_metas.size(), {}); } FResult D3d12ShaderBinding::SetName(const FStr8or16& name) noexcept @@ -24,6 +26,12 @@ FResult D3d12ShaderBinding::SetName(const FStr8or16& name) noexcept return FResult::None(); } +FView* D3d12ShaderBinding::GetViews(u32* out_size) noexcept +{ + *out_size = m_f_views.size(); + return m_f_views.data(); +} + FResult D3d12ShaderBinding::Set(const u32 count, const FShaderBindingBatchSet* bindings) noexcept { return feb([&] @@ -34,16 +42,23 @@ FResult D3d12ShaderBinding::Set(const u32 count, const FShaderBindingBatchSet* b void D3d12ShaderBinding::Set(const std::span bindings) { + auto item_metas = m_layout->GetItemMetas(); + auto item_defines = m_layout->GetItemDefines(); for (const auto& [View, Index] : bindings) { - if (Index >= m_views.size()) throw WRuntimeException(L"Index out of bounds"); - if (View == nullptr) + if (Index >= m_views.size()) + COPLT_THROW("Index out of bounds"); + const auto& define = item_defines[Index]; + switch (View.Type) { - m_views[Index] = nullptr; - continue; + case FViewType::None: + break; + case FViewType::Buffer: + if (!define.IsAllowBuffer()) + COPLT_THROW_FMT("Binding index {} is not allowed to bind to buffer.", Index); + break; } - Rc view = Rc::UnsafeClone(View); - // todo check - m_views[Index] = std::move(view); + m_f_views[Index] = View; + m_views[Index] = View; } } diff --git a/Coplt.Graphics.Native/D3d12/Src/Binding.h b/Coplt.Graphics.Native/D3d12/Src/Binding.h index 45c0b45..4e1f625 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Binding.h +++ b/Coplt.Graphics.Native/D3d12/Src/Binding.h @@ -5,6 +5,7 @@ #include "../../Api/Include/Object.h" #include "../FFI/Binding.h" #include "../FFI/Layout.h" +#include "../Include/View.h" namespace Coplt { @@ -13,13 +14,16 @@ namespace Coplt Rc m_device{}; ComPtr m_dx_device{}; Rc m_layout{}; - std::vector> m_views{}; + std::vector m_f_views{}; + std::vector m_views{}; std::vector m_changed{}; explicit D3d12ShaderBinding(Rc&& device, const FShaderBindingCreateOptions& options); FResult SetName(const FStr8or16& name) noexcept override; + FView* GetViews(u32* out_size) noexcept override; + FResult Set(u32 count, const FShaderBindingBatchSet* bindings) noexcept override; void Set(std::span bindings); diff --git a/Coplt.Graphics.Native/D3d12/Src/Buffer.cc b/Coplt.Graphics.Native/D3d12/Src/Buffer.cc index 46e3f37..428f936 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Buffer.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Buffer.cc @@ -16,7 +16,7 @@ D3d12GpuBuffer::D3d12GpuBuffer(Rc&& device, const FGpuBufferCrea m_usage = options.Usage; if (HasAnyFlags(m_purpose, FResourcePurpose::DepthStencil | FResourcePurpose::ShadingRate)) - throw WRuntimeException(L"Buffer does not support this purpose combination."); + COPLT_THROW("Buffer does not support this purpose combination."); m_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; m_desc.Alignment = 0; diff --git a/Coplt.Graphics.Native/D3d12/Src/Command.cc b/Coplt.Graphics.Native/D3d12/Src/Command.cc index f86f683..66a7e97 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Command.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Command.cc @@ -127,7 +127,8 @@ void D3d12CommandInterpreter::InitStates(const FCommandSubmit& submit) for (u32 i = 0; i < submit.ResourceCount; ++i) { const auto& res = submit.Resources[i]; - if (res.GetObjectPtr() == nullptr) throw WRuntimeException(fmt::format(L"Resource is null at {}", i)); + if (res.GetObjectPtr() == nullptr) + COPLT_THROW_FMT("Resource is null at {}", i); ResState state{}; state.Resource = GetResource(res); state.Type = res.Type; @@ -167,7 +168,7 @@ void D3d12CommandInterpreter::CollectBarrier(const FCommandSubmit& submit) case FCommandType::BufferCopy: goto BufferCopy; } - throw WRuntimeException(fmt::format(L"Unknown command type {}", static_cast(item.Type))); + COPLT_THROW_FMT("Unknown command type {}", static_cast(item.Type)); CmdNext: { @@ -222,10 +223,12 @@ void D3d12CommandInterpreter::CollectBarrier(const FCommandSubmit& submit) } const auto vbs = reinterpret_cast(&submit.Payload[cmd.VertexBuffersIndex]); if (cmd.VertexStartSlot + cmd.VertexBufferCount >= 31) - throw WRuntimeException(fmt::format( - L"The number of input buffers is out of range, the maximum allowed input slots is 31; at command {}", + { + COPLT_THROW_FMT( + "The number of input buffers is out of range, the maximum allowed input slots is 31; at command {}", i - )); + ); + } for (u32 n = 0; n < cmd.VertexBufferCount; ++n) { const auto& vb = vbs[n]; @@ -263,7 +266,7 @@ void D3d12CommandInterpreter::CollectBarrier(const FCommandSubmit& submit) const auto& cmd = item.Draw; if (cmd.Pipeline != nullptr) SetPipelineContext(cmd.Pipeline, i); if (m_context.Pipeline == nullptr) - throw WRuntimeException(fmt::format(L"Pipeline not set at command {}", i)); + COPLT_THROW_FMT("Pipeline not set at command {}", i); goto Graphics_MarkResUse; } Dispatch: @@ -271,7 +274,7 @@ void D3d12CommandInterpreter::CollectBarrier(const FCommandSubmit& submit) const auto& cmd = item.Dispatch; if (cmd.Pipeline != nullptr) SetPipelineContext(cmd.Pipeline, i); if (m_context.Pipeline == nullptr) - throw WRuntimeException(fmt::format(L"Pipeline not set at command {}", i)); + COPLT_THROW_FMT("Pipeline not set at command {}", i); if (cmd.Type == FDispatchType::Mesh && m_context.GPipeline) goto Graphics_MarkResUse; continue; } @@ -293,8 +296,9 @@ void D3d12CommandInterpreter::CollectBarrier(const FCommandSubmit& submit) ReqState(cmd.Dst.Buffer, FResourceState::CopyDst); break; case FBufferRefType::Upload: - throw WRuntimeException( - fmt::format(L"The upload buffer cannot be used as a copy target at command {}", i) + COPLT_THROW_FMT( + "The upload buffer cannot be used as a copy target at command {}", + i ); } continue; @@ -352,10 +356,10 @@ void D3d12CommandInterpreter::Translate(const FCommandSubmit& submit) case FCommandType::BufferCopy: goto BufferCopy; } - throw WRuntimeException(fmt::format(L"Unknown command type {}", static_cast(item.Type))); + COPLT_THROW_FMT("Unknown command type {}", static_cast(item.Type)); Transition: - throw WRuntimeException(L"TODO"); + COPLT_THROW("TODO"); continue; ClearColor: { @@ -449,10 +453,10 @@ void D3d12CommandInterpreter::Translate(const FCommandSubmit& submit) const auto& cmd = item.Draw; if (cmd.Pipeline != nullptr) SetPipeline(cmd_pack, cmd.Pipeline, i); if (m_context.Pipeline == nullptr) - throw WRuntimeException(fmt::format(L"Pipeline not set at command {}", i)); + COPLT_THROW_FMT("Pipeline not set at command {}", i); const auto stages = m_context.Pipeline->GetStages(); if (!HasFlags(stages, FShaderStageFlags::Vertex)) - throw WRuntimeException(L"Non Vertex pipelines cannot use Draw"); + COPLT_THROW("Non Vertex pipelines cannot use Draw"); if (cmd.Indexed) { cmd_pack->DrawIndexedInstanced( @@ -481,12 +485,12 @@ void D3d12CommandInterpreter::Translate(const FCommandSubmit& submit) break; case FDispatchType::Mesh: if (!cmd_pack.m_list7) - throw WRuntimeException(L"Mesh Shader is not supported on this device"); + COPLT_THROW("Mesh Shader is not supported on this device"); cmd_pack.m_list7->DispatchMesh(cmd.GroupCountX, cmd.GroupCountY, cmd.GroupCountZ); break; default: - throw WRuntimeException( - fmt::format(L"Unknown dispatch type {} at command {}", static_cast(cmd.Type), i) + COPLT_THROW_FMT( + "Unknown dispatch type {} at command {}", static_cast(cmd.Type), i ); } continue; @@ -511,20 +515,18 @@ void D3d12CommandInterpreter::Translate(const FCommandSubmit& submit) { const auto dst = GetResource(cmd.Dst.Buffer.Get(submit)); if (cmd.Src.Upload.Index >= m_queue->m_frame_context->m_upload_buffers.size()) - throw WRuntimeException(fmt::format(L"Index out of bounds at command {}", i)); + COPLT_THROW_FMT("Index out of bounds at command {}", i); const auto& src_obj = m_queue->m_frame_context->m_upload_buffers[cmd.Src.Upload.Index]; if (cmd.SrcOffset + cmd.Size >= src_obj.m_size) - throw WRuntimeException(fmt::format(L"Size out of range at command {}", i)); + COPLT_THROW_FMT("Size out of range at command {}", i); const auto src = src_obj.m_resource.m_resource.Get(); cmd_pack->CopyBufferRegion(dst, cmd.DstOffset, src, cmd.SrcOffset, cmd.Size); } else { - throw WRuntimeException( - fmt::format( - L"Unsupported copy combination {{ SrcType = {} DstType = {} }} at command {}", - static_cast(cmd.SrcType), static_cast(cmd.DstType), i - ) + COPLT_THROW_FMT( + "Unsupported copy combination {{ SrcType = {} DstType = {} }} at command {}", + static_cast(cmd.SrcType), static_cast(cmd.DstType), i ); } continue; @@ -539,22 +541,22 @@ void D3d12CommandInterpreter::SetPipelineContext(FShaderPipeline* pipeline, cons m_context.Pipeline = pipeline; m_context.D3dPipeline = pipeline->QueryInterface(); if (!m_context.D3dPipeline) - throw WRuntimeException( - fmt::format( - L"Pipeline({:#x}) comes from different backends at cmd {}", - reinterpret_cast(pipeline), i - ) + { + COPLT_THROW_FMT( + "Pipeline({:#x}) comes from different backends at cmd {}", + reinterpret_cast(pipeline), i ); + } m_context.Layout = pipeline->GetLayout()->QueryInterface(); if (!m_context.Layout) - throw WRuntimeException(L"Shader layout from different backends"); + COPLT_THROW("Shader layout from different backends"); const auto stages = pipeline->GetStages(); m_context.GPipeline = nullptr; if (HasFlags(stages, FShaderStageFlags::Pixel)) { m_context.GPipeline = pipeline->QueryInterface(); if (!m_context.GPipeline) - throw WRuntimeException(L"Pipeline from different backends or pipeline not a graphics pipeline"); + COPLT_THROW("Pipeline from different backends or pipeline not a graphics pipeline"); } } @@ -588,11 +590,12 @@ ID3D12Resource* D3d12CommandInterpreter::GetResource(FUnknown* object, FResource switch (type) { case FResourceRefType::Image: - throw WRuntimeException(L"TODO"); + COPLT_THROW("TODO"); case FResourceRefType::Buffer: { const auto buffer = object->QueryInterface(); - if (!buffer) throw WRuntimeException(L"The memory may be corrupted"); + if (!buffer) + COPLT_THROW("The memory may be corrupted"); ID3D12Resource* ptr{}; buffer->GetCurrentResourcePtr(&ptr).TryThrow(); return ptr; @@ -600,13 +603,14 @@ ID3D12Resource* D3d12CommandInterpreter::GetResource(FUnknown* object, FResource case FResourceRefType::Output: { const auto output = object->QueryInterface(); - if (!output) throw WRuntimeException(L"The memory may be corrupted"); + if (!output) + COPLT_THROW("The memory may be corrupted"); ID3D12Resource* ptr{}; output->GetCurrentResourcePtr(&ptr).TryThrow(); return ptr; } default: - throw WRuntimeException(fmt::format(L"Unknown resource ref type {}", static_cast(type))); + COPLT_THROW_FMT("Unknown resource ref type {}", static_cast(type)); } } @@ -616,16 +620,17 @@ D3D12_CPU_DESCRIPTOR_HANDLE D3d12CommandInterpreter::GetRtv(const FResourceMeta& { case FResourceRefType::Image: case FResourceRefType::Buffer: - throw WRuntimeException(L"TODO"); + COPLT_THROW("TODO"); case FResourceRefType::Output: { const auto output = meta.Output->QueryInterface(); - if (!output) throw WRuntimeException(L"The memory may be corrupted"); + if (!output) + COPLT_THROW("The memory may be corrupted"); D3D12_CPU_DESCRIPTOR_HANDLE rtv{}; output->GetCurrentRtv(&rtv).TryThrow(); return rtv; } default: - throw WRuntimeException(fmt::format(L"Unknown resource ref type {}", static_cast(meta.Type))); + COPLT_THROW_FMT("Unknown resource ref type {}", static_cast(meta.Type)); } } diff --git a/Coplt.Graphics.Native/D3d12/Src/Device.cc b/Coplt.Graphics.Native/D3d12/Src/Device.cc index 3b3da96..b668570 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Device.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Device.cc @@ -145,7 +145,7 @@ D3d12GpuDevice::D3d12GpuDevice( GetAdapter(m_factory.Get(), &m_adapter, feature_level, options); if (!m_adapter) - throw WRuntimeException(L"No matching devices found"); + COPLT_THROW("No matching devices found"); chr | D3D12CreateDevice(m_adapter.Get(), feature_level, IID_PPV_ARGS(&m_device)); diff --git a/Coplt.Graphics.Native/D3d12/Src/GraphicsPipeline.cc b/Coplt.Graphics.Native/D3d12/Src/GraphicsPipeline.cc index bc9867b..72d2d78 100644 --- a/Coplt.Graphics.Native/D3d12/Src/GraphicsPipeline.cc +++ b/Coplt.Graphics.Native/D3d12/Src/GraphicsPipeline.cc @@ -131,14 +131,17 @@ D3d12GraphicsShaderPipeline::D3d12GraphicsShaderPipeline( ) : m_device(std::move(device)), m_graphics_state(options.GraphicsState) { m_dx_device = m_device->m_device; - if (options.Shader == nullptr) throw WRuntimeException(L"Shader is null"); + if (options.Shader == nullptr) + COPLT_THROW("Shader is null"); m_shader = Rc::UnsafeClone(options.Shader); - if (!HasFlags(m_shader->Stages, FShaderStageFlags::Pixel)) throw WRuntimeException(L"The shader is not graphics"); + if (!HasFlags(m_shader->Stages, FShaderStageFlags::Pixel)) + COPLT_THROW("The shader is not graphics"); if (auto layout = m_shader->Layout()) { auto dx_layout = layout->QueryInterface(); - if (dx_layout == nullptr) throw WRuntimeException(L"Shader layout from different backends"); + if (dx_layout == nullptr) + COPLT_THROW("Shader layout from different backends"); m_layout = Rc::UnsafeClone(dx_layout); } else @@ -173,12 +176,14 @@ D3d12GraphicsShaderPipeline::D3d12GraphicsShaderPipeline( if (auto input_layout = m_shader->InputLayout()) { auto dx_input_layout = input_layout->QueryInterface(); - if (dx_input_layout == nullptr) throw WRuntimeException(L"Input layout from different backends"); + if (dx_input_layout == nullptr) + COPLT_THROW("Input layout from different backends"); FD3d12MeshLayout* dx_mesh_layout{}; if (options.MeshLayout != nullptr) { dx_mesh_layout = options.MeshLayout->QueryInterface(); - if (dx_mesh_layout == nullptr) throw WRuntimeException(L"Mesh layout from different backends"); + if (dx_mesh_layout == nullptr) + COPLT_THROW("Mesh layout from different backends"); } else dx_mesh_layout = m_device->GetEmptyMeshLayout().get(); SetInputLayout(&m_device, tmp_strings, input_element_desc, input_slots, dx_input_layout, dx_mesh_layout); @@ -204,7 +209,7 @@ D3d12GraphicsShaderPipeline::D3d12GraphicsShaderPipeline( desc.Flags = D3D12_PIPELINE_STATE_FLAG_DYNAMIC_DEPTH_BIAS; stream = CD3DX12_PIPELINE_STATE_STREAM2(desc); } - else throw WRuntimeException(L"Unknown shader stage combination"); + else COPLT_THROW("Unknown shader stage combination"); D3D12_PIPELINE_STATE_STREAM_DESC stream_desc{}; stream_desc.SizeInBytes = sizeof(stream); diff --git a/Coplt.Graphics.Native/D3d12/Src/Layout.cc b/Coplt.Graphics.Native/D3d12/Src/Layout.cc index 6e72d2b..31b0793 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Layout.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Layout.cc @@ -26,13 +26,13 @@ D3d12ShaderLayout::D3d12ShaderLayout(Rc&& device, const FShaderL if (item.View == FShaderLayoutItemView::Constants) { if (item.Type != FShaderLayoutItemType::ConstantBuffer) - throw WRuntimeException(L"Push Const / Root Const view must be ConstantBuffer"); + COPLT_THROW("Push Const / Root Const view must be ConstantBuffer"); D3D12_ROOT_PARAMETER1 param{}; param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; param.Constants.ShaderRegister = item.Slot; param.Constants.RegisterSpace = item.Space; - param.Constants.Num32BitValues = item.CountOrIndex; + param.Constants.Num32BitValues = std::max(1u, item.CountOrIndex); param.ShaderVisibility = ToDxVisibility(item.Stage); m_item_metas[i] = ItemMeta{.Index = static_cast(root_parameters.size()), .Type = ItemType::Const}; root_parameters.push_back(param); @@ -68,14 +68,12 @@ D3d12ShaderLayout::D3d12ShaderLayout(Rc&& device, const FShaderL type = D3D12_ROOT_PARAMETER_TYPE_UAV; goto DefineDescriptor; case FShaderLayoutItemView::Sampler: - throw WRuntimeException(L"TODO"); // 静态采样器 + COPLT_THROW("TODO"); // 静态采样器 default: - throw WRuntimeException( - fmt::format(L"Unknown shader layout item type {}", static_cast(item.Type)) - ); + COPLT_THROW_FMT("Unknown shader layout item type {}", static_cast(item.Type)); } default: - throw WRuntimeException(fmt::format(L"Unknown shader layout item usage {}", static_cast(item.Usage))); + COPLT_THROW_FMT("Unknown shader layout item usage {}", static_cast(item.Usage)); } continue; @@ -116,15 +114,13 @@ D3d12ShaderLayout::D3d12ShaderLayout(Rc&& device, const FShaderL range_type = RangeType::Sampler; break; default: - throw WRuntimeException( - fmt::format(L"Unknown shader layout item type {}", static_cast(item.Type)) - ); + COPLT_THROW_FMT("Unknown shader layout item type {}", static_cast(item.Type)); } auto& meta = table.GetOrAdd(TableKey(item.Stage, range_type), [&](auto& p) { p = TableMeta(table_index[static_cast(table_scope)]++, item.Stage, range_type); }); - range.NumDescriptors = item.CountOrIndex; + range.NumDescriptors = std::max(1u, item.CountOrIndex); range.BaseShaderRegister = item.Slot; range.RegisterSpace = item.Space; range.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; @@ -217,7 +213,7 @@ const FShaderLayoutItemDefine* D3d12ShaderLayout::GetItemDefines(u32* out_count) return m_layout_item_defines.data(); } -std::span D3d12ShaderLayout::GetItemMeta() noexcept +std::span D3d12ShaderLayout::GetItemMetas() noexcept { return m_item_metas; } @@ -259,19 +255,19 @@ D3d12MeshLayout::D3d12MeshLayout(Rc&& device, const FMeshLayoutC m_elements = std::vector(options.Elements, options.Elements + options.ElementCount); // 保留 1 个 slot 永远为 0 if (m_buffers.size() >= 31) - throw WRuntimeException( - fmt::format( - L"Too many buffers, a maximum of 31 buffers are supported, but actually provided {}", - m_buffers.size() - ) + { + COPLT_THROW_FMT( + "Too many buffers, a maximum of 31 buffers are supported, but actually provided {}", + m_buffers.size() ); + } for (u32 i = 0; i < m_elements.size(); ++i) { const auto& element = m_elements[i]; const auto key = static_cast(element.SlotId) | (static_cast(element.SlotIndex) << 32); m_slot_id_index_to_element.TryAdd(key, &element); if (element.BufferIndex > m_buffers.size()) - throw WRuntimeException(fmt::format(L"BufferIndex of element {} is out of range", i)); + COPLT_THROW_FMT("BufferIndex of element {} is out of range", i); } } diff --git a/Coplt.Graphics.Native/D3d12/Src/Layout.h b/Coplt.Graphics.Native/D3d12/Src/Layout.h index d22fdaf..7b5e2fd 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Layout.h +++ b/Coplt.Graphics.Native/D3d12/Src/Layout.h @@ -90,7 +90,7 @@ namespace Coplt RangeType RangeType{}; }; - virtual std::span GetItemMeta() noexcept = 0; + virtual std::span GetItemMetas() noexcept = 0; virtual std::array, 2> GetTableMetas() noexcept = 0; }; @@ -113,7 +113,7 @@ namespace Coplt const FShaderLayoutItemDefine* GetItemDefines(u32* out_count) noexcept override; - std::span GetItemMeta() noexcept override; + std::span GetItemMetas() noexcept override; std::array, 2> GetTableMetas() noexcept override; }; diff --git a/Coplt.Graphics.Native/D3d12/Src/Output.cc b/Coplt.Graphics.Native/D3d12/Src/Output.cc index fec418b..0e48f5f 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Output.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Output.cc @@ -10,7 +10,7 @@ using namespace Coplt; D3d12GpuSwapChainOutput::D3d12GpuSwapChainOutput(Rc&& queue) : m_queue(std::move(queue)) { if (m_queue->m_queue_type != FGpuQueueType::Direct) - throw WRuntimeException(L"Cannot create output on a non direct queue."); + COPLT_THROW("Cannot create output on a non direct queue."); m_device = m_queue->m_device; m_dx_device = m_queue->m_dx_device; diff --git a/Examples/Colorful/Example.cs b/Examples/Colorful/Example.cs index 7e0b572..f20292c 100644 --- a/Examples/Colorful/Example.cs +++ b/Examples/Colorful/Example.cs @@ -7,18 +7,31 @@ namespace Examples; public class Example(IntPtr Handle, uint Width, uint Height) : ExampleBase(Handle, Width, Height) { + private ShaderLayout Layout = null!; private Shader Shader = null!; private GraphicsShaderPipeline Pipeline = null!; private ShaderBinding ShaderBinding = null!; + private GpuBuffer ArgBuffer = null!; public override string Name => "Colorful"; protected override async Task LoadResources(CommandList cmd) { var modules = await LoadShaderModules("Shader", [ShaderStage.Vertex, ShaderStage.Pixel]); - Shader = Device.CreateShader( - modules, Device.CreateShaderLayout([]), Device.CreateShaderInputLayout([]) + Layout = Device.CreateShaderLayout( + [ + new() + { + Slot = 0, + Stage = ShaderStage.Pixel, + View = ShaderLayoutItemView.Cbv, + Type = ShaderLayoutItemType.ConstantBuffer, + Usage = ShaderLayoutItemUsage.Common, + } + ], + Name: Name ); - ShaderBinding = Device.CreateShaderBinding(Shader.Layout!, Name: Name); + Shader = Device.CreateShader(modules, Layout); + ShaderBinding = Device.CreateShaderBinding(Layout, Name: Name); Pipeline = Device.CreateGraphicsShaderPipeline( Shader, new() { @@ -35,9 +48,19 @@ protected override async Task LoadResources(CommandList cmd) Topology = PrimitiveTopologyType.TriangleStrip, }, Name: Name ); + ArgBuffer = Device.CreateBuffer( + new() + { + Purpose = ResourcePurpose.ConstantBuffer, + Size = sizeof(float), + }, + Name: "Args" + ); + ShaderBinding.Set([new(0, ArgBuffer)]); } protected override void Render(CommandList cmd, Time time) { + cmd.Upload(ArgBuffer, [(float)time.Total.TotalSeconds]); cmd.SetRenderTargets([Output]); cmd.ClearColor(Output, new float4(0.83f, 0.8f, 0.97f, 1f)); cmd.Draw(Pipeline, 4); diff --git a/Examples/Colorful/Shaders/Shader.hlsl b/Examples/Colorful/Shaders/Shader.hlsl index a7fad12..be05d9c 100644 --- a/Examples/Colorful/Shaders/Shader.hlsl +++ b/Examples/Colorful/Shaders/Shader.hlsl @@ -24,8 +24,13 @@ Varying Vertex(Attribute input) return output; } +cbuffer Args : register(b0) +{ + float time; +} + [shader("pixel")] float4 Pixel(Varying input) : SV_Target { - return float4(input.Uv, 0, 1); + return float4(input.Uv, time, 1); } From 50562579a98be827cbdfc5461f25e5c9d9d51e4f Mon Sep 17 00:00:00 2001 From: U2A5F Date: Tue, 25 Feb 2025 22:29:42 +0800 Subject: [PATCH 09/23] save --- Coplt.Graphics.Core/Core/CommandList.cs | 132 ++++++++++++--- Coplt.Graphics.Core/Core/GpuDevice.cs | 16 +- Coplt.Graphics.Core/Core/GpuQueue.cs | 23 +++ Coplt.Graphics.Core/Core/ShaderBinding.cs | 70 +++----- Coplt.Graphics.Core/Core/ShaderLayout.cs | 11 +- .../Native/FShaderLayoutItemDefine.cs | 25 +++ Coplt.Graphics.Core/Native/FSlice.cs | 153 ++++++++++++++++++ Coplt.Graphics.Core/Native/Native.cs | 49 +++++- Coplt.Graphics.Native/Api/FFI/Command.h | 33 +++- Coplt.Graphics.Native/D3d12/Src/Command.cc | 17 ++ Examples/Colorful/Example.cs | 2 +- 11 files changed, 430 insertions(+), 101 deletions(-) create mode 100644 Coplt.Graphics.Core/Native/FShaderLayoutItemDefine.cs create mode 100644 Coplt.Graphics.Core/Native/FSlice.cs diff --git a/Coplt.Graphics.Core/Core/CommandList.cs b/Coplt.Graphics.Core/Core/CommandList.cs index 7f37469..acf86dc 100644 --- a/Coplt.Graphics.Core/Core/CommandList.cs +++ b/Coplt.Graphics.Core/Core/CommandList.cs @@ -5,6 +5,7 @@ namespace Coplt.Graphics.Core; +[Flags] public enum CommandFlags : uint { None = 0, @@ -30,6 +31,7 @@ public sealed unsafe class CommandList internal readonly List m_payload = new(); internal GpuOutput? m_current_output; internal ShaderPipeline? m_current_pipeline; + internal ShaderBinding? m_current_binding; #endregion @@ -58,6 +60,8 @@ internal void Reset() m_objects.Clear(); m_payload.Clear(); m_current_output = null; + m_current_pipeline = null; + m_current_binding = null; } #endregion @@ -113,7 +117,8 @@ internal void Present(GpuOutput Output, CommandFlags Flags = CommandFlags.None) Present = cmd, } ); - Output.UnsafeChangeState(FResourceState.Present); + if ((Flags & CommandFlags.DontTransition) == 0) + Output.UnsafeChangeState(FResourceState.Present); } #endregion @@ -162,7 +167,8 @@ public void ClearColor( ClearColor = cmd, } ); - Image.UnsafeChangeState(FResourceState.RenderTarget); + if ((Flags & CommandFlags.DontTransition) == 0) + Image.UnsafeChangeState(FResourceState.RenderTarget); } #endregion @@ -230,7 +236,8 @@ public void ClearDepthStencil( ClearDepthStencil = cmd, } ); - Image.UnsafeChangeState(FResourceState.DepthWrite); + if ((Flags & CommandFlags.DontTransition) == 0) + Image.UnsafeChangeState(FResourceState.DepthWrite); } #endregion @@ -291,11 +298,14 @@ public void SetRenderTargets( SetRenderTargets = cmd, } ); - for (var i = 0; i < num_rtv; i++) + if ((Flags & CommandFlags.DontTransition) == 0) { - Rtvs[i].UnsafeChangeState(FResourceState.RenderTarget); + for (var i = 0; i < num_rtv; i++) + { + Rtvs[i].UnsafeChangeState(FResourceState.RenderTarget); + } + Dsv?.UnsafeChangeState(FResourceState.DepthWrite); } - Dsv?.UnsafeChangeState(FResourceState.DepthWrite); } #endregion @@ -335,11 +345,70 @@ public void SetViewportScissor( #endregion + #region Bind + + public void Bind( + ShaderBinding Binding, ReadOnlySpan Items, CommandFlags Flags = CommandFlags.None + ) + { + AddObject(Binding); + var cmd = new FCommandBind + { + Binding = Binding.m_ptr, + ItemCount = (uint)Items.Length, + ItemsIndex = 0 + }; + if (Items.Length > 0) + { + var index = m_payload.Count; + cmd.ItemsIndex = (uint)index; + var size = Items.Length * sizeof(FBindItem); + CollectionsMarshal.SetCount(m_payload, m_payload.Count + size); + var dst = MemoryMarshal.Cast( + CollectionsMarshal.AsSpan(m_payload).Slice(index, size) + ); + var defines = Binding.Layout.NativeDefines; + var views = Binding.MutViews; + for (var i = 0; i < Items.Length; i++) + { + var src = Items[i]; + ref readonly var define = ref defines[(int)src.Index]; + define.CheckCompatible(src.View, (int)src.Index); + dst[i] = new() + { + Index = src.Index, + View = src.View.ToFFI(), + }; + views[(int)src.Index] = src.View; + } + } + m_commands.Add( + new() + { + Type = FCommandType.Bind, + Flags = (FCommandFlags)Flags, + Bind = cmd, + } + ); + } + + #endregion + #region SetPipeline - public void SetPipeline(ShaderPipeline Pipeline, CommandFlags Flags = CommandFlags.None) + public void SetPipeline( + ShaderPipeline Pipeline, ShaderBinding? Binding = null, CommandFlags Flags = CommandFlags.None + ) { AddObject(m_current_pipeline = Pipeline); + if (Binding != null) + { + if (m_current_pipeline.Shader.Layout != Binding.Layout) + throw new ArgumentException( + "The layout of the shader bindings is incompatible with the layout of the shader pipeline" + ); + AddObject(m_current_binding = Binding); + } var cmd = new FCommandSetPipeline { Pipeline = Pipeline.m_ptr, @@ -427,13 +496,16 @@ public void SetMeshBuffers( SetMeshBuffers = cmd, } ); - if (IndexBuffer.HasValue) - { - IndexBuffer.Value.Buffer.UnsafeChangeState(FResourceState.IndexBuffer); - } - foreach (var buffer in VertexBuffers) + if ((Flags & CommandFlags.DontTransition) == 0) { - buffer.Buffer.UnsafeChangeState(FResourceState.VertexBuffer); + if (IndexBuffer.HasValue) + { + IndexBuffer.Value.Buffer.UnsafeChangeState(FResourceState.IndexBuffer); + } + foreach (var buffer in VertexBuffers) + { + buffer.Buffer.UnsafeChangeState(FResourceState.VertexBuffer); + } } } @@ -444,33 +516,38 @@ public void SetMeshBuffers( public void Draw( uint VertexCount, uint InstanceCount = 1, uint FirstVertex = 0, uint FirstInstance = 0, + ShaderBinding? Binding = null, CommandFlags Flags = CommandFlags.None - ) => Draw(null, false, VertexCount, InstanceCount, FirstVertex, FirstInstance, 0, Flags); + ) => Draw(null, false, VertexCount, InstanceCount, FirstVertex, FirstInstance, 0, Binding, Flags); public void Draw( ShaderPipeline? Pipeline, uint VertexCount, uint InstanceCount = 1, uint FirstVertex = 0, uint FirstInstance = 0, + ShaderBinding? Binding = null, CommandFlags Flags = CommandFlags.None - ) => Draw(Pipeline, false, VertexCount, InstanceCount, FirstVertex, FirstInstance, 0, Flags); + ) => Draw(Pipeline, false, VertexCount, InstanceCount, FirstVertex, FirstInstance, 0, Binding, Flags); public void DrawIndexed( uint IndexCount, uint InstanceCount = 1, uint FirstIndex = 0, uint FirstInstance = 0, uint VertexOffset = 0, + ShaderBinding? Binding = null, CommandFlags Flags = CommandFlags.None - ) => Draw(null, true, IndexCount, InstanceCount, FirstIndex, FirstInstance, VertexOffset, Flags); + ) => Draw(null, true, IndexCount, InstanceCount, FirstIndex, FirstInstance, VertexOffset, Binding, Flags); public void DrawIndexed( ShaderPipeline? Pipeline, uint IndexCount, uint InstanceCount = 1, uint FirstIndex = 0, uint FirstInstance = 0, uint VertexOffset = 0, + ShaderBinding? Binding = null, CommandFlags Flags = CommandFlags.None - ) => Draw(Pipeline, true, IndexCount, InstanceCount, FirstIndex, FirstInstance, VertexOffset, Flags); + ) => Draw(Pipeline, true, IndexCount, InstanceCount, FirstIndex, FirstInstance, VertexOffset, Binding, Flags); public void Draw( ShaderPipeline? Pipeline, bool Indexed, uint VertexOrIndexCount, uint InstanceCount = 1, uint FirstVertexOrIndex = 0, uint FirstInstance = 0, uint VertexOffset = 0, + ShaderBinding? Binding = null, CommandFlags Flags = CommandFlags.None ) { @@ -487,6 +564,14 @@ public void Draw( if (!m_current_pipeline.Shader.Stages.HasFlags(ShaderStageFlags.Vertex)) throw new ArgumentException("Non Vertex pipelines cannot use Draw"); } + if (Binding != null) + { + if (m_current_pipeline.Shader.Layout != Binding.Layout) + throw new ArgumentException( + "The layout of the shader bindings is incompatible with the layout of the shader pipeline" + ); + AddObject(m_current_binding = Binding); + } var cmd = new FCommandDraw { Pipeline = Pipeline == null ? null : Pipeline.m_ptr, @@ -621,8 +706,11 @@ public void Copy( BufferCopy = cmd, } ); - Dst.UnsafeChangeState(FResourceState.CopyDst); - Src.UnsafeChangeState(FResourceState.CopySrc); + if ((Flags & CommandFlags.DontTransition) == 0) + { + Dst.UnsafeChangeState(FResourceState.CopyDst); + Src.UnsafeChangeState(FResourceState.CopySrc); + } } #endregion @@ -665,7 +753,8 @@ public void Upload( BufferCopy = cmd, } ); - Dst.UnsafeChangeState(FResourceState.CopyDst); + if ((Flags & CommandFlags.DontTransition) == 0) + Dst.UnsafeChangeState(FResourceState.CopyDst); } public void Upload( @@ -697,7 +786,8 @@ public void Upload( BufferCopy = cmd, } ); - Dst.UnsafeChangeState(FResourceState.CopyDst); + if ((Flags & CommandFlags.DontTransition) == 0) + Dst.UnsafeChangeState(FResourceState.CopyDst); } #endregion diff --git a/Coplt.Graphics.Core/Core/GpuDevice.cs b/Coplt.Graphics.Core/Core/GpuDevice.cs index 595d446..ae47851 100644 --- a/Coplt.Graphics.Core/Core/GpuDevice.cs +++ b/Coplt.Graphics.Core/Core/GpuDevice.cs @@ -334,21 +334,7 @@ public Shader CreateShader( public ShaderBinding CreateShaderBinding( ShaderLayout Layout, string? Name = null, ReadOnlySpan Name8 = default - ) - { - fixed (char* p_name = Name) - fixed (byte* p_name8 = Name8) - { - FShaderBindingCreateOptions f_options = new() - { - Name = new(Name, Name8, p_name, p_name8), - Layout = Layout.m_ptr, - }; - FShaderBinding* ptr; - m_ptr->CreateShaderBinding(&f_options, &ptr).TryThrow(); - return new(ptr, Name, this, Layout); - } - } + ) => MainQueue.CreateShaderBinding(Layout, Name, Name8); #endregion diff --git a/Coplt.Graphics.Core/Core/GpuQueue.cs b/Coplt.Graphics.Core/Core/GpuQueue.cs index 0aeb939..3943749 100644 --- a/Coplt.Graphics.Core/Core/GpuQueue.cs +++ b/Coplt.Graphics.Core/Core/GpuQueue.cs @@ -131,6 +131,29 @@ public GpuOutput CreateOutputForHwnd( #endregion + #region CreateShaderBinding + + public ShaderBinding CreateShaderBinding( + ShaderLayout Layout, + string? Name = null, ReadOnlySpan Name8 = default + ) + { + fixed (char* p_name = Name) + fixed (byte* p_name8 = Name8) + { + FShaderBindingCreateOptions f_options = new() + { + Name = new(Name, Name8, p_name, p_name8), + Layout = Layout.m_ptr, + }; + FShaderBinding* ptr; + m_device.m_ptr->CreateShaderBinding(&f_options, &ptr).TryThrow(); + return new(ptr, Name, m_device, this, Layout); + } + } + + #endregion + #region CreateBuffer public GpuBuffer CreateBuffer( diff --git a/Coplt.Graphics.Core/Core/ShaderBinding.cs b/Coplt.Graphics.Core/Core/ShaderBinding.cs index 70e6ad7..db361ac 100644 --- a/Coplt.Graphics.Core/Core/ShaderBinding.cs +++ b/Coplt.Graphics.Core/Core/ShaderBinding.cs @@ -14,7 +14,10 @@ public sealed unsafe partial class ShaderBinding internal FShaderBinding* m_ptr; internal string? m_name; internal readonly GpuDevice m_device; + internal readonly GpuQueue m_queue; internal readonly ShaderLayout m_layout; + internal readonly FRoSlice m_native_views; + internal readonly View[] m_views; #endregion @@ -22,18 +25,32 @@ public sealed unsafe partial class ShaderBinding public FShaderBinding* Ptr => m_ptr; public GpuDevice Device => m_device; + public GpuQueue Queue => m_queue; public ShaderLayout Layout => m_layout; + public ReadOnlySpan NativeViews => m_native_views.Span; + public ReadOnlySpan Views => m_views; + internal Span MutViews => m_views; + public ref readonly View this[int index] => ref m_views[index]; #endregion #region Ctor - internal ShaderBinding(FShaderBinding* ptr, string? name, GpuDevice device, ShaderLayout layout) + internal ShaderBinding(FShaderBinding* ptr, string? name, GpuDevice device, GpuQueue queue, ShaderLayout layout) { m_name = name; m_ptr = ptr; m_device = device; + m_queue = queue; m_layout = layout; + + { + uint size = 0; + var views = m_ptr->GetViews(&size); + m_native_views = new(views, size); + } + + m_views = new View[m_native_views.Length]; } #endregion @@ -81,55 +98,4 @@ m_name is null : $"0x{nameof(ShaderBinding)}({(nuint)m_ptr:X} \"{m_name}\")"; #endregion - - #region Set - - public void Set(ReadOnlySpan Items) - { - if (Items.Length < 32) - { - var p = stackalloc FShaderBindingBatchSet[Items.Length]; - DoSet(m_ptr, p, Items); - } - else - { - var arr = ArrayPool.Shared.Rent(Items.Length); - try - { - fixed (FShaderBindingBatchSet* p = arr) - { - DoSet(m_ptr, p, Items); - } - } - finally - { - ArrayPool.Shared.Return(arr); - } - } - return; - - static void DoSet(FShaderBinding* ptr, FShaderBindingBatchSet* p, ReadOnlySpan Items) - { - for (var i = 0; i < Items.Length; i++) - { - ref readonly var item = ref Items[i]; - p[i] = new() - { - Index = item.Index, - View = item.View.ToFFI(), - }; - } - ptr->Set((uint)Items.Length, p).TryThrow(); - } - } - - public void UnsafeSet(ReadOnlySpan Items) - { - fixed (FShaderBindingBatchSet* ptr = Items) - { - m_ptr->Set((uint)Items.Length, ptr).TryThrow(); - } - } - - #endregion } diff --git a/Coplt.Graphics.Core/Core/ShaderLayout.cs b/Coplt.Graphics.Core/Core/ShaderLayout.cs index 38a3166..844a2fb 100644 --- a/Coplt.Graphics.Core/Core/ShaderLayout.cs +++ b/Coplt.Graphics.Core/Core/ShaderLayout.cs @@ -102,15 +102,14 @@ public sealed unsafe partial class ShaderLayout internal FShaderLayout* m_ptr; internal string? m_name; - internal readonly FShaderLayoutItemDefine* m_native_defines; - internal readonly uint m_native_defines_count; + internal readonly FRoSlice m_native_defines; #endregion #region Props public FShaderLayout* Ptr => m_ptr; - public ReadOnlySpan NativeElements => new(m_native_defines, (int)m_native_defines_count); + public ReadOnlySpan NativeDefines => m_native_defines.Span; #endregion @@ -122,9 +121,9 @@ internal ShaderLayout(FShaderLayout* ptr, string? name) m_name = name; if (m_ptr != null) { - uint count; - m_native_defines = m_ptr->GetItemDefines(&count); - m_native_defines_count = count; + uint count = 0; + var defines = m_ptr->GetItemDefines(&count); + m_native_defines = new(defines, count); } } diff --git a/Coplt.Graphics.Core/Native/FShaderLayoutItemDefine.cs b/Coplt.Graphics.Core/Native/FShaderLayoutItemDefine.cs new file mode 100644 index 0000000..1ee5c88 --- /dev/null +++ b/Coplt.Graphics.Core/Native/FShaderLayoutItemDefine.cs @@ -0,0 +1,25 @@ +using Coplt.Graphics.Core; + +namespace Coplt.Graphics.Native; + +public partial struct FShaderLayoutItemDefine +{ + /// + /// 检查兼容性,不兼容将 throw + /// + public readonly void CheckCompatible(in View view, int index) + { + switch (view.Tag) + { + case Core.View.Tags.None: + break; + case Core.View.Tags.Buffer: + if (Type is not (FShaderLayoutItemType.ConstantBuffer or FShaderLayoutItemType.RawBuffer + or FShaderLayoutItemType.StructureBuffer or FShaderLayoutItemType.StructureBufferWithCounter)) + throw new ArgumentException($"Binding slot {index} does not supports buffers"); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } +} diff --git a/Coplt.Graphics.Core/Native/FSlice.cs b/Coplt.Graphics.Core/Native/FSlice.cs new file mode 100644 index 0000000..a3307c0 --- /dev/null +++ b/Coplt.Graphics.Core/Native/FSlice.cs @@ -0,0 +1,153 @@ +using System.Runtime.CompilerServices; + +namespace Coplt.Graphics.Native; + +public readonly unsafe struct FSlice(T* Data, nuint Size) : IEquatable> +{ + #region Fields + + public readonly T* Data = Data; + public readonly nuint Size = Size; + + #endregion + + #region Props + + public bool IsEmpty => Size == 0; + public int Length => (int)(uint)Size; + + public Span Span => new(Data, Length); + + public ref T this[int index] => ref Span[index]; + + #endregion + + #region Convert + + public static implicit operator Span(FSlice Slice) => new(Slice.Data, Slice.Length); + + public static implicit operator ReadOnlySpan(FSlice Slice) => new(Slice.Data, Slice.Length); + + public static implicit operator FRoSlice(FSlice Slice) => new(Slice.Data, Slice.Size); + + #endregion + + #region Equals + + public bool Equals(FSlice other) => Data == other.Data && Size == other.Size; + public override bool Equals(object? obj) => obj is FSlice other && Equals(other); + public override int GetHashCode() => HashCode.Combine(unchecked((int)(long)Data), Size); + public static bool operator ==(FSlice left, FSlice right) => left.Equals(right); + public static bool operator !=(FSlice left, FSlice right) => !left.Equals(right); + + #endregion + + #region ToString + + public override string ToString() + { + if (typeof(T) == typeof(char)) return Span.ToString(); + return $"FSlice<{typeof(T).Name}>(0x{(nuint)Data:X})[{Size}]"; + } + + #endregion + + #region Slice + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public FSlice Slice(int start) + { + ArgumentOutOfRangeException.ThrowIfGreaterThan((uint)start, (ulong)Size); + return new(Data + (nuint)(uint)start, Size - (uint)start); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public FSlice Slice(int start, int length) + { + ArgumentOutOfRangeException.ThrowIfGreaterThan((uint)start + (uint)length, (ulong)Size); + return new(Data + (nuint)(uint)start, (uint)length); + } + + #endregion + + #region Enumerator + + public Span.Enumerator GetEnumerator() => Span.GetEnumerator(); + + #endregion +} + +public readonly unsafe struct FRoSlice(T* Data, nuint Size) : IEquatable> +{ + #region Fields + + public readonly T* Data = Data; + public readonly nuint Size = Size; + + #endregion + + #region Props + + public bool IsEmpty => Size == 0; + public int Length => (int)(uint)Size; + + public ReadOnlySpan Span => new(Data, Length); + + public ref readonly T this[int index] => ref Span[index]; + + #endregion + + #region Convert + + public static explicit operator Span(FRoSlice Slice) => new(Slice.Data, Slice.Length); + + public static implicit operator ReadOnlySpan(FRoSlice Slice) => new(Slice.Data, Slice.Length); + + public static explicit operator FSlice(FRoSlice Slice) => new(Slice.Data, Slice.Size); + + #endregion + + #region Equals + + public bool Equals(FRoSlice other) => Data == other.Data && Size == other.Size; + public override bool Equals(object? obj) => obj is FRoSlice other && Equals(other); + public override int GetHashCode() => HashCode.Combine(unchecked((int)(long)Data), Size); + public static bool operator ==(FRoSlice left, FRoSlice right) => left.Equals(right); + public static bool operator !=(FRoSlice left, FRoSlice right) => !left.Equals(right); + + #endregion + + #region ToString + + public override string ToString() + { + if (typeof(T) == typeof(char)) return Span.ToString(); + return $"FRoSlice<{typeof(T).Name}>(0x{(nuint)Data:X})[{Size}]"; + } + + #endregion + + #region Slice + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public FRoSlice Slice(int start) + { + ArgumentOutOfRangeException.ThrowIfGreaterThan((uint)start, (ulong)Size); + return new(Data + (nuint)(uint)start, Size - (uint)start); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public FRoSlice Slice(int start, int length) + { + ArgumentOutOfRangeException.ThrowIfGreaterThan((uint)start + (uint)length, (ulong)Size); + return new(Data + (nuint)(uint)start, (uint)length); + } + + #endregion + + #region Enumerator + + public ReadOnlySpan.Enumerator GetEnumerator() => Span.GetEnumerator(); + + #endregion +} diff --git a/Coplt.Graphics.Core/Native/Native.cs b/Coplt.Graphics.Core/Native/Native.cs index d72879c..1abbe03 100644 --- a/Coplt.Graphics.Core/Native/Native.cs +++ b/Coplt.Graphics.Core/Native/Native.cs @@ -2273,6 +2273,7 @@ public enum FCommandType : uint ClearDepthStencil, SetRenderTargets, SetViewportScissor, + Bind, SetPipeline, SetMeshBuffers, Draw, @@ -2297,7 +2298,7 @@ public enum FResourceRefType : byte public unsafe partial struct FResourceMeta { - [NativeTypeName("__AnonymousRecord_Command_L45_C9")] + [NativeTypeName("__AnonymousRecord_Command_L47_C9")] public _Anonymous_e__Union Anonymous; [NativeTypeName("Coplt::FResourceState")] @@ -2494,10 +2495,34 @@ public partial struct FCommandSetViewportScissor public uint ScissorRectIndex; } + public partial struct FBindItem + { + [NativeTypeName("Coplt::FView")] + public FView View; + + [NativeTypeName("Coplt::u32")] + public uint Index; + } + + public unsafe partial struct FCommandBind + { + [NativeTypeName("Coplt::FShaderBinding *")] + public FShaderBinding* Binding; + + [NativeTypeName("Coplt::u32")] + public uint ItemCount; + + [NativeTypeName("Coplt::u32")] + public uint ItemsIndex; + } + public unsafe partial struct FCommandSetPipeline { [NativeTypeName("Coplt::FShaderPipeline *")] public FShaderPipeline* Pipeline; + + [NativeTypeName("Coplt::FShaderBinding *")] + public FShaderBinding* Binding; } public partial struct FBufferRange @@ -2547,6 +2572,9 @@ public unsafe partial struct FCommandDraw [NativeTypeName("Coplt::FShaderPipeline *")] public FShaderPipeline* Pipeline; + [NativeTypeName("Coplt::FShaderBinding *")] + public FShaderBinding* Binding; + [NativeTypeName("Coplt::u32")] public uint VertexOrIndexCount; @@ -2578,6 +2606,9 @@ public unsafe partial struct FCommandDispatch [NativeTypeName("Coplt::FShaderPipeline *")] public FShaderPipeline* Pipeline; + [NativeTypeName("Coplt::FShaderBinding *")] + public FShaderBinding* Binding; + [NativeTypeName("Coplt::u32")] public uint GroupCountX; @@ -2648,7 +2679,7 @@ public partial struct FCommandItem [NativeTypeName("Coplt::FCommandFlags")] public FCommandFlags Flags; - [NativeTypeName("__AnonymousRecord_Command_L271_C9")] + [NativeTypeName("__AnonymousRecord_Command_L295_C9")] public _Anonymous_e__Union Anonymous; [UnscopedRef] @@ -2711,6 +2742,16 @@ public ref FCommandSetViewportScissor SetViewportScissor } } + [UnscopedRef] + public ref FCommandBind Bind + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.Bind; + } + } + [UnscopedRef] public ref FCommandSetPipeline SetPipeline { @@ -2798,6 +2839,10 @@ public partial struct _Anonymous_e__Union [NativeTypeName("Coplt::FCommandSetViewportScissor")] public FCommandSetViewportScissor SetViewportScissor; + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandBind")] + public FCommandBind Bind; + [FieldOffset(0)] [NativeTypeName("Coplt::FCommandSetPipeline")] public FCommandSetPipeline SetPipeline; diff --git a/Coplt.Graphics.Native/Api/FFI/Command.h b/Coplt.Graphics.Native/Api/FFI/Command.h index 21b83e6..6b4f691 100644 --- a/Coplt.Graphics.Native/Api/FFI/Command.h +++ b/Coplt.Graphics.Native/Api/FFI/Command.h @@ -1,5 +1,6 @@ #pragma once +#include "Binding.h" #include "Blob.h" #include "Output.h" #include "Pipeline.h" @@ -18,6 +19,7 @@ namespace Coplt ClearDepthStencil, SetRenderTargets, SetViewportScissor, + Bind, SetPipeline, SetMeshBuffers, Draw, @@ -135,7 +137,7 @@ namespace Coplt { // 有多少个 Rect u32 RectCount{}; - // Payload 内的索引 + // Payload 内的索引, 类型为 FRect u32 RectIndex{}; FResourceRef Image{}; f32 Depth{}; @@ -152,11 +154,11 @@ namespace Coplt // 有多少个 Viewport u32 ViewportCount{}; - // Payload 内的索引 + // Payload 内的索引, 类型为 FViewport u32 ViewportIndex{}; // 有多少个 Rect u32 ScissorRectCount{}; - // Payload 内的索引 + // Payload 内的索引, 类型为 FRect u32 ScissorRectIndex{}; }; @@ -168,13 +170,31 @@ namespace Coplt u32 ViewportIndex{}; // 有多少个 Rect u32 ScissorRectCount{}; - // Payload 内的索引 + // Payload 内的索引, 类型为 FRect u32 ScissorRectIndex{}; }; + struct FBindItem + { + FView View{}; + u32 Index{}; + }; + + struct FCommandBind + { + // 要修改的绑定集 + FShaderBinding* Binding{}; + // 有多少个绑定修改 + u32 ItemCount{}; + // Payload 内的索引, 类型为 FBindItem + u32 ItemsIndex{}; + }; + struct FCommandSetPipeline { FShaderPipeline* Pipeline{}; + // 可选 + FShaderBinding* Binding{}; }; struct FBufferRange @@ -207,6 +227,8 @@ namespace Coplt { // 可选 FShaderPipeline* Pipeline{}; + // 可选 + FShaderBinding* Binding{}; u32 VertexOrIndexCount{}; u32 InstanceCount{}; u32 FirstVertexOrIndex{}; @@ -226,6 +248,8 @@ namespace Coplt { // 可选 FShaderPipeline* Pipeline{}; + // 可选 + FShaderBinding* Binding{}; u32 GroupCountX{}; u32 GroupCountY{}; u32 GroupCountZ{}; @@ -276,6 +300,7 @@ namespace Coplt FCommandClearDepthStencil ClearDepthStencil; FCommandSetRenderTargets SetRenderTargets; FCommandSetViewportScissor SetViewportScissor; + FCommandBind Bind; FCommandSetPipeline SetPipeline; FCommandSetMeshBuffers SetMeshBuffers; FCommandDraw Draw; diff --git a/Coplt.Graphics.Native/D3d12/Src/Command.cc b/Coplt.Graphics.Native/D3d12/Src/Command.cc index 66a7e97..50ee419 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Command.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Command.cc @@ -157,6 +157,8 @@ void D3d12CommandInterpreter::CollectBarrier(const FCommandSubmit& submit) goto ClearDepthStencil; case FCommandType::SetRenderTargets: goto SetRenderTargets; + case FCommandType::Bind: + goto Bind; case FCommandType::SetPipeline: goto SetPipeline; case FCommandType::SetMeshBuffers: @@ -208,10 +210,17 @@ void D3d12CommandInterpreter::CollectBarrier(const FCommandSubmit& submit) } continue; } + Bind: + { + const auto& cmd = item.Bind; + // todo + continue; + } SetPipeline: { const auto& cmd = item.SetPipeline; SetPipelineContext(cmd.Pipeline, i); + continue; } SetMeshBuffers: { @@ -345,6 +354,8 @@ void D3d12CommandInterpreter::Translate(const FCommandSubmit& submit) goto SetRenderTargets; case FCommandType::SetViewportScissor: goto SetViewportScissor; + case FCommandType::Bind: + goto Bind; case FCommandType::SetPipeline: goto SetPipeline; case FCommandType::SetMeshBuffers: @@ -411,6 +422,12 @@ void D3d12CommandInterpreter::Translate(const FCommandSubmit& submit) if (cmd.ScissorRectCount > 0) cmd_pack->RSSetScissorRects(cmd.ScissorRectCount, scissor); continue; } + Bind: + { + const auto& cmd = item.Bind; + // todo + continue; + } SetPipeline: { const auto& cmd = item.SetPipeline; diff --git a/Examples/Colorful/Example.cs b/Examples/Colorful/Example.cs index f20292c..93b0299 100644 --- a/Examples/Colorful/Example.cs +++ b/Examples/Colorful/Example.cs @@ -56,7 +56,7 @@ protected override async Task LoadResources(CommandList cmd) }, Name: "Args" ); - ShaderBinding.Set([new(0, ArgBuffer)]); + cmd.Bind(ShaderBinding, [new(0, ArgBuffer)]); } protected override void Render(CommandList cmd, Time time) { From 885b83cf0f8969a6dc5db5b3ee02f4cde573c996 Mon Sep 17 00:00:00 2001 From: U2A5F Date: Wed, 26 Feb 2025 21:51:00 +0800 Subject: [PATCH 10/23] save --- .idea/vcs.xml | 2 +- Coplt.Graphics.Core/Core/CommandList.cs | 1521 ++++++++++++++------ Coplt.Graphics.Core/Core/GpuExecutor.cs | 92 ++ Coplt.Graphics.Core/Core/GpuOutput.cs | 129 +- Coplt.Graphics.Core/Core/GpuQueue.cs | 20 +- Coplt.Graphics.Core/Native/FUploadLoc.cs | 2 + Coplt.Graphics.Core/Native/Native.D3d12.cs | 32 +- Coplt.Graphics.Core/Native/Native.cs | 1120 ++++++++++---- Coplt.Graphics.Native/Api/CMakeLists.txt | 1 + Coplt.Graphics.Native/Api/FFI/Command.h | 434 ++++-- Coplt.Graphics.Native/Api/FFI/Executor.h | 12 + Coplt.Graphics.Native/Api/FFI/Output.h | 15 +- Coplt.Graphics.Native/Api/FFI/Queue.h | 5 + Coplt.Graphics.Native/Api/Include/Object.h | 10 + Coplt.Graphics.Native/D3d12/CMakeLists.txt | 1 + Coplt.Graphics.Native/D3d12/Src/Command.cc | 458 +++--- Coplt.Graphics.Native/D3d12/Src/Command.h | 4 +- Coplt.Graphics.Native/D3d12/Src/Executor.h | 14 + Coplt.Graphics.Native/D3d12/Src/Output.cc | 30 +- Coplt.Graphics.Native/D3d12/Src/Output.h | 10 +- Coplt.Graphics.Native/D3d12/Src/Queue.cc | 22 + Coplt.Graphics.Native/D3d12/Src/Queue.h | 4 + Examples/Colorful/Example.cs | 5 +- Examples/HelloTriangle/Example.cs | 7 +- Examples/HelloTriangleVertex/Example.cs | 7 +- 25 files changed, 2684 insertions(+), 1273 deletions(-) create mode 100644 Coplt.Graphics.Core/Core/GpuExecutor.cs create mode 100644 Coplt.Graphics.Native/Api/FFI/Executor.h create mode 100644 Coplt.Graphics.Native/D3d12/Src/Executor.h diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 5d7b1f3..dd3e634 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -5,8 +5,8 @@ + - diff --git a/Coplt.Graphics.Core/Core/CommandList.cs b/Coplt.Graphics.Core/Core/CommandList.cs index acf86dc..b045400 100644 --- a/Coplt.Graphics.Core/Core/CommandList.cs +++ b/Coplt.Graphics.Core/Core/CommandList.cs @@ -1,7 +1,9 @@ using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using Coplt.Dropping; using Coplt.Graphics.Native; +using Coplt.Union; namespace Coplt.Graphics.Core; @@ -25,13 +27,22 @@ public sealed unsafe class CommandList internal readonly GpuQueue m_queue; internal readonly List m_commands = new(); + internal readonly List m_render_commands = new(); + internal readonly List m_compute_commands = new(); internal readonly List m_resource_metas = new(); + internal readonly List m_render_infos = new(); + internal readonly List m_resolve_infos = new(); + internal readonly List m_rects = new(); + internal readonly List m_viewports = new(); + internal readonly List m_mesh_buffers = new(); + internal readonly List m_vertex_buffer_ranges = new(); + internal readonly List m_buffer_copy_ranges = new(); + internal readonly List m_bind_items = new(); + internal readonly List m_string8 = new(); + internal readonly List m_string16 = new(); internal readonly Dictionary m_resources = new(); internal readonly HashSet m_objects = new(); - internal readonly List m_payload = new(); internal GpuOutput? m_current_output; - internal ShaderPipeline? m_current_pipeline; - internal ShaderBinding? m_current_binding; #endregion @@ -55,20 +66,80 @@ internal CommandList(GpuQueue mQueue) internal void Reset() { m_commands.Clear(); + m_render_commands.Clear(); + m_compute_commands.Clear(); + m_render_infos.Clear(); + m_resolve_infos.Clear(); + m_rects.Clear(); + m_viewports.Clear(); + m_mesh_buffers.Clear(); + m_vertex_buffer_ranges.Clear(); + m_buffer_copy_ranges.Clear(); + m_string8.Clear(); + m_string16.Clear(); m_resource_metas.Clear(); m_resources.Clear(); m_objects.Clear(); - m_payload.Clear(); m_current_output = null; - m_current_pipeline = null; - m_current_binding = null; + } + + #endregion + + #region Submit + + internal void Submit(GpuQueue Queue, GpuExecutor Executor, bool NoWait) + { + fixed (FCommandItem* p_commands = CollectionsMarshal.AsSpan(m_commands)) + fixed (FRenderCommandItem* p_render_commands = CollectionsMarshal.AsSpan(m_render_commands)) + fixed (FComputeCommandItem* p_compute_commands = CollectionsMarshal.AsSpan(m_compute_commands)) + fixed (FResourceMeta* p_resources = CollectionsMarshal.AsSpan(m_resource_metas)) + fixed (FRenderInfo* p_render_infos = CollectionsMarshal.AsSpan(m_render_infos)) + fixed (FResolveInfo* p_resolve_infos = CollectionsMarshal.AsSpan(m_resolve_infos)) + fixed (FRect* p_rects = CollectionsMarshal.AsSpan(m_rects)) + fixed (FViewport* p_viewports = CollectionsMarshal.AsSpan(m_viewports)) + fixed (FMeshBuffers* p_mesh_buffers = CollectionsMarshal.AsSpan(m_mesh_buffers)) + fixed (FVertexBufferRange* p_vertex_buffer_ranges = CollectionsMarshal.AsSpan(m_vertex_buffer_ranges)) + fixed (FBufferCopyRange* p_buffer_copy_ranges = CollectionsMarshal.AsSpan(m_buffer_copy_ranges)) + fixed (FBindItem* p_bind_items = CollectionsMarshal.AsSpan(m_bind_items)) + fixed (byte* p_string8 = CollectionsMarshal.AsSpan(m_string8)) + fixed (char* p_string16 = CollectionsMarshal.AsSpan(m_string16)) + { + FCommandSubmit submit = new() + { + Commands = p_commands, + RenderCommands = p_render_commands, + ComputeCommands = p_compute_commands, + Resources = p_resources, + RenderInfos = p_render_infos, + ResolveInfos = p_resolve_infos, + Rects = p_rects, + Viewports = p_viewports, + MeshBuffers = p_mesh_buffers, + VertexBufferRanges = p_vertex_buffer_ranges, + BufferCopyRanges = p_buffer_copy_ranges, + BindItems = p_bind_items, + Str8 = p_string8, + Str16 = p_string16, + CommandCount = (uint)m_commands.Count, + ResourceCount = (uint)m_resource_metas.Count, + }; + try + { + if (NoWait) Queue.m_ptr->SubmitNoWait(Executor.m_ptr, &submit).TryThrow(); + else Queue.m_ptr->Submit(Executor.m_ptr, &submit).TryThrow(); + } + finally + { + Reset(); + } + } } #endregion #region AddResource - private int AddResource(T resource) where T : IGpuResource + internal FResourceRef AddResource(T resource) where T : IGpuResource { if (resource.Queue != m_queue) throw new ArgumentException($"Resource {resource} does not belong to queue {m_queue}"); @@ -84,7 +155,7 @@ private int AddResource(T resource) where T : IGpuResource slot = m_resource_metas.Count; m_resource_metas.Add(resource.GetMeta()); } - return slot; + return new(slot + 1); } #endregion @@ -100,23 +171,100 @@ private int AddResource(T resource) where T : IGpuResource #region Commands + #region Debug + + #region AddString + + internal uint AddString(string str) + { + var index = m_string16.Count; + CollectionsMarshal.SetCount(m_string16, index + str.Length); + var dst = CollectionsMarshal.AsSpan(m_string16).Slice(index, str.Length); + str.CopyTo(dst); + return (uint)index; + } + + internal uint AddString(ReadOnlySpan str) + { + var index = m_string8.Count; + CollectionsMarshal.SetCount(m_string8, index + str.Length); + var dst = CollectionsMarshal.AsSpan(m_string8).Slice(index, str.Length); + str.CopyTo(dst); + return (uint)index; + } + + #endregion + + #region Label + + public void Label(string Label) + { + var cmd = new FCommandLabel + { + Base = { Type = FCommandType.Label }, + StringIndex = AddString(Label), + StringLength = (uint)Label.Length, + StrType = FStrType.Str16, + }; + m_commands.Add(new() { Label = cmd }); + } + + public void Label(ReadOnlySpan Label) + { + var cmd = new FCommandLabel + { + Base = { Type = FCommandType.Label }, + StringIndex = AddString(Label), + StringLength = (uint)Label.Length, + StrType = FStrType.Str8, + }; + m_commands.Add(new() { Label = cmd }); + } + + #endregion + + #region Scope + + public DebugScope Scope(string Name) + { + var cmd = new FCommandLabel + { + Base = { Type = FCommandType.BeginScope }, + StringIndex = AddString(Name), + StringLength = (uint)Name.Length, + StrType = FStrType.Str16, + }; + m_commands.Add(new() { Label = cmd }); + return new(this); + } + + public DebugScope Scope(ReadOnlySpan Name) + { + var cmd = new FCommandLabel + { + Base = { Type = FCommandType.BeginScope }, + StringIndex = AddString(Name), + StringLength = (uint)Name.Length, + StrType = FStrType.Str8, + }; + m_commands.Add(new() { Label = cmd }); + return new(this); + } + + #endregion + + #endregion + #region Present internal void Present(GpuOutput Output, CommandFlags Flags = CommandFlags.None) { - var index = AddResource(Output); var cmd = new FCommandPresent { - Image = new(index), + Base = { Type = FCommandType.Present }, + Image = AddResource(Output), }; - m_commands.Add( - new() - { - Type = FCommandType.Present, - Flags = (FCommandFlags)Flags, - Present = cmd, - } - ); + m_commands.Add(new() { Present = cmd }); if ((Flags & CommandFlags.DontTransition) == 0) Output.UnsafeChangeState(FResourceState.Present); } @@ -143,30 +291,19 @@ public void ClearColor( { if (!Image.TryRtv()) throw new ArgumentException($"Resource {Image} cannot be used as Rtv"); - var index = AddResource(Image); - var cmd = new FCommandClearColor { + Base = { Type = FCommandType.ClearColor }, RectCount = (uint)Rects.Length, - Image = new(index), + Image = AddResource(Image), + Color = Unsafe.BitCast(Color), }; - cmd.Color[0] = Color.r; - cmd.Color[1] = Color.g; - cmd.Color[2] = Color.b; - cmd.Color[3] = Color.a; if (Rects.Length > 0) { - cmd.RectIndex = (uint)m_payload.Count; - m_payload.AddRange(MemoryMarshal.AsBytes(Rects)); + cmd.RectIndex = (uint)m_rects.Count; + m_rects.AddRange(MemoryMarshal.Cast(Rects)); } - m_commands.Add( - new() - { - Type = FCommandType.ClearColor, - Flags = (FCommandFlags)Flags, - ClearColor = cmd, - } - ); + m_commands.Add(new() { ClearColor = cmd }); if ((Flags & CommandFlags.DontTransition) == 0) Image.UnsafeChangeState(FResourceState.RenderTarget); } @@ -213,138 +350,27 @@ public void ClearDepthStencil( { if (!Image.TryDsv()) throw new ArgumentException($"Resource {Image} cannot be used as Dsv"); - var index = AddResource(Image); - var cmd = new FCommandClearDepthStencil { + Base = { Type = FCommandType.ClearDepthStencil }, RectCount = (uint)Rects.Length, - Image = new(index), + Image = AddResource(Image), Depth = Depth, Stencil = Stencil, Clear = (FDepthStencilClearFlags)Clear, }; if (Rects.Length > 0) { - cmd.RectIndex = (uint)m_payload.Count; - m_payload.AddRange(MemoryMarshal.AsBytes(Rects)); + cmd.RectIndex = (uint)m_rects.Count; + m_rects.AddRange(MemoryMarshal.Cast(Rects)); } - m_commands.Add( - new() - { - Type = FCommandType.ClearDepthStencil, - Flags = (FCommandFlags)Flags, - ClearDepthStencil = cmd, - } - ); + m_commands.Add(new() { ClearDepthStencil = cmd }); if ((Flags & CommandFlags.DontTransition) == 0) Image.UnsafeChangeState(FResourceState.DepthWrite); } #endregion - #region SetRenderTargets - - public void SetRenderTargets( - ReadOnlySpan Rtvs, IDsvRes? Dsv = null, - bool AutoViewportScissor = true, - CommandFlags Flags = CommandFlags.None - ) - { - if (Rtvs.Length == 0 && Dsv == null) throw new ArgumentException("No Rtvs or Dsv"); - var num_rtv = Math.Min(Rtvs.Length, 8); - for (var i = 0; i < num_rtv; i++) - { - var rtv = Rtvs[i]; - if (!rtv.TryRtv()) throw new ArgumentException($"Resource {rtv} cannot be used as Rtv"); - } - if (Dsv != null && !Dsv.TryDsv()) throw new ArgumentException($"Resource {Dsv} cannot be used as Dsv"); - - var cmd = new FCommandSetRenderTargets - { - Dsv = Dsv == null ? new(uint.MaxValue) : new(AddResource(Dsv)), - NumRtv = (uint)num_rtv, - }; - var rt_size = Dsv?.Size ?? Rtvs[0].Size; - for (var i = 0; i < num_rtv; i++) - { - cmd.Rtv[i] = new(AddResource(Rtvs[i])); - if (!Rtvs[i].Size.Equals(rt_size)) - throw new ArgumentException($"RenderTargets And DepthStencil must be the same size"); - } - if (AutoViewportScissor) - { - cmd.ViewportCount = 1; - cmd.ScissorRectCount = 1; - var viewport = new UViewPort - { - Width = rt_size.x, - Height = rt_size.y, - }; - var scissor = new URect - { - Right = rt_size.x, - Bottom = rt_size.y, - }; - cmd.ViewportIndex = (uint)m_payload.Count; - m_payload.AddRange(MemoryMarshal.AsBytes(new ReadOnlySpan(in viewport))); - cmd.ScissorRectIndex = (uint)m_payload.Count; - m_payload.AddRange(MemoryMarshal.AsBytes(new ReadOnlySpan(in scissor))); - } - m_commands.Add( - new() - { - Type = FCommandType.SetRenderTargets, - Flags = (FCommandFlags)Flags, - SetRenderTargets = cmd, - } - ); - if ((Flags & CommandFlags.DontTransition) == 0) - { - for (var i = 0; i < num_rtv; i++) - { - Rtvs[i].UnsafeChangeState(FResourceState.RenderTarget); - } - Dsv?.UnsafeChangeState(FResourceState.DepthWrite); - } - } - - #endregion - - #region SetViewportScissor - - public void SetViewportScissor( - ReadOnlySpan Viewports, - ReadOnlySpan Scissors, - CommandFlags Flags = CommandFlags.None - ) - { - var cmd = new FCommandSetViewportScissor - { - ViewportCount = (uint)Viewports.Length, - ScissorRectCount = (uint)Scissors.Length, - }; - if (Viewports.Length > 0) - { - cmd.ViewportIndex = (uint)m_payload.Count; - m_payload.AddRange(MemoryMarshal.AsBytes(Viewports)); - } - if (Scissors.Length > 0) - { - cmd.ScissorRectIndex = (uint)m_payload.Count; - m_payload.AddRange(MemoryMarshal.AsBytes(Scissors)); - } - m_commands.Add( - new() - { - Type = FCommandType.SetViewportScissor, - Flags = (FCommandFlags)Flags, - SetViewportScissor = cmd, - } - ); - } - - #endregion - #region Bind public void Bind( @@ -354,19 +380,17 @@ public void Bind( AddObject(Binding); var cmd = new FCommandBind { + Base = { Type = FCommandType.Bind }, Binding = Binding.m_ptr, ItemCount = (uint)Items.Length, ItemsIndex = 0 }; if (Items.Length > 0) { - var index = m_payload.Count; + var index = m_bind_items.Count; cmd.ItemsIndex = (uint)index; - var size = Items.Length * sizeof(FBindItem); - CollectionsMarshal.SetCount(m_payload, m_payload.Count + size); - var dst = MemoryMarshal.Cast( - CollectionsMarshal.AsSpan(m_payload).Slice(index, size) - ); + CollectionsMarshal.SetCount(m_bind_items, m_bind_items.Count + Items.Length); + var dst = CollectionsMarshal.AsSpan(m_bind_items).Slice(index, Items.Length); var defines = Binding.Layout.NativeDefines; var views = Binding.MutViews; for (var i = 0; i < Items.Length; i++) @@ -382,199 +406,771 @@ public void Bind( views[(int)src.Index] = src.View; } } - m_commands.Add( - new() - { - Type = FCommandType.Bind, - Flags = (FCommandFlags)Flags, - Bind = cmd, - } - ); + m_commands.Add(new() { Bind = cmd }); } #endregion - #region SetPipeline + #region BufferCopy - public void SetPipeline( - ShaderPipeline Pipeline, ShaderBinding? Binding = null, CommandFlags Flags = CommandFlags.None + public void Copy( + GpuBuffer Dst, + GpuBuffer Src, + ulong DstOffset = 0, + ulong SrcOffset = 0, + ulong Size = ulong.MaxValue, + CommandFlags Flags = CommandFlags.None ) { - AddObject(m_current_pipeline = Pipeline); - if (Binding != null) + if (Size != ulong.MaxValue) { - if (m_current_pipeline.Shader.Layout != Binding.Layout) - throw new ArgumentException( - "The layout of the shader bindings is incompatible with the layout of the shader pipeline" - ); - AddObject(m_current_binding = Binding); + if (DstOffset + Size > Dst.Size) throw new ArgumentException("The copy range exceeds the buffer range"); + if (SrcOffset + Size > Src.Size) throw new ArgumentException("The copy range exceeds the buffer range"); } - var cmd = new FCommandSetPipeline + else if (Dst == Src || Dst.Size != Src.Size) Size = Math.Min(Dst.Size, Src.Size); + var cmd = new FCommandBufferCopy { - Pipeline = Pipeline.m_ptr, + Base = { Type = FCommandType.BufferCopy }, + RangeIndex = (uint)m_buffer_copy_ranges.Count, + Dst = { Buffer = AddResource(Dst) }, + DstType = FBufferRefType.Buffer, + Src = { Buffer = AddResource(Src) }, + SrcType = FBufferRefType.Buffer, }; - m_commands.Add( + m_buffer_copy_ranges.Add( new() { - Type = FCommandType.SetPipeline, - Flags = (FCommandFlags)Flags, - SetPipeline = cmd, + Size = Size, + DstOffset = DstOffset, + SrcOffset = SrcOffset, } ); + m_commands.Add(new() { BufferCopy = cmd }); + if ((Flags & CommandFlags.DontTransition) == 0) + { + Dst.UnsafeChangeState(FResourceState.CopyDst); + Src.UnsafeChangeState(FResourceState.CopySrc); + } } #endregion - #region SetMeshBuffers - - public void SetMeshBuffers( - MeshLayout MeshLayout, - uint VertexStartSlot, - ReadOnlySpan VertexBuffers, - CommandFlags Flags = CommandFlags.None - ) => SetMeshBuffers(MeshLayout, FGraphicsFormat.Unknown, null, VertexStartSlot, VertexBuffers, Flags); + #region BufferUpload - public void SetMeshBuffers( - MeshLayout MeshLayout, - ReadOnlySpan VertexBuffers, + public void Upload( + GpuBuffer Dst, + ReadOnlySpan Data, + ulong DstOffset = 0, CommandFlags Flags = CommandFlags.None - ) => SetMeshBuffers(MeshLayout, FGraphicsFormat.Unknown, null, 0, VertexBuffers, Flags); + ) where T : unmanaged => Upload(Dst, MemoryMarshal.AsBytes(Data), DstOffset, Flags); - public void SetMeshBuffers( - MeshLayout MeshLayout, - FGraphicsFormat IndexFormat, - BufferRange? IndexBuffer, - uint VertexStartSlot, - ReadOnlySpan VertexBuffers, + public void Upload( + GpuBuffer Dst, + ReadOnlySpan Data, + ulong DstOffset = 0, CommandFlags Flags = CommandFlags.None ) { - AddObject(MeshLayout); - var cmd = new FCommandSetMeshBuffers + if (Data.Length == 0) return; + var Size = Math.Min(Dst.Size, (uint)Data.Length); + var src = m_queue.WriteToUpload(Data); + var cmd = new FCommandBufferCopy { - MeshLayout = MeshLayout.m_ptr, - IndexFormat = IndexFormat, - IndexBuffer = IndexBuffer is { } index_buffer - ? new() - { - Buffer = new(AddResource(index_buffer.Buffer)), - Offset = index_buffer.Offset, - Size = index_buffer.Size == uint.MaxValue ? (uint)index_buffer.Buffer.LongSize : index_buffer.Size, - } - : new() - { - Buffer = new(uint.MaxValue), - }, - VertexStartSlot = VertexStartSlot, - VertexBufferCount = (uint)VertexBuffers.Length, + Base = { Type = FCommandType.BufferCopy }, + RangeIndex = (uint)m_buffer_copy_ranges.Count, + Dst = { Buffer = AddResource(Dst) }, + DstType = FBufferRefType.Buffer, + Src = { Upload = src }, + SrcType = FBufferRefType.Upload, }; - if (VertexBuffers.Length > 0) - { - cmd.VertexBuffersIndex = (uint)m_payload.Count; - Span vbs = stackalloc FVertexBufferRange[VertexBuffers.Length]; - for (var i = 0; i < VertexBuffers.Length; i++) - { - var buffer = VertexBuffers[i]; - vbs[i] = new() - { - Base = - { - Buffer = new(AddResource(buffer.Buffer)), - Offset = buffer.Offset, - Size = buffer.Size == uint.MaxValue ? (uint)buffer.Buffer.LongSize : buffer.Size, - }, - Index = buffer.Index, - }; - } - m_payload.AddRange(MemoryMarshal.AsBytes(vbs)); - } - m_commands.Add( + m_buffer_copy_ranges.Add( new() { - Type = FCommandType.SetMeshBuffers, - Flags = (FCommandFlags)Flags, - SetMeshBuffers = cmd, + Size = Size, + DstOffset = DstOffset, + SrcOffset = src.Offset, } ); + m_commands.Add(new() { BufferCopy = cmd }); if ((Flags & CommandFlags.DontTransition) == 0) + Dst.UnsafeChangeState(FResourceState.CopyDst); + } + + public void Upload( + GpuBuffer Dst, + UploadLoc Loc, + ulong DstOffset = 0, + CommandFlags Flags = CommandFlags.None + ) + { + if (Loc.SubmitId != m_queue.SubmitId) + throw new ArgumentException("An attempt was made to use an expired upload location"); + var Size = Math.Min(Dst.Size, Loc.Size); + var cmd = new FCommandBufferCopy { - if (IndexBuffer.HasValue) - { - IndexBuffer.Value.Buffer.UnsafeChangeState(FResourceState.IndexBuffer); - } - foreach (var buffer in VertexBuffers) + Base = { Type = FCommandType.BufferCopy }, + RangeIndex = (uint)m_buffer_copy_ranges.Count, + Dst = { Buffer = AddResource(Dst) }, + DstType = FBufferRefType.Buffer, + Src = { Upload = Loc }, + SrcType = FBufferRefType.Upload, + }; + m_buffer_copy_ranges.Add( + new() { - buffer.Buffer.UnsafeChangeState(FResourceState.VertexBuffer); + Size = Size, + DstOffset = DstOffset, + SrcOffset = Loc.Offset, } - } + ); + m_commands.Add(new() { BufferCopy = cmd }); + if ((Flags & CommandFlags.DontTransition) == 0) + Dst.UnsafeChangeState(FResourceState.CopyDst); } #endregion - #region Draw + #region Render - public void Draw( - uint VertexCount, uint InstanceCount = 1, - uint FirstVertex = 0, uint FirstInstance = 0, - ShaderBinding? Binding = null, - CommandFlags Flags = CommandFlags.None - ) => Draw(null, false, VertexCount, InstanceCount, FirstVertex, FirstInstance, 0, Binding, Flags); + public RenderScope Render( + ReadOnlySpan Rtvs, RenderInfo.DsvInfo? Dsv = null, + bool AutoViewportScissor = true, + string? Name = null, ReadOnlySpan Name8 = default + ) => Render(new(Rtvs, Dsv), AutoViewportScissor, Name, Name8); + public RenderScope Render( + RenderInfo.DsvInfo Dsv, ReadOnlySpan Rtvs = default, + bool AutoViewportScissor = true, + string? Name = null, ReadOnlySpan Name8 = default + ) => Render(new(Rtvs, Dsv), AutoViewportScissor, Name, Name8); + public RenderScope Render( + in RenderInfo Info, + bool AutoViewportScissor = true, + string? Name = null, ReadOnlySpan Name8 = default + ) + { + #region Check Args - public void Draw( - ShaderPipeline? Pipeline, - uint VertexCount, uint InstanceCount = 1, - uint FirstVertex = 0, uint FirstInstance = 0, - ShaderBinding? Binding = null, - CommandFlags Flags = CommandFlags.None - ) => Draw(Pipeline, false, VertexCount, InstanceCount, FirstVertex, FirstInstance, 0, Binding, Flags); + if (Info.Dsv == null && Info.Rtvs.Length == 0) throw new ArgumentException("No any rtv or dsv provided"); + if (Info.Rtvs.Length > 8) throw new ArgumentException("Too many rtvs provided, it can't be more than 8"); - public void DrawIndexed( - uint IndexCount, uint InstanceCount = 1, - uint FirstIndex = 0, uint FirstInstance = 0, uint VertexOffset = 0, - ShaderBinding? Binding = null, - CommandFlags Flags = CommandFlags.None - ) => Draw(null, true, IndexCount, InstanceCount, FirstIndex, FirstInstance, VertexOffset, Binding, Flags); + #endregion + + #region Cmd + + var cmd = new FCommandRender + { + Base = { Type = FCommandType.Render }, + InfoIndex = (uint)m_render_infos.Count, + CommandStartIndex = (uint)m_render_commands.Count, + }; + + #endregion + + #region Init + + var has_dsv = Info.Dsv.HasValue; + var dsv = Info.Dsv ?? default; + + #endregion + + #region Info + + FRenderInfo info = new() + { + Dsv = has_dsv ? AddResource(dsv.View!) : default, + NumRtv = (uint)Info.Rtvs.Length, + Depth = has_dsv && dsv.DepthLoad is { IsClear: true, Clear: var cd } ? cd : 1, + Stencil = has_dsv && dsv.StencilLoad is { IsClear: true, Clear: var cs } ? (byte)cs : (byte)0, + }; + + #endregion + + #region DsvLoadOp + + info.DsvLoadOp[0] = has_dsv + ? dsv.DepthLoad.Tag switch + { + LoadOp.Tags.Load => FLoadOp.Load, + LoadOp.Tags.Clear => FLoadOp.Clear, + LoadOp.Tags.Discard => FLoadOp.Discard, + LoadOp.Tags.NoAccess => FLoadOp.NoAccess, + _ => throw new ArgumentOutOfRangeException() + } + : FLoadOp.NoAccess; + info.DsvLoadOp[1] = has_dsv + ? dsv.StencilLoad.Tag switch + { + LoadOp.Tags.Load => FLoadOp.Load, + LoadOp.Tags.Clear => FLoadOp.Clear, + LoadOp.Tags.Discard => FLoadOp.Discard, + LoadOp.Tags.NoAccess => FLoadOp.NoAccess, + _ => throw new ArgumentOutOfRangeException() + } + : FLoadOp.NoAccess; + + #endregion + + #region DsvStoreOp + + info.DsvStoreOp[0] = has_dsv + ? dsv.DepthStore.Tag switch + { + StoreOp.Tags.Store => FStoreOp.Store, + StoreOp.Tags.Discard => FStoreOp.Discard, + StoreOp.Tags.NoAccess => FStoreOp.NoAccess, + _ => throw new ArgumentOutOfRangeException() + } + : FStoreOp.NoAccess; + + info.DsvStoreOp[1] = has_dsv + ? dsv.StencilStore.Tag switch + { + StoreOp.Tags.Store => FStoreOp.Store, + StoreOp.Tags.Discard => FStoreOp.Discard, + StoreOp.Tags.NoAccess => FStoreOp.NoAccess, + _ => throw new ArgumentOutOfRangeException() + } + : FStoreOp.NoAccess; + + #endregion + + #region Rtv + + var rt_size = Info.Dsv?.View.Size ?? Info.Rtvs[0].View.Size; + for (var i = 0; i < Info.Rtvs.Length; i++) + { + ref readonly var rtv = ref Info.Rtvs[i]; + if (!rtv.View.Size.Equals(rt_size)) + throw new ArgumentException("RenderTargets And DepthStencil must be the same size"); + info.Rtv[i] = AddResource(rtv.View); + info.ResolveInfoIndex[i] = uint.MaxValue; // todo + if (rtv.Load is { IsClear: true, Clear: var cc }) + Unsafe.As(ref info.Color[i * 4]) = cc; + info.RtvLoadOp[i] = rtv.Load.Tag switch + { + LoadOp.Tags.Load => FLoadOp.Load, + LoadOp.Tags.Clear => FLoadOp.Clear, + LoadOp.Tags.Discard => FLoadOp.Discard, + LoadOp.Tags.NoAccess => FLoadOp.NoAccess, + _ => throw new ArgumentOutOfRangeException() + }; + info.RtvStoreOp[i] = rtv.Store.Tag switch + { + StoreOp.Tags.Store => FStoreOp.Store, + StoreOp.Tags.Discard => FStoreOp.Discard, + StoreOp.Tags.NoAccess => FStoreOp.NoAccess, + _ => throw new ArgumentOutOfRangeException() + }; + } + + #endregion + + #region EndInfo + + m_render_infos.Add(info); + + #endregion + + #region DebugScope + + var debug_scope = false; + if (Name != null) + { + debug_scope = true; + Scope(Name); + } + else if (Name8.Length > 0) + { + debug_scope = true; + Scope(Name8); + } + + #endregion + + #region Add + + m_commands.Add(new() { Render = cmd }); + + #endregion + + #region Scope + + RenderScope scope = new(this, m_render_commands, debug_scope); + + #endregion + + #region AutoViewportScissor + + if (AutoViewportScissor) + { + scope.SetViewportScissor( + [new UViewPort { Width = rt_size.x, Height = rt_size.y }], + [new URect { Right = rt_size.x, Bottom = rt_size.y }] + ); + } + + #endregion + + return scope; + } + + #endregion + + #region Compute + + public ComputeScope Compute(string? Name = null, ReadOnlySpan Name8 = default) + { + var debug_scope = false; + if (Name != null) + { + debug_scope = true; + Scope(Name); + } + else if (Name8.Length > 0) + { + debug_scope = true; + Scope(Name8); + } + var cmd = new FCommandCompute + { + Base = { Type = FCommandType.Compute }, + CommandStartIndex = (uint)m_compute_commands.Count, + }; + m_commands.Add(new() { Compute = cmd }); + return new(this, m_compute_commands, debug_scope); + } + + #endregion + + #endregion +} + +#region DebugScope + +public readonly struct DebugScope(CommandList self) : IDisposable +{ + public void Dispose() + { + var cmd = new FCommandEndScope + { + Base = { Type = FCommandType.EndScope }, + }; + self.m_commands.Add(new() { EndScope = cmd }); + } +} + +public readonly struct RenderDebugScope(CommandList self) : IDisposable +{ + public void Dispose() + { + var cmd = new FCommandEndScope + { + Base = { Type = FCommandType.EndScope }, + }; + self.m_render_commands.Add(new() { EndScope = cmd }); + } +} + +public readonly struct ComputeDebugScope(CommandList self) : IDisposable +{ + public void Dispose() + { + var cmd = new FCommandEndScope + { + Base = { Type = FCommandType.EndScope }, + }; + self.m_compute_commands.Add(new() { EndScope = cmd }); + } +} + +#endregion + +#region RenderInfo + +[Union] +public partial struct LoadOp +{ + [UnionTemplate] + private interface Template + { + void Load(); + void Discard(); + void NoAccess(); + } + + public static readonly LoadOp Load = MakeLoad(); + public static LoadOp Clear(T Clear) => LoadOp.MakeClear(Clear); + public static readonly LoadOp Discard = MakeDiscard(); + public static readonly LoadOp NoAccess = MakeNoAccess(); +} + +[Union] +public partial struct LoadOp +{ + [UnionTemplate] + private interface Template + { + void Load(); + T Clear(); + void Discard(); + void NoAccess(); + } + + public static readonly LoadOp Load = MakeLoad(); + public static implicit operator LoadOp(T Clear) => MakeClear(Clear); + public static readonly LoadOp Discard = MakeDiscard(); + public static readonly LoadOp NoAccess = MakeNoAccess(); + + public static implicit operator LoadOp(LoadOp op) => op.Tag switch + { + LoadOp.Tags.Load => Load, + LoadOp.Tags.Discard => Discard, + LoadOp.Tags.NoAccess => NoAccess, + _ => throw new ArgumentOutOfRangeException() + }; +} + +[Union] +public partial struct StoreOp +{ + [UnionTemplate] + private interface Template + { + void Store(); + void Discard(); + void NoAccess(); + } + + public static readonly StoreOp Store = MakeStore(); + public static readonly StoreOp Discard = MakeDiscard(); + public static readonly StoreOp NoAccess = MakeNoAccess(); +} + +public ref struct RenderInfo(ReadOnlySpan Rtvs, RenderInfo.DsvInfo? Dsv = null) +{ + public DsvInfo? Dsv = Dsv; + public ReadOnlySpan Rtvs = Rtvs; + + public RenderInfo() : this([]) { } + public RenderInfo(DsvInfo Dsv, ReadOnlySpan Rtvs = default) : this(Rtvs, Dsv) { } + + public struct DsvInfo( + IDsvRes View, + LoadOp DepthLoad, + LoadOp StencilLoad, + StoreOp DepthStore, + StoreOp StencilStore + ) + { + public IDsvRes View = View; + public LoadOp DepthLoad = DepthLoad; + public LoadOp StencilLoad = StencilLoad; + public StoreOp DepthStore = DepthStore; + public StoreOp StencilStore = StencilStore; + + public DsvInfo(IDsvRes View) : this(View, LoadOp.Load, LoadOp.Load, StoreOp.Store, StoreOp.Store) { } + public DsvInfo(IDsvRes View, LoadOp DepthLoad, LoadOp StencilLoad) + : this(View, DepthLoad, StencilLoad, StoreOp.Store, StoreOp.Store) { } + public DsvInfo(IDsvRes View, LoadOp DepthLoad) + : this(View, DepthLoad, LoadOp.Load, StoreOp.Store, StoreOp.Store) { } + } + + public struct RtvInfo(IRtvRes View, LoadOp Load, StoreOp Store) + { + public IRtvRes View = View; + public LoadOp Load = Load; + public StoreOp Store = Store; + + public RtvInfo(IRtvRes View) : this(View, LoadOp.Load, StoreOp.Store) { } + + public RtvInfo(IRtvRes View, LoadOp Load) : this(View, Load, StoreOp.Store) { } + } +} + +#endregion + +#region RenderScope + +public unsafe struct RenderScope( + CommandList self, + List m_commands, + bool debug_scope +) : IDisposable +{ + #region Fields + + private ShaderPipeline? m_current_pipeline; + private ShaderBinding? m_current_binding; + + #endregion + + #region Dispose + + public void Dispose() + { + self.m_render_commands.Add(new() { Type = FCommandType.End }); + if (debug_scope) new DebugScope(self).Dispose(); + } + + #endregion + + #region Debug + + #region Label + + public void Label(string Label) + { + var cmd = new FCommandLabel + { + Base = { Type = FCommandType.Label }, + StringIndex = self.AddString(Label), + StringLength = (uint)Label.Length, + StrType = FStrType.Str16, + }; + m_commands.Add(new() { Label = cmd }); + } + + public void Label(ReadOnlySpan Label) + { + var cmd = new FCommandLabel + { + Base = { Type = FCommandType.EndScope }, + StringIndex = self.AddString(Label), + StringLength = (uint)Label.Length, + StrType = FStrType.Str8, + }; + m_commands.Add(new() { Label = cmd }); + } + + #endregion + + #region Scope + + public RenderDebugScope Scope(string Name) + { + var cmd = new FCommandLabel + { + Base = { Type = FCommandType.EndScope }, + StringIndex = self.AddString(Name), + StringLength = (uint)Name.Length, + StrType = FStrType.Str16, + }; + m_commands.Add(new() { Label = cmd }); + return new(self); + } + + public RenderDebugScope Scope(ReadOnlySpan Name) + { + var cmd = new FCommandLabel + { + Base = { Type = FCommandType.EndScope }, + StringIndex = self.AddString(Name), + StringLength = (uint)Name.Length, + StrType = FStrType.Str8, + }; + m_commands.Add(new() { Label = cmd }); + return new(self); + } + + #endregion + + #endregion + + #region SetPipeline + + public void SetPipeline(ShaderPipeline Pipeline) + { + if (m_current_pipeline == Pipeline) return; + self.AddObject(m_current_pipeline = Pipeline); + if (m_current_binding != null) + { + if (Pipeline.Shader.Layout != m_current_binding.Layout) + m_current_binding = null; + } + var cmd = new FCommandSetPipeline + { + Base = { Type = FCommandType.SetPipeline }, + Pipeline = Pipeline.m_ptr, + }; + m_commands.Add(new() { SetPipeline = cmd }); + } + + #endregion + + #region SetBinding + + public void SetBinding(ShaderBinding Binding) + { + if (m_current_binding == Binding) return; + if (m_current_pipeline != null) + { + if (m_current_pipeline.Shader.Layout != Binding.Layout) + throw new ArgumentException("This binding is incompatible with the current pipeline"); + } + self.AddObject(m_current_binding = Binding); + var cmd = new FCommandSetBinding + { + Base = { Type = FCommandType.SetBinding }, + Binding = Binding.m_ptr, + }; + m_commands.Add(new() { SetBinding = cmd }); + } + + #endregion + + #region SetViewportScissor + + public void SetViewportScissor( + ReadOnlySpan Viewports, + ReadOnlySpan Scissors + ) + { + var cmd = new FCommandSetViewportScissor + { + Base = { Type = FCommandType.SetViewportScissor }, + ViewportCount = (uint)Viewports.Length, + ScissorRectCount = (uint)Scissors.Length, + }; + if (Viewports.Length > 0) + { + cmd.ViewportIndex = (uint)self.m_viewports.Count; + self.m_viewports.AddRange(MemoryMarshal.Cast(Viewports)); + } + if (Scissors.Length > 0) + { + cmd.ScissorRectIndex = (uint)self.m_rects.Count; + self.m_rects.AddRange(MemoryMarshal.Cast(Scissors)); + } + m_commands.Add(new() { SetViewportScissor = cmd }); + } + + #endregion + + #region SetMeshBuffers + + public void SetMeshBuffers( + MeshLayout MeshLayout, + uint VertexStartSlot, + ReadOnlySpan VertexBuffers + ) => SetMeshBuffers(MeshLayout, FGraphicsFormat.Unknown, null, VertexStartSlot, VertexBuffers); + + public void SetMeshBuffers( + MeshLayout MeshLayout, + ReadOnlySpan VertexBuffers + ) => SetMeshBuffers(MeshLayout, FGraphicsFormat.Unknown, null, 0, VertexBuffers); + + public void SetMeshBuffers( + MeshLayout MeshLayout, + FGraphicsFormat IndexFormat, + BufferRange? IndexBuffer, + uint VertexStartSlot, + ReadOnlySpan VertexBuffers + ) + { + self.AddObject(MeshLayout); + var cmd = new FCommandSetMeshBuffers + { + Base = { Type = FCommandType.SetMeshBuffers }, + IndexFormat = IndexFormat, + VertexStartSlot = VertexStartSlot, + PayloadIndex = (uint)self.m_mesh_buffers.Count, + }; + var buf = new FMeshBuffers + { + MeshLayout = MeshLayout.m_ptr, + IndexBuffer = IndexBuffer is { } index_buffer + ? new() + { + Buffer = self.AddResource(index_buffer.Buffer), + Offset = index_buffer.Offset, + Size = index_buffer.Size == uint.MaxValue ? (uint)index_buffer.Buffer.LongSize : index_buffer.Size, + } + : new() + { + Buffer = new(uint.MaxValue), + }, + VertexBufferCount = (uint)VertexBuffers.Length, + }; + if (VertexBuffers.Length > 0) + { + var index = self.m_vertex_buffer_ranges.Count; + buf.VertexBuffersIndex = (uint)index; + CollectionsMarshal.SetCount( + self.m_vertex_buffer_ranges, self.m_vertex_buffer_ranges.Count + VertexBuffers.Length + ); + var vbs = CollectionsMarshal.AsSpan(self.m_vertex_buffer_ranges).Slice(index, VertexBuffers.Length); + for (var i = 0; i < VertexBuffers.Length; i++) + { + var buffer = VertexBuffers[i]; + vbs[i] = new() + { + Base = + { + Buffer = self.AddResource(buffer.Buffer), + Offset = buffer.Offset, + Size = buffer.Size == uint.MaxValue ? (uint)buffer.Buffer.LongSize : buffer.Size, + }, + Index = buffer.Index, + }; + } + } + self.m_mesh_buffers.Add(buf); + m_commands.Add(new() { SetMeshBuffers = cmd }); + } + + #endregion + + #region Draw + + public void Draw( + uint VertexCount, uint InstanceCount = 1, + uint FirstVertex = 0, uint FirstInstance = 0, + ShaderBinding? Binding = null + ) => Draw(null, false, VertexCount, InstanceCount, FirstVertex, FirstInstance, 0, Binding); + + public void Draw( + ShaderPipeline? Pipeline, + uint VertexCount, uint InstanceCount = 1, + uint FirstVertex = 0, uint FirstInstance = 0, + ShaderBinding? Binding = null + ) => Draw(Pipeline, false, VertexCount, InstanceCount, FirstVertex, FirstInstance, 0, Binding); + + public void DrawIndexed( + uint IndexCount, uint InstanceCount = 1, + uint FirstIndex = 0, uint FirstInstance = 0, uint VertexOffset = 0, + ShaderBinding? Binding = null + ) => Draw(null, true, IndexCount, InstanceCount, FirstIndex, FirstInstance, VertexOffset, Binding); public void DrawIndexed( ShaderPipeline? Pipeline, uint IndexCount, uint InstanceCount = 1, uint FirstIndex = 0, uint FirstInstance = 0, uint VertexOffset = 0, - ShaderBinding? Binding = null, - CommandFlags Flags = CommandFlags.None - ) => Draw(Pipeline, true, IndexCount, InstanceCount, FirstIndex, FirstInstance, VertexOffset, Binding, Flags); + ShaderBinding? Binding = null + ) => Draw(Pipeline, true, IndexCount, InstanceCount, FirstIndex, FirstInstance, VertexOffset, Binding); public void Draw( ShaderPipeline? Pipeline, bool Indexed, uint VertexOrIndexCount, uint InstanceCount = 1, uint FirstVertexOrIndex = 0, uint FirstInstance = 0, uint VertexOffset = 0, - ShaderBinding? Binding = null, - CommandFlags Flags = CommandFlags.None + ShaderBinding? Binding = null ) { if (Pipeline != null) { - m_current_pipeline = Pipeline; if (!Pipeline.Shader.Stages.HasFlags(ShaderStageFlags.Vertex)) - throw new ArgumentException("Non Vertex pipelines cannot use Draw"); - AddObject(Pipeline); + throw new ArgumentException("Only Vertex shaders can use Draw"); + SetPipeline(Pipeline); } else { if (m_current_pipeline == null) throw new InvalidOperationException("Pipeline is not set"); if (!m_current_pipeline.Shader.Stages.HasFlags(ShaderStageFlags.Vertex)) - throw new ArgumentException("Non Vertex pipelines cannot use Draw"); - } - if (Binding != null) - { - if (m_current_pipeline.Shader.Layout != Binding.Layout) - throw new ArgumentException( - "The layout of the shader bindings is incompatible with the layout of the shader pipeline" - ); - AddObject(m_current_binding = Binding); + throw new ArgumentException("Only Vertex shaders can use Draw"); } + if (Binding != null) SetBinding(Binding); var cmd = new FCommandDraw { - Pipeline = Pipeline == null ? null : Pipeline.m_ptr, + Base = { Type = FCommandType.Draw }, VertexOrIndexCount = VertexOrIndexCount, InstanceCount = InstanceCount, FirstVertexOrIndex = FirstVertexOrIndex, @@ -582,215 +1178,250 @@ public void Draw( VertexOffset = VertexOffset, Indexed = Indexed, }; - m_commands.Add( - new() - { - Type = FCommandType.Draw, - Flags = (FCommandFlags)Flags, - Draw = cmd, - } - ); + m_commands.Add(new() { Draw = cmd }); } #endregion - #region Dispatch - - public void Dispatch( - uint GroupCountX = 1, uint GroupCountY = 1, uint GroupCountZ = 1, - CommandFlags Flags = CommandFlags.None - ) => Dispatch(null, DispatchType.Compute); + #region DispatchMesh public void DispatchMesh( - uint GroupCountX = 1, uint GroupCountY = 1, uint GroupCountZ = 1, - CommandFlags Flags = CommandFlags.None - ) => Dispatch(null, DispatchType.Mesh); - - public void Dispatch( - ShaderPipeline Pipeline, - uint GroupCountX = 1, uint GroupCountY = 1, uint GroupCountZ = 1, - CommandFlags Flags = CommandFlags.None - ) => Dispatch(Pipeline, DispatchType.Auto); + uint GroupCountX = 1, uint GroupCountY = 1, uint GroupCountZ = 1 + ) => DispatchMesh(null, GroupCountX, GroupCountY, GroupCountZ); - public void Dispatch( - ShaderPipeline? Pipeline, DispatchType Type, - uint GroupCountX = 1, uint GroupCountY = 1, uint GroupCountZ = 1, - CommandFlags Flags = CommandFlags.None + public void DispatchMesh( + ShaderPipeline? Pipeline, + uint GroupCountX = 1, uint GroupCountY = 1, uint GroupCountZ = 1 ) { if (Pipeline != null) { - m_current_pipeline = Pipeline; - if (!Pipeline.Shader.Stages.HasAnyFlags(ShaderStageFlags.Compute | ShaderStageFlags.Mesh)) - throw new ArgumentException("Non Mesh and Compute pipelines cannot use Dispatch"); - AddObject(Pipeline); - if (Type == DispatchType.Auto) - { - if (Pipeline.Shader.Stages.HasFlags(ShaderStageFlags.Compute)) Type = DispatchType.Compute; - else if (Pipeline.Shader.Stages.HasFlags(ShaderStageFlags.Mesh)) Type = DispatchType.Mesh; - else throw new UnreachableException(); - } + if (!Pipeline.Shader.Stages.HasFlags(ShaderStageFlags.Mesh)) + throw new ArgumentException("Only Mesh shaders can use DispatchMesh"); + SetPipeline(Pipeline); } else { if (m_current_pipeline == null) throw new InvalidOperationException("Pipeline is not set"); - if (!m_current_pipeline.Shader.Stages.HasAnyFlags(ShaderStageFlags.Compute | ShaderStageFlags.Mesh)) - throw new ArgumentException("Non Mesh and Compute pipelines cannot use Dispatch"); - if (Type == DispatchType.Auto) - { - if (m_current_pipeline.Shader.Stages.HasFlags(ShaderStageFlags.Compute)) Type = DispatchType.Compute; - else if (m_current_pipeline.Shader.Stages.HasFlags(ShaderStageFlags.Mesh)) Type = DispatchType.Mesh; - else throw new UnreachableException(); - } + if (!m_current_pipeline.Shader.Stages.HasFlags(ShaderStageFlags.Mesh)) + throw new ArgumentException("Only Mesh shaders can use DispatchMesh"); } var cmd = new FCommandDispatch { - Pipeline = Pipeline == null ? null : Pipeline.m_ptr, + Base = { Type = FCommandType.Draw }, GroupCountX = GroupCountX, GroupCountY = GroupCountY, GroupCountZ = GroupCountZ, - Type = Type switch - { - DispatchType.Auto => throw new UnreachableException(), - DispatchType.Compute => FDispatchType.Compute, - DispatchType.Mesh => FDispatchType.Mesh, - _ => throw new ArgumentOutOfRangeException(nameof(Type), Type, null) - }, + Type = FDispatchType.Mesh, }; - m_commands.Add( - new() - { - Type = FCommandType.Dispatch, - Flags = (FCommandFlags)Flags, - Dispatch = cmd, - } - ); + m_commands.Add(new() { Dispatch = cmd }); } #endregion +} - #region BufferCopy +#endregion - public void Copy( - GpuBuffer Dst, - GpuBuffer Src, - ulong DstOffset = 0, - ulong SrcOffset = 0, - ulong Size = ulong.MaxValue, - CommandFlags Flags = CommandFlags.None - ) +#region ComputeScope + +public unsafe struct ComputeScope( + CommandList self, + List m_commands, + bool debug_scope +) : IDisposable +{ + #region Fields + + private ShaderPipeline? m_current_pipeline; + private ShaderBinding? m_current_binding; + + #endregion + + #region Dispose + + public void Dispose() { - if (Size != ulong.MaxValue) + self.m_compute_commands.Add(new() { Type = FCommandType.End }); + if (debug_scope) new DebugScope(self).Dispose(); + } + + #endregion + + #region Debug + + #region Label + + public void Label(string Label) + { + var cmd = new FCommandLabel { - if (DstOffset + Size > Dst.Size) throw new ArgumentException("The copy range exceeds the buffer range"); - if (SrcOffset + Size > Src.Size) throw new ArgumentException("The copy range exceeds the buffer range"); - } - else if (Dst == Src || Dst.Size != Src.Size) Size = Math.Min(Dst.Size, Src.Size); - var dst = AddResource(Dst); - var src = AddResource(Src); - var cmd = new FCommandBufferCopy + Base = { Type = FCommandType.Label }, + StringIndex = self.AddString(Label), + StringLength = (uint)Label.Length, + StrType = FStrType.Str16, + }; + m_commands.Add(new() { Label = cmd }); + } + + public void Label(ReadOnlySpan Label) + { + var cmd = new FCommandLabel { - Size = Size, - DstOffset = DstOffset, - SrcOffset = SrcOffset, - DstType = FBufferRefType.Buffer, - SrcType = FBufferRefType.Buffer, + Base = { Type = FCommandType.EndScope }, + StringIndex = self.AddString(Label), + StringLength = (uint)Label.Length, + StrType = FStrType.Str8, }; - cmd.Dst.Buffer = new(dst); - cmd.Src.Buffer = new(src); - m_commands.Add( - new() - { - Type = FCommandType.BufferCopy, - Flags = (FCommandFlags)Flags, - BufferCopy = cmd, - } - ); - if ((Flags & CommandFlags.DontTransition) == 0) + m_commands.Add(new() { Label = cmd }); + } + + #endregion + + #region Scope + + public ComputeDebugScope Scope(string Name) + { + var cmd = new FCommandLabel { - Dst.UnsafeChangeState(FResourceState.CopyDst); - Src.UnsafeChangeState(FResourceState.CopySrc); - } + Base = { Type = FCommandType.EndScope }, + StringIndex = self.AddString(Name), + StringLength = (uint)Name.Length, + StrType = FStrType.Str16, + }; + m_commands.Add(new() { Label = cmd }); + return new(self); + } + + public ComputeDebugScope Scope(ReadOnlySpan Name) + { + var cmd = new FCommandLabel + { + Base = { Type = FCommandType.EndScope }, + StringIndex = self.AddString(Name), + StringLength = (uint)Name.Length, + StrType = FStrType.Str8, + }; + m_commands.Add(new() { Label = cmd }); + return new(self); } #endregion - #region BufferUpload + #endregion - public void Upload( - GpuBuffer Dst, - ReadOnlySpan Data, - ulong DstOffset = 0, - CommandFlags Flags = CommandFlags.None - ) where T : unmanaged => Upload(Dst, MemoryMarshal.AsBytes(Data), DstOffset, Flags); + #region SetPipeline - public void Upload( - GpuBuffer Dst, - ReadOnlySpan Data, - ulong DstOffset = 0, - CommandFlags Flags = CommandFlags.None - ) + public void SetPipeline(ShaderPipeline Pipeline) { - if (Data.Length == 0) return; - var Size = Math.Min(Dst.Size, (uint)Data.Length); - var dst = AddResource(Dst); - var src = m_queue.WriteToUpload(Data); - var cmd = new FCommandBufferCopy + if (m_current_pipeline == Pipeline) return; + self.AddObject(m_current_pipeline = Pipeline); + if (m_current_binding != null) { - Size = Size, - DstOffset = DstOffset, - SrcOffset = src.Offset, - DstType = FBufferRefType.Buffer, - SrcType = FBufferRefType.Upload, + if (Pipeline.Shader.Layout != m_current_binding.Layout) + m_current_binding = null; + } + var cmd = new FCommandSetPipeline + { + Base = { Type = FCommandType.SetPipeline }, + Pipeline = Pipeline.m_ptr, }; - cmd.Dst.Buffer = new(dst); - cmd.Src.Upload = new(src); - m_commands.Add( - new() - { - Type = FCommandType.BufferCopy, - Flags = (FCommandFlags)Flags, - BufferCopy = cmd, - } - ); - if ((Flags & CommandFlags.DontTransition) == 0) - Dst.UnsafeChangeState(FResourceState.CopyDst); + m_commands.Add(new() { SetPipeline = cmd }); } - public void Upload( - GpuBuffer Dst, - UploadLoc Loc, - ulong DstOffset = 0, - CommandFlags Flags = CommandFlags.None - ) + #endregion + + #region SetBinding + + public void SetBinding(ShaderBinding Binding) { - if (Loc.SubmitId != m_queue.SubmitId) - throw new ArgumentException("An attempt was made to use an expired upload location"); - var Size = Math.Min(Dst.Size, Loc.Size); - var dst = AddResource(Dst); - var cmd = new FCommandBufferCopy + if (m_current_binding == Binding) return; + if (m_current_pipeline != null) { - Size = Size, - DstOffset = DstOffset, - SrcOffset = Loc.Offset, - DstType = FBufferRefType.Buffer, - SrcType = FBufferRefType.Upload, + if (m_current_pipeline.Shader.Layout != Binding.Layout) + throw new ArgumentException("This binding is incompatible with the current pipeline"); + } + self.AddObject(m_current_binding = Binding); + var cmd = new FCommandSetBinding + { + Base = { Type = FCommandType.SetBinding }, + Binding = Binding.m_ptr, }; - cmd.Dst.Buffer = new(dst); - cmd.Src.Upload = new(Loc); - m_commands.Add( - new() - { - Type = FCommandType.BufferCopy, - Flags = (FCommandFlags)Flags, - BufferCopy = cmd, - } - ); - if ((Flags & CommandFlags.DontTransition) == 0) - Dst.UnsafeChangeState(FResourceState.CopyDst); + m_commands.Add(new() { SetBinding = cmd }); } #endregion + #region Dispatch + + public void Dispatch( + uint GroupCountX = 1, uint GroupCountY = 1, uint GroupCountZ = 1 + ) => Dispatch(null, DispatchType.Compute, GroupCountX, GroupCountY, GroupCountZ); + + public void DispatchMesh( + uint GroupCountX = 1, uint GroupCountY = 1, uint GroupCountZ = 1 + ) => Dispatch(null, DispatchType.Mesh, GroupCountX, GroupCountY, GroupCountZ); + + public void Dispatch( + ShaderPipeline Pipeline, + uint GroupCountX = 1, uint GroupCountY = 1, uint GroupCountZ = 1 + ) => Dispatch(Pipeline, DispatchType.Auto, GroupCountX, GroupCountY, GroupCountZ); + + public void DispatchMesh( + ShaderPipeline Pipeline, + uint GroupCountX = 1, uint GroupCountY = 1, uint GroupCountZ = 1 + ) => Dispatch(Pipeline, DispatchType.Mesh, GroupCountX, GroupCountY, GroupCountZ); + + public void Dispatch( + ShaderPipeline? Pipeline, DispatchType Type, + uint GroupCountX = 1, uint GroupCountY = 1, uint GroupCountZ = 1 + ) + { + if (Pipeline != null) + { + if (!Pipeline.Shader.Stages.HasAnyFlags(ShaderStageFlags.Compute | ShaderStageFlags.Mesh)) + throw new ArgumentException("Only Mesh and Compute shaders can use Dispatch/DispatchMesh"); + SetPipeline(Pipeline); + } + else + { + if (m_current_pipeline == null) throw new InvalidOperationException("Pipeline is not set"); + if (!m_current_pipeline.Shader.Stages.HasAnyFlags(ShaderStageFlags.Compute | ShaderStageFlags.Mesh)) + throw new ArgumentException("Only Mesh and Compute shaders can use Dispatch/DispatchMesh"); + } + if (Type == DispatchType.Auto) + { + if (m_current_pipeline!.Shader.Stages.HasFlags(ShaderStageFlags.Compute)) Type = DispatchType.Compute; + else if (m_current_pipeline.Shader.Stages.HasFlags(ShaderStageFlags.Mesh)) Type = DispatchType.Mesh; + else throw new UnreachableException(); + } + else if (Type == DispatchType.Mesh) + { + if (!m_current_pipeline!.Shader.Stages.HasFlags(ShaderStageFlags.Mesh)) + throw new ArgumentException("Only Mesh shaders can use DispatchMesh"); + } + else if (Type == DispatchType.Compute) + { + if (!m_current_pipeline!.Shader.Stages.HasFlags(ShaderStageFlags.Compute)) + throw new ArgumentException("Only Compute shaders can use Dispatch"); + } + var cmd = new FCommandDispatch + { + Base = { Type = FCommandType.SetBinding }, + GroupCountX = GroupCountX, + GroupCountY = GroupCountY, + GroupCountZ = GroupCountZ, + Type = Type switch + { + DispatchType.Auto => throw new UnreachableException(), + DispatchType.Compute => FDispatchType.Compute, + DispatchType.Mesh => FDispatchType.Mesh, + _ => throw new ArgumentOutOfRangeException(nameof(Type), Type, null) + }, + }; + m_commands.Add(new() { Dispatch = cmd }); + } + #endregion } + +#endregion diff --git a/Coplt.Graphics.Core/Core/GpuExecutor.cs b/Coplt.Graphics.Core/Core/GpuExecutor.cs new file mode 100644 index 0000000..3a8d037 --- /dev/null +++ b/Coplt.Graphics.Core/Core/GpuExecutor.cs @@ -0,0 +1,92 @@ +using Coplt.Dropping; +using Coplt.Graphics.Native; + +namespace Coplt.Graphics.Core; + +[Dropping(Unmanaged = true)] +public abstract unsafe partial class GpuExecutor +{ + #region Fields + + internal FGpuExecutor* m_ptr; + internal string? m_name; + internal readonly GpuQueue m_queue; + + #endregion + + #region Props + + public FGpuExecutor* Ptr => m_ptr; + public GpuDevice Device => m_queue.m_device; + public GpuQueue Queue => m_queue; + + #endregion + + #region Ctor + + internal GpuExecutor(FGpuExecutor* ptr, string? name, GpuQueue queue) + { + m_ptr = ptr; + m_name = name; + m_queue = queue; + } + + #endregion + + #region Drop + + [Drop] + private void Drop() + { + if (ExchangeUtils.ExchangePtr(ref m_ptr, null, out var ptr) is null) return; + ptr->Release(); + } + + #endregion + + #region SetName + + public void SetName(string name) + { + m_name = name; + fixed (char* ptr = name) + { + FStr8or16 str = new(ptr, name.Length); + m_ptr->SetName(&str).TryThrow(); + } + } + + public void SetName(ReadOnlySpan name) + { + m_name = null; + fixed (byte* ptr = name) + { + FStr8or16 str = new(ptr, name.Length); + m_ptr->SetName(&str).TryThrow(); + } + } + + #endregion + + #region ToString + + public override string ToString() => + m_name is null + ? $"{nameof(GpuExecutor)}(0x{(nuint)m_ptr:X})" + : $"{nameof(GpuExecutor)}(0x{(nuint)m_ptr:X} \"{m_name}\")"; + + #endregion + + #region Wait + + /// + /// 等待可重用 + /// + public void Wait() + { + using var _ = Queue.m_lock.EnterScope(); + m_ptr->Wait().TryThrow(); + } + + #endregion +} diff --git a/Coplt.Graphics.Core/Core/GpuOutput.cs b/Coplt.Graphics.Core/Core/GpuOutput.cs index 692f620..5e21bd5 100644 --- a/Coplt.Graphics.Core/Core/GpuOutput.cs +++ b/Coplt.Graphics.Core/Core/GpuOutput.cs @@ -64,32 +64,27 @@ public record struct GpuOutputOptions() #endregion [Dropping(Unmanaged = true)] -public sealed unsafe partial class GpuOutput : IRtvRes, ISrvRes +public sealed unsafe partial class GpuOutput : GpuExecutor, IRtvRes, ISrvRes { #region Fields - internal FGpuOutput* m_ptr; - internal string? m_name; - internal readonly GpuQueue m_queue; + internal new FGpuOutput* m_ptr; #endregion #region Props - public FGpuOutput* Ptr => m_ptr; + public new FGpuOutput* Ptr => m_ptr; public uint3 Size => new(m_ptr->m_width, m_ptr->m_height, 1); - public GpuQueue Queue => m_queue; #endregion #region Ctor - internal GpuOutput(GpuQueue queue, FGpuOutput* ptr, string? name) + internal GpuOutput(FGpuOutput* ptr, string? name, GpuQueue queue) : base((FGpuExecutor*)ptr, name, queue) { - m_queue = queue; m_ptr = ptr; - m_name = name; } #endregion @@ -99,32 +94,7 @@ internal GpuOutput(GpuQueue queue, FGpuOutput* ptr, string? name) [Drop] private void Drop() { - if (ExchangeUtils.ExchangePtr(ref m_ptr, null, out var ptr) is null) return; - ptr->Release(); - } - - #endregion - - #region SetName - - public void SetName(string name) - { - m_name = name; - fixed (char* ptr = name) - { - FStr8or16 str = new(ptr, name.Length); - m_ptr->SetName(&str).TryThrow(); - } - } - - public void SetName(ReadOnlySpan name) - { - m_name = null; - fixed (byte* ptr = name) - { - FStr8or16 str = new(ptr, name.Length); - m_ptr->SetName(&str).TryThrow(); - } + m_ptr = null; } #endregion @@ -138,6 +108,12 @@ m_name is null #endregion + #region Present + + public void Present(bool NoWait = false) => Queue.Submit(this, NoWait); + + #endregion + #region Views FResourceMeta IGpuResource.GetMeta() => new() @@ -154,89 +130,6 @@ m_name is null #endregion - #region Present - - /// - /// 提交命令并等待下帧可用 - /// - public void Present() - { - using var _ = Queue.m_lock.EnterScope(); - var cmd = Queue.m_cmd; - if (cmd.m_current_output != null && cmd.m_current_output != this) - throw new ArgumentException( - $"The command is already used by another output and cannot be presented in this output" - ); - cmd.Present(this); - fixed (FResourceMeta* p_resources = CollectionsMarshal.AsSpan(cmd.m_resource_metas)) - fixed (FCommandItem* p_commands = CollectionsMarshal.AsSpan(cmd.m_commands)) - fixed (byte* p_payload = CollectionsMarshal.AsSpan(cmd.m_payload)) - { - FCommandSubmit submit = new() - { - CommandCount = (uint)cmd.m_commands.Count, - ResourceCount = (uint)cmd.m_resource_metas.Count, - Commands = p_commands, - Resources = p_resources, - Payload = p_payload, - }; - try - { - m_ptr->Present(&submit).TryThrow(); - } - finally - { - cmd.Reset(); - } - } - } - - /// - /// 提交命令 - /// - public void PresentNoWait() - { - using var _ = Queue.m_lock.EnterScope(); - var cmd = Queue.m_cmd; - if (cmd.m_current_output != null && cmd.m_current_output != this) - throw new ArgumentException( - $"The command is already used by another output and cannot be presented in this output" - ); - cmd.Present(this); - fixed (FResourceMeta* p_resources = CollectionsMarshal.AsSpan(cmd.m_resource_metas)) - fixed (FCommandItem* p_commands = CollectionsMarshal.AsSpan(cmd.m_commands)) - fixed (byte* p_payload = CollectionsMarshal.AsSpan(cmd.m_payload)) - { - FCommandSubmit submit = new() - { - CommandCount = (uint)cmd.m_commands.Count, - ResourceCount = (uint)cmd.m_resource_metas.Count, - Commands = p_commands, - Resources = p_resources, - Payload = p_payload, - }; - try - { - m_ptr->PresentNoWait(&submit).TryThrow(); - } - finally - { - cmd.Reset(); - } - } - } - - /// - /// 等待下帧可用 - /// - public void WaitNextFrame() - { - using var _ = Queue.m_lock.EnterScope(); - m_ptr->WaitNextFrame().TryThrow(); - } - - #endregion - #region Resize public void Resize(uint width, uint height) => m_ptr->Resize(width, height).TryThrow(); diff --git a/Coplt.Graphics.Core/Core/GpuQueue.cs b/Coplt.Graphics.Core/Core/GpuQueue.cs index 3943749..cf4321c 100644 --- a/Coplt.Graphics.Core/Core/GpuQueue.cs +++ b/Coplt.Graphics.Core/Core/GpuQueue.cs @@ -97,6 +97,24 @@ m_name is null #endregion + #region Submit + + public void Submit(GpuExecutor Executor, bool NoWait = false) + { + using var _ = m_lock.EnterScope(); + if (Executor is GpuOutput output) + { + if (m_cmd.m_current_output != null && m_cmd.m_current_output != output) + throw new ArgumentException( + $"The command is already used by another output and cannot be presented in this output" + ); + m_cmd.Present(output); + } + m_cmd.Submit(this, Executor, NoWait); + } + + #endregion + #region CreateOutputForHwnd public GpuOutput CreateOutputForHwnd( @@ -125,7 +143,7 @@ public GpuOutput CreateOutputForHwnd( }; FGpuOutput* ptr; m_ptr->CreateOutputForHwnd(&f_options, (void*)Hwnd, &ptr).TryThrow(); - return new(this, ptr, Name); + return new(ptr, Name, this); } } diff --git a/Coplt.Graphics.Core/Native/FUploadLoc.cs b/Coplt.Graphics.Core/Native/FUploadLoc.cs index d288196..04c29f9 100644 --- a/Coplt.Graphics.Core/Native/FUploadLoc.cs +++ b/Coplt.Graphics.Core/Native/FUploadLoc.cs @@ -8,4 +8,6 @@ public FUploadLoc(in UploadLoc loc) { Index = (uint)loc.Index; } + + public static implicit operator FUploadLoc(in UploadLoc loc) => new(loc); } diff --git a/Coplt.Graphics.Core/Native/Native.D3d12.cs b/Coplt.Graphics.Core/Native/Native.D3d12.cs index 47aa19f..59b50b3 100644 --- a/Coplt.Graphics.Core/Native/Native.D3d12.cs +++ b/Coplt.Graphics.Core/Native/Native.D3d12.cs @@ -202,42 +202,26 @@ public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetVSync([NativeTypeName("Coplt::b8")] B8 Enable) - { - FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[5]))((FD3d12GpuOutput*)Unsafe.AsPointer(ref this), &result, Enable); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [return: NativeTypeName("Coplt::FResult")] - public FResult Resize([NativeTypeName("Coplt::u32")] uint Width, [NativeTypeName("Coplt::u32")] uint Height) + public FResult Wait() { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[6]))((FD3d12GpuOutput*)Unsafe.AsPointer(ref this), &result, Width, Height); + return *((delegate* unmanaged[Thiscall])(lpVtbl[5]))((FD3d12GpuOutput*)Unsafe.AsPointer(ref this), &result); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult Present([NativeTypeName("const FCommandSubmit *")] FCommandSubmit* submit) - { - FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[7]))((FD3d12GpuOutput*)Unsafe.AsPointer(ref this), &result, submit); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [return: NativeTypeName("Coplt::FResult")] - public FResult PresentNoWait([NativeTypeName("const FCommandSubmit *")] FCommandSubmit* submit) + public FResult SetVSync([NativeTypeName("Coplt::b8")] B8 Enable) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[8]))((FD3d12GpuOutput*)Unsafe.AsPointer(ref this), &result, submit); + return *((delegate* unmanaged[Thiscall])(lpVtbl[6]))((FD3d12GpuOutput*)Unsafe.AsPointer(ref this), &result, Enable); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult WaitNextFrame() + public FResult Resize([NativeTypeName("Coplt::u32")] uint Width, [NativeTypeName("Coplt::u32")] uint Height) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[9]))((FD3d12GpuOutput*)Unsafe.AsPointer(ref this), &result); + return *((delegate* unmanaged[Thiscall])(lpVtbl[7]))((FD3d12GpuOutput*)Unsafe.AsPointer(ref this), &result, Width, Height); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -245,7 +229,7 @@ public FResult WaitNextFrame() public FResult GetCurrentResourcePtr(void* @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[10]))((FD3d12GpuOutput*)Unsafe.AsPointer(ref this), &result, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[8]))((FD3d12GpuOutput*)Unsafe.AsPointer(ref this), &result, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -253,7 +237,7 @@ public FResult GetCurrentResourcePtr(void* @out) public FResult GetCurrentRtv(void* @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[11]))((FD3d12GpuOutput*)Unsafe.AsPointer(ref this), &result, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[9]))((FD3d12GpuOutput*)Unsafe.AsPointer(ref this), &result, @out); } public interface Interface : FGpuOutput.Interface diff --git a/Coplt.Graphics.Core/Native/Native.cs b/Coplt.Graphics.Core/Native/Native.cs index 1abbe03..0d6a39a 100644 --- a/Coplt.Graphics.Core/Native/Native.cs +++ b/Coplt.Graphics.Core/Native/Native.cs @@ -1533,6 +1533,22 @@ public FResult CreateOutputForHwnd([NativeTypeName("const FGpuOutputCreateOption return *((delegate* unmanaged[Thiscall])(lpVtbl[7]))((FGpuQueue*)Unsafe.AsPointer(ref this), &result, options, hwnd, @out); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FResult")] + public FResult Submit([NativeTypeName("Coplt::FGpuExecutor *")] FGpuExecutor* Executor, [NativeTypeName("const FCommandSubmit *")] FCommandSubmit* submit) + { + FResult result; + return *((delegate* unmanaged[Thiscall])(lpVtbl[8]))((FGpuQueue*)Unsafe.AsPointer(ref this), &result, Executor, submit); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FResult")] + public FResult SubmitNoWait([NativeTypeName("Coplt::FGpuExecutor *")] FGpuExecutor* Executor, [NativeTypeName("const FCommandSubmit *")] FCommandSubmit* submit) + { + FResult result; + return *((delegate* unmanaged[Thiscall])(lpVtbl[9]))((FGpuQueue*)Unsafe.AsPointer(ref this), &result, Executor, submit); + } + public interface Interface : FGpuObject.Interface { void* GetRawQueue(); @@ -1542,6 +1558,69 @@ public interface Interface : FGpuObject.Interface [return: NativeTypeName("Coplt::FResult")] FResult CreateOutputForHwnd([NativeTypeName("const FGpuOutputCreateOptions &")] FGpuOutputCreateOptions* options, void* hwnd, FGpuOutput** @out); + + [return: NativeTypeName("Coplt::FResult")] + FResult Submit([NativeTypeName("Coplt::FGpuExecutor *")] FGpuExecutor* Executor, [NativeTypeName("const FCommandSubmit *")] FCommandSubmit* submit); + + [return: NativeTypeName("Coplt::FResult")] + FResult SubmitNoWait([NativeTypeName("Coplt::FGpuExecutor *")] FGpuExecutor* Executor, [NativeTypeName("const FCommandSubmit *")] FCommandSubmit* submit); + } + } + + [Guid("EDAB0989-E0C2-4B1E-826F-C73380088FC6")] + [NativeTypeName("struct FGpuExecutor : Coplt::FGpuObject")] + public unsafe partial struct FGpuExecutor : FGpuExecutor.Interface, INativeGuid + { + static Guid* INativeGuid.NativeGuid => (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in IID_FGpuExecutor)); + + public void** lpVtbl; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + ((delegate* unmanaged[Thiscall])(lpVtbl[0]))((FGpuExecutor*)Unsafe.AsPointer(ref this)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("size_t")] + public nuint Release() + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[1]))((FGpuExecutor*)Unsafe.AsPointer(ref this)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("size_t")] + public nuint AddRef() + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[2]))((FGpuExecutor*)Unsafe.AsPointer(ref this)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void* QueryInterface([NativeTypeName("const Guid &")] Guid* id) + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[3]))((FGpuExecutor*)Unsafe.AsPointer(ref this), id); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FResult")] + public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) + { + FResult result; + return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGpuExecutor*)Unsafe.AsPointer(ref this), &result, name); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FResult")] + public FResult Wait() + { + FResult result; + return *((delegate* unmanaged[Thiscall])(lpVtbl[5]))((FGpuExecutor*)Unsafe.AsPointer(ref this), &result); + } + + public interface Interface : FGpuObject.Interface + { + [return: NativeTypeName("Coplt::FResult")] + FResult Wait(); } } @@ -2005,24 +2084,57 @@ public partial struct FCommandSubmit public unsafe partial struct FCommandSubmit { - [NativeTypeName("Coplt::u32")] - public uint CommandCount; - - [NativeTypeName("Coplt::u32")] - public uint ResourceCount; - [NativeTypeName("Coplt::FCommandItem *")] public FCommandItem* Commands; + [NativeTypeName("Coplt::FRenderCommandItem *")] + public FRenderCommandItem* RenderCommands; + + [NativeTypeName("Coplt::FComputeCommandItem *")] + public FComputeCommandItem* ComputeCommands; + [NativeTypeName("Coplt::FResourceMeta *")] public FResourceMeta* Resources; - [NativeTypeName("Coplt::u8 *")] - public byte* Payload; + [NativeTypeName("Coplt::FRenderInfo *")] + public FRenderInfo* RenderInfos; + + [NativeTypeName("Coplt::FResolveInfo *")] + public FResolveInfo* ResolveInfos; + + [NativeTypeName("Coplt::FRect *")] + public FRect* Rects; + + [NativeTypeName("Coplt::FViewport *")] + public FViewport* Viewports; + + [NativeTypeName("Coplt::FMeshBuffers *")] + public FMeshBuffers* MeshBuffers; + + [NativeTypeName("Coplt::FVertexBufferRange *")] + public FVertexBufferRange* VertexBufferRanges; + + [NativeTypeName("Coplt::FBufferCopyRange *")] + public FBufferCopyRange* BufferCopyRanges; + + [NativeTypeName("Coplt::FBindItem *")] + public FBindItem* BindItems; + + [NativeTypeName("Coplt::Char8 *")] + public byte* Str8; + + [NativeTypeName("Coplt::Char16 *")] + public char* Str16; + + [NativeTypeName("Coplt::u32")] + public uint CommandCount; + + [NativeTypeName("Coplt::u32")] + public uint ResourceCount; } [Guid("F1C59CB4-7EE6-4EE2-80F4-07CC568920D2")] - [NativeTypeName("struct FGpuOutput : Coplt::FGpuObject")] + [NativeTypeName("struct FGpuOutput : Coplt::FGpuExecutor")] public unsafe partial struct FGpuOutput : FGpuOutput.Interface, INativeGuid { static Guid* INativeGuid.NativeGuid => (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in IID_FGpuOutput)); @@ -2077,60 +2189,35 @@ public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult SetVSync([NativeTypeName("Coplt::b8")] B8 Enable) - { - FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[5]))((FGpuOutput*)Unsafe.AsPointer(ref this), &result, Enable); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [return: NativeTypeName("Coplt::FResult")] - public FResult Resize([NativeTypeName("Coplt::u32")] uint Width, [NativeTypeName("Coplt::u32")] uint Height) - { - FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[6]))((FGpuOutput*)Unsafe.AsPointer(ref this), &result, Width, Height); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [return: NativeTypeName("Coplt::FResult")] - public FResult Present([NativeTypeName("const FCommandSubmit *")] FCommandSubmit* submit) + public FResult Wait() { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[7]))((FGpuOutput*)Unsafe.AsPointer(ref this), &result, submit); + return *((delegate* unmanaged[Thiscall])(lpVtbl[5]))((FGpuOutput*)Unsafe.AsPointer(ref this), &result); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult PresentNoWait([NativeTypeName("const FCommandSubmit *")] FCommandSubmit* submit) + public FResult SetVSync([NativeTypeName("Coplt::b8")] B8 Enable) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[8]))((FGpuOutput*)Unsafe.AsPointer(ref this), &result, submit); + return *((delegate* unmanaged[Thiscall])(lpVtbl[6]))((FGpuOutput*)Unsafe.AsPointer(ref this), &result, Enable); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult WaitNextFrame() + public FResult Resize([NativeTypeName("Coplt::u32")] uint Width, [NativeTypeName("Coplt::u32")] uint Height) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[9]))((FGpuOutput*)Unsafe.AsPointer(ref this), &result); + return *((delegate* unmanaged[Thiscall])(lpVtbl[7]))((FGpuOutput*)Unsafe.AsPointer(ref this), &result, Width, Height); } - public interface Interface : FGpuObject.Interface + public interface Interface : FGpuExecutor.Interface { [return: NativeTypeName("Coplt::FResult")] FResult SetVSync([NativeTypeName("Coplt::b8")] B8 Enable); [return: NativeTypeName("Coplt::FResult")] FResult Resize([NativeTypeName("Coplt::u32")] uint Width, [NativeTypeName("Coplt::u32")] uint Height); - - [return: NativeTypeName("Coplt::FResult")] - FResult Present([NativeTypeName("const FCommandSubmit *")] FCommandSubmit* submit); - - [return: NativeTypeName("Coplt::FResult")] - FResult PresentNoWait([NativeTypeName("const FCommandSubmit *")] FCommandSubmit* submit); - - [return: NativeTypeName("Coplt::FResult")] - FResult WaitNextFrame(); } } @@ -2267,25 +2354,24 @@ public enum FResourceState : uint public enum FCommandType : uint { None, - Transition, + End, + Label, + BeginScope, + EndScope, Present, + Barrier, ClearColor, ClearDepthStencil, - SetRenderTargets, - SetViewportScissor, Bind, + BufferCopy, + Render, + Compute, SetPipeline, + SetBinding, + SetViewportScissor, SetMeshBuffers, Draw, Dispatch, - BufferCopy, - } - - [NativeTypeName("Coplt::u32")] - public enum FCommandFlags : uint - { - None = 0, - DontTransition = 1 << 0, } [NativeTypeName("Coplt::u8")] @@ -2298,7 +2384,7 @@ public enum FResourceRefType : byte public unsafe partial struct FResourceMeta { - [NativeTypeName("__AnonymousRecord_Command_L47_C9")] + [NativeTypeName("__AnonymousRecord_Command_L62_C9")] public _Anonymous_e__Union Anonymous; [NativeTypeName("Coplt::FResourceState")] @@ -2382,75 +2468,106 @@ public partial struct FViewport public float MaxDepth; } - public partial struct FCommandTransition + [NativeTypeName("Coplt::u8")] + public enum FDepthStencilClearFlags : byte { - [NativeTypeName("Coplt::FResourceRef")] - public FResourceRef Resource; + None = 0, + Depth = 1, + Stencil = 2, + } - [NativeTypeName("Coplt::FResourceState")] - public FResourceState SrcState; + public partial struct FBindItem + { + [NativeTypeName("Coplt::FCommandType")] + public FCommandType Type; - [NativeTypeName("Coplt::FResourceState")] - public FResourceState DstState; + [NativeTypeName("Coplt::FView")] + public FView View; + + [NativeTypeName("Coplt::u32")] + public uint Index; } - public partial struct FCommandPresent + public partial struct FUploadLoc { - [NativeTypeName("Coplt::FResourceRef")] - public FResourceRef Image; + [NativeTypeName("Coplt::u32")] + public uint Index; } - public partial struct FCommandClearColor + [StructLayout(LayoutKind.Explicit)] + public partial struct FBufferRef { - [NativeTypeName("Coplt::u32")] - public uint RectCount; + [FieldOffset(0)] + [NativeTypeName("Coplt::FResourceRef")] + public FResourceRef Buffer; - [NativeTypeName("Coplt::u32")] - public uint RectIndex; + [FieldOffset(0)] + [NativeTypeName("Coplt::FUploadLoc")] + public FUploadLoc Upload; + } - [NativeTypeName("Coplt::FResourceRef")] - public FResourceRef Image; + [NativeTypeName("Coplt::u8")] + public enum FBufferRefType : byte + { + Buffer = 0, + Upload, + } - [NativeTypeName("f32[4]")] - public _Color_e__FixedBuffer Color; + public partial struct FBufferCopyRange + { + [NativeTypeName("Coplt::u64")] + public ulong Size; - [InlineArray(4)] - public partial struct _Color_e__FixedBuffer - { - public float e0; - } + [NativeTypeName("Coplt::u64")] + public ulong DstOffset; + + [NativeTypeName("Coplt::u64")] + public ulong SrcOffset; } [NativeTypeName("Coplt::u8")] - public enum FDepthStencilClearFlags : byte + public enum FResolveMode : byte { - None = 0, - Depth = 1, - Stencil = 2, + Decompress, + Min, + Max, + Average, } - public partial struct FCommandClearDepthStencil + public partial struct FResolveInfo { - [NativeTypeName("Coplt::u32")] - public uint RectCount; - - [NativeTypeName("Coplt::u32")] - public uint RectIndex; + [NativeTypeName("Coplt::FResourceRef")] + public FResourceRef Src; [NativeTypeName("Coplt::FResourceRef")] - public FResourceRef Image; + public FResourceRef Dst; - [NativeTypeName("Coplt::f32")] - public float Depth; + [NativeTypeName("Coplt::FGraphicsFormat")] + public FGraphicsFormat Format; - [NativeTypeName("Coplt::u8")] - public byte Stencil; + [NativeTypeName("Coplt::FResolveMode")] + public FResolveMode Mode; + } - [NativeTypeName("Coplt::FDepthStencilClearFlags")] - public FDepthStencilClearFlags Clear; + [NativeTypeName("Coplt::u8")] + public enum FLoadOp : byte + { + Load, + Clear, + Discard, + NoAccess, + } + + [NativeTypeName("Coplt::u8")] + public enum FStoreOp : byte + { + Store, + Discard, + Resolve, + NoAccess, } - public partial struct FCommandSetRenderTargets + public partial struct FRenderInfo { [NativeTypeName("Coplt::FResourceRef")] public FResourceRef Dsv; @@ -2461,119 +2578,333 @@ public partial struct FCommandSetRenderTargets [NativeTypeName("FResourceRef[8]")] public _Rtv_e__FixedBuffer Rtv; - [NativeTypeName("Coplt::u32")] - public uint ViewportCount; + [NativeTypeName("u32[8]")] + public _ResolveInfoIndex_e__FixedBuffer ResolveInfoIndex; - [NativeTypeName("Coplt::u32")] - public uint ViewportIndex; + [NativeTypeName("f32[32]")] + public _Color_e__FixedBuffer Color; - [NativeTypeName("Coplt::u32")] - public uint ScissorRectCount; + [NativeTypeName("Coplt::f32")] + public float Depth; - [NativeTypeName("Coplt::u32")] - public uint ScissorRectIndex; + [NativeTypeName("Coplt::u8")] + public byte Stencil; + + [NativeTypeName("FLoadOp[2]")] + public _DsvLoadOp_e__FixedBuffer DsvLoadOp; + + [NativeTypeName("FStoreOp[2]")] + public _DsvStoreOp_e__FixedBuffer DsvStoreOp; + + [NativeTypeName("FLoadOp[8]")] + public _RtvLoadOp_e__FixedBuffer RtvLoadOp; + + [NativeTypeName("FStoreOp[8]")] + public _RtvStoreOp_e__FixedBuffer RtvStoreOp; [InlineArray(8)] public partial struct _Rtv_e__FixedBuffer { public FResourceRef e0; } - } - public partial struct FCommandSetViewportScissor - { - [NativeTypeName("Coplt::u32")] - public uint ViewportCount; + [InlineArray(8)] + public partial struct _ResolveInfoIndex_e__FixedBuffer + { + public uint e0; + } - [NativeTypeName("Coplt::u32")] - public uint ViewportIndex; + [InlineArray(32)] + public partial struct _Color_e__FixedBuffer + { + public float e0; + } - [NativeTypeName("Coplt::u32")] - public uint ScissorRectCount; + [InlineArray(2)] + public partial struct _DsvLoadOp_e__FixedBuffer + { + public FLoadOp e0; + } - [NativeTypeName("Coplt::u32")] - public uint ScissorRectIndex; + [InlineArray(2)] + public partial struct _DsvStoreOp_e__FixedBuffer + { + public FStoreOp e0; + } + + [InlineArray(8)] + public partial struct _RtvLoadOp_e__FixedBuffer + { + public FLoadOp e0; + } + + [InlineArray(8)] + public partial struct _RtvStoreOp_e__FixedBuffer + { + public FStoreOp e0; + } } - public partial struct FBindItem + public partial struct FBufferRange { - [NativeTypeName("Coplt::FView")] - public FView View; + [NativeTypeName("Coplt::FResourceRef")] + public FResourceRef Buffer; + + [NativeTypeName("Coplt::u32")] + public uint Offset; + + [NativeTypeName("Coplt::u32")] + public uint Size; + } + + [NativeTypeName("struct FVertexBufferRange : Coplt::FBufferRange")] + public partial struct FVertexBufferRange + { + public FBufferRange Base; [NativeTypeName("Coplt::u32")] public uint Index; } - public unsafe partial struct FCommandBind + public unsafe partial struct FMeshBuffers { - [NativeTypeName("Coplt::FShaderBinding *")] - public FShaderBinding* Binding; + [NativeTypeName("Coplt::FMeshLayout *")] + public FMeshLayout* MeshLayout; + + [NativeTypeName("Coplt::FBufferRange")] + public FBufferRange IndexBuffer; [NativeTypeName("Coplt::u32")] - public uint ItemCount; + public uint VertexBufferCount; [NativeTypeName("Coplt::u32")] - public uint ItemsIndex; + public uint VertexBuffersIndex; } - public unsafe partial struct FCommandSetPipeline + [NativeTypeName("Coplt::u8")] + public enum FDispatchType : byte { - [NativeTypeName("Coplt::FShaderPipeline *")] - public FShaderPipeline* Pipeline; + Compute, + Mesh, + } - [NativeTypeName("Coplt::FShaderBinding *")] - public FShaderBinding* Binding; + public partial struct FCommandBase + { + [NativeTypeName("Coplt::FCommandType")] + public FCommandType Type; } - public partial struct FBufferRange + [NativeTypeName("struct FCommandLabel : Coplt::FCommandBase")] + public partial struct FCommandLabel { + public FCommandBase Base; + + [NativeTypeName("Coplt::u32")] + public uint StringIndex; + + [NativeTypeName("Coplt::u32")] + public uint StringLength; + + [NativeTypeName("Coplt::FStrType")] + public FStrType StrType; + } + + [NativeTypeName("struct FCommandBeginScope : Coplt::FCommandBase")] + public partial struct FCommandBeginScope + { + public FCommandBase Base; + + [NativeTypeName("Coplt::u32")] + public uint StringIndex; + + [NativeTypeName("Coplt::u32")] + public uint StringLength; + + [NativeTypeName("Coplt::FStrType")] + public FStrType StrType; + } + + [NativeTypeName("struct FCommandEndScope : Coplt::FCommandBase")] + public partial struct FCommandEndScope + { + public FCommandBase Base; + } + + [NativeTypeName("struct FCommandPresent : Coplt::FCommandBase")] + public partial struct FCommandPresent + { + public FCommandBase Base; + [NativeTypeName("Coplt::FResourceRef")] - public FResourceRef Buffer; + public FResourceRef Image; + } + + [NativeTypeName("struct FCommandBarrier : Coplt::FCommandBase")] + public partial struct FCommandBarrier + { + public FCommandBase Base; + } + + [NativeTypeName("struct FCommandClearColor : Coplt::FCommandBase")] + public partial struct FCommandClearColor + { + public FCommandBase Base; [NativeTypeName("Coplt::u32")] - public uint Offset; + public uint RectCount; [NativeTypeName("Coplt::u32")] - public uint Size; + public uint RectIndex; + + [NativeTypeName("Coplt::FResourceRef")] + public FResourceRef Image; + + [NativeTypeName("f32[4]")] + public _Color_e__FixedBuffer Color; + + [InlineArray(4)] + public partial struct _Color_e__FixedBuffer + { + public float e0; + } } - [NativeTypeName("struct FVertexBufferRange : Coplt::FBufferRange")] - public partial struct FVertexBufferRange + [NativeTypeName("struct FCommandClearDepthStencil : Coplt::FCommandBase")] + public partial struct FCommandClearDepthStencil { - public FBufferRange Base; + public FCommandBase Base; [NativeTypeName("Coplt::u32")] - public uint Index; + public uint RectCount; + + [NativeTypeName("Coplt::u32")] + public uint RectIndex; + + [NativeTypeName("Coplt::FResourceRef")] + public FResourceRef Image; + + [NativeTypeName("Coplt::f32")] + public float Depth; + + [NativeTypeName("Coplt::u8")] + public byte Stencil; + + [NativeTypeName("Coplt::FDepthStencilClearFlags")] + public FDepthStencilClearFlags Clear; } - public unsafe partial struct FCommandSetMeshBuffers + [NativeTypeName("struct FCommandBind : Coplt::FCommandBase")] + public unsafe partial struct FCommandBind { - [NativeTypeName("Coplt::FMeshLayout *")] - public FMeshLayout* MeshLayout; + public FCommandBase Base; - [NativeTypeName("Coplt::FGraphicsFormat")] - public FGraphicsFormat IndexFormat; + [NativeTypeName("Coplt::u32")] + public uint ItemCount; - [NativeTypeName("Coplt::FBufferRange")] - public FBufferRange IndexBuffer; + [NativeTypeName("Coplt::u32")] + public uint ItemsIndex; + + [NativeTypeName("Coplt::FShaderBinding *")] + public FShaderBinding* Binding; + } + + [NativeTypeName("struct FCommandBufferCopy : Coplt::FCommandBase")] + public partial struct FCommandBufferCopy + { + public FCommandBase Base; [NativeTypeName("Coplt::u32")] - public uint VertexStartSlot; + public uint RangeIndex; + + [NativeTypeName("Coplt::FBufferRef")] + public FBufferRef Dst; + + [NativeTypeName("Coplt::FBufferRef")] + public FBufferRef Src; + + [NativeTypeName("Coplt::FBufferRefType")] + public FBufferRefType DstType; + + [NativeTypeName("Coplt::FBufferRefType")] + public FBufferRefType SrcType; + } + + [NativeTypeName("struct FCommandRender : Coplt::FCommandBase")] + public partial struct FCommandRender + { + public FCommandBase Base; [NativeTypeName("Coplt::u32")] - public uint VertexBufferCount; + public uint InfoIndex; [NativeTypeName("Coplt::u32")] - public uint VertexBuffersIndex; + public uint CommandStartIndex; + } + + [NativeTypeName("struct FCommandCompute : Coplt::FCommandBase")] + public partial struct FCommandCompute + { + public FCommandBase Base; + + [NativeTypeName("Coplt::u32")] + public uint CommandStartIndex; } - public unsafe partial struct FCommandDraw + [NativeTypeName("struct FCommandSetPipeline : Coplt::FCommandBase")] + public unsafe partial struct FCommandSetPipeline { + public FCommandBase Base; + [NativeTypeName("Coplt::FShaderPipeline *")] public FShaderPipeline* Pipeline; + } + + [NativeTypeName("struct FCommandSetBinding : Coplt::FCommandBase")] + public unsafe partial struct FCommandSetBinding + { + public FCommandBase Base; [NativeTypeName("Coplt::FShaderBinding *")] public FShaderBinding* Binding; + } + + [NativeTypeName("struct FCommandSetViewportScissor : Coplt::FCommandBase")] + public partial struct FCommandSetViewportScissor + { + public FCommandBase Base; + + [NativeTypeName("Coplt::u32")] + public uint ViewportCount; + + [NativeTypeName("Coplt::u32")] + public uint ViewportIndex; + + [NativeTypeName("Coplt::u32")] + public uint ScissorRectCount; + + [NativeTypeName("Coplt::u32")] + public uint ScissorRectIndex; + } + + [NativeTypeName("struct FCommandSetMeshBuffers : Coplt::FCommandBase")] + public partial struct FCommandSetMeshBuffers + { + public FCommandBase Base; + + [NativeTypeName("Coplt::FGraphicsFormat")] + public FGraphicsFormat IndexFormat; + + [NativeTypeName("Coplt::u32")] + public uint VertexStartSlot; + + [NativeTypeName("Coplt::u32")] + public uint PayloadIndex; + } + + [NativeTypeName("struct FCommandDraw : Coplt::FCommandBase")] + public partial struct FCommandDraw + { + public FCommandBase Base; [NativeTypeName("Coplt::u32")] public uint VertexOrIndexCount; @@ -2584,221 +2915,474 @@ public unsafe partial struct FCommandDraw [NativeTypeName("Coplt::u32")] public uint FirstVertexOrIndex; - [NativeTypeName("Coplt::u32")] - public uint FirstInstance; + [NativeTypeName("Coplt::u32")] + public uint FirstInstance; + + [NativeTypeName("Coplt::u32")] + public uint VertexOffset; + + [NativeTypeName("Coplt::b8")] + public B8 Indexed; + } + + [NativeTypeName("struct FCommandDispatch : Coplt::FCommandBase")] + public partial struct FCommandDispatch + { + public FCommandBase Base; + + [NativeTypeName("Coplt::u32")] + public uint GroupCountX; + + [NativeTypeName("Coplt::u32")] + public uint GroupCountY; + + [NativeTypeName("Coplt::u32")] + public uint GroupCountZ; + + [NativeTypeName("Coplt::FDispatchType")] + public FDispatchType Type; + } + + public partial struct FCommandItem + { + [NativeTypeName("__AnonymousRecord_Command_L404_C9")] + public _Anonymous_e__Union Anonymous; + + [UnscopedRef] + public ref FCommandType Type + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.Type; + } + } + + [UnscopedRef] + public ref FCommandLabel Label + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.Label; + } + } + + [UnscopedRef] + public ref FCommandBeginScope BeginScope + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.BeginScope; + } + } + + [UnscopedRef] + public ref FCommandEndScope EndScope + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.EndScope; + } + } + + [UnscopedRef] + public ref FCommandPresent Present + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.Present; + } + } + + [UnscopedRef] + public ref FCommandBarrier Barrier + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.Barrier; + } + } + + [UnscopedRef] + public ref FCommandClearColor ClearColor + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.ClearColor; + } + } + + [UnscopedRef] + public ref FCommandClearDepthStencil ClearDepthStencil + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.ClearDepthStencil; + } + } + + [UnscopedRef] + public ref FCommandBind Bind + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.Bind; + } + } + + [UnscopedRef] + public ref FCommandBufferCopy BufferCopy + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.BufferCopy; + } + } + + [UnscopedRef] + public ref FCommandRender Render + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.Render; + } + } + + [UnscopedRef] + public ref FCommandCompute Compute + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.Compute; + } + } + + [UnscopedRef] + public Span _pad + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return Anonymous._pad; + } + } + + [StructLayout(LayoutKind.Explicit)] + public partial struct _Anonymous_e__Union + { + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandType")] + public FCommandType Type; - [NativeTypeName("Coplt::u32")] - public uint VertexOffset; + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandLabel")] + public FCommandLabel Label; - [NativeTypeName("Coplt::b8")] - public B8 Indexed; - } + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandBeginScope")] + public FCommandBeginScope BeginScope; - [NativeTypeName("Coplt::u8")] - public enum FDispatchType : byte - { - Compute, - Mesh, - } + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandEndScope")] + public FCommandEndScope EndScope; - public unsafe partial struct FCommandDispatch - { - [NativeTypeName("Coplt::FShaderPipeline *")] - public FShaderPipeline* Pipeline; + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandPresent")] + public FCommandPresent Present; - [NativeTypeName("Coplt::FShaderBinding *")] - public FShaderBinding* Binding; + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandBarrier")] + public FCommandBarrier Barrier; - [NativeTypeName("Coplt::u32")] - public uint GroupCountX; + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandClearColor")] + public FCommandClearColor ClearColor; - [NativeTypeName("Coplt::u32")] - public uint GroupCountY; + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandClearDepthStencil")] + public FCommandClearDepthStencil ClearDepthStencil; - [NativeTypeName("Coplt::u32")] - public uint GroupCountZ; + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandBind")] + public FCommandBind Bind; - [NativeTypeName("Coplt::FDispatchType")] - public FDispatchType Type; - } + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandBufferCopy")] + public FCommandBufferCopy BufferCopy; - public partial struct FUploadLoc - { - [NativeTypeName("Coplt::u32")] - public uint Index; - } + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandRender")] + public FCommandRender Render; - [StructLayout(LayoutKind.Explicit)] - public partial struct FBufferRef - { - [FieldOffset(0)] - [NativeTypeName("Coplt::FResourceRef")] - public FResourceRef Buffer; + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandCompute")] + public FCommandCompute Compute; - [FieldOffset(0)] - [NativeTypeName("Coplt::FUploadLoc")] - public FUploadLoc Upload; - } + [FieldOffset(0)] + [NativeTypeName("u8[32]")] + public __pad_e__FixedBuffer _pad; - [NativeTypeName("Coplt::u8")] - public enum FBufferRefType : byte - { - Buffer = 0, - Upload, + [InlineArray(32)] + public partial struct __pad_e__FixedBuffer + { + public byte e0; + } + } } - public partial struct FCommandBufferCopy + public partial struct FRenderCommandItem { - [NativeTypeName("Coplt::u64")] - public ulong Size; - - [NativeTypeName("Coplt::u64")] - public ulong DstOffset; - - [NativeTypeName("Coplt::u64")] - public ulong SrcOffset; - - [NativeTypeName("Coplt::FBufferRef")] - public FBufferRef Dst; + [NativeTypeName("__AnonymousRecord_Command_L432_C9")] + public _Anonymous_e__Union Anonymous; - [NativeTypeName("Coplt::FBufferRef")] - public FBufferRef Src; + [UnscopedRef] + public ref FCommandType Type + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.Type; + } + } - [NativeTypeName("Coplt::FBufferRefType")] - public FBufferRefType DstType; + [UnscopedRef] + public ref FCommandLabel Label + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.Label; + } + } - [NativeTypeName("Coplt::FBufferRefType")] - public FBufferRefType SrcType; - } + [UnscopedRef] + public ref FCommandBeginScope BeginScope + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.BeginScope; + } + } - public partial struct FCommandItem - { - [NativeTypeName("Coplt::FCommandType")] - public FCommandType Type; + [UnscopedRef] + public ref FCommandEndScope EndScope + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.EndScope; + } + } - [NativeTypeName("Coplt::FCommandFlags")] - public FCommandFlags Flags; + [UnscopedRef] + public ref FCommandSetPipeline SetPipeline + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.SetPipeline; + } + } - [NativeTypeName("__AnonymousRecord_Command_L295_C9")] - public _Anonymous_e__Union Anonymous; + [UnscopedRef] + public ref FCommandSetBinding SetBinding + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.SetBinding; + } + } [UnscopedRef] - public ref FCommandTransition Transition + public ref FCommandSetViewportScissor SetViewportScissor { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return ref Anonymous.Transition; + return ref Anonymous.SetViewportScissor; } } [UnscopedRef] - public ref FCommandPresent Present + public ref FCommandSetMeshBuffers SetMeshBuffers { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return ref Anonymous.Present; + return ref Anonymous.SetMeshBuffers; } } [UnscopedRef] - public ref FCommandClearColor ClearColor + public ref FCommandDraw Draw { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return ref Anonymous.ClearColor; + return ref Anonymous.Draw; } } [UnscopedRef] - public ref FCommandClearDepthStencil ClearDepthStencil + public ref FCommandDispatch Dispatch { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return ref Anonymous.ClearDepthStencil; + return ref Anonymous.Dispatch; } } [UnscopedRef] - public ref FCommandSetRenderTargets SetRenderTargets + public Span _pad { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return ref Anonymous.SetRenderTargets; + return Anonymous._pad; + } + } + + [StructLayout(LayoutKind.Explicit)] + public partial struct _Anonymous_e__Union + { + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandType")] + public FCommandType Type; + + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandLabel")] + public FCommandLabel Label; + + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandBeginScope")] + public FCommandBeginScope BeginScope; + + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandEndScope")] + public FCommandEndScope EndScope; + + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandSetPipeline")] + public FCommandSetPipeline SetPipeline; + + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandSetBinding")] + public FCommandSetBinding SetBinding; + + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandSetViewportScissor")] + public FCommandSetViewportScissor SetViewportScissor; + + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandSetMeshBuffers")] + public FCommandSetMeshBuffers SetMeshBuffers; + + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandDraw")] + public FCommandDraw Draw; + + [FieldOffset(0)] + [NativeTypeName("Coplt::FCommandDispatch")] + public FCommandDispatch Dispatch; + + [FieldOffset(0)] + [NativeTypeName("u8[32]")] + public __pad_e__FixedBuffer _pad; + + [InlineArray(32)] + public partial struct __pad_e__FixedBuffer + { + public byte e0; } } + } + + public partial struct FComputeCommandItem + { + [NativeTypeName("__AnonymousRecord_Command_L455_C9")] + public _Anonymous_e__Union Anonymous; [UnscopedRef] - public ref FCommandSetViewportScissor SetViewportScissor + public ref FCommandType Type { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return ref Anonymous.SetViewportScissor; + return ref Anonymous.Type; } } [UnscopedRef] - public ref FCommandBind Bind + public ref FCommandLabel Label { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return ref Anonymous.Bind; + return ref Anonymous.Label; } } [UnscopedRef] - public ref FCommandSetPipeline SetPipeline + public ref FCommandBeginScope BeginScope { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return ref Anonymous.SetPipeline; + return ref Anonymous.BeginScope; } } [UnscopedRef] - public ref FCommandSetMeshBuffers SetMeshBuffers + public ref FCommandEndScope EndScope { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return ref Anonymous.SetMeshBuffers; + return ref Anonymous.EndScope; } } [UnscopedRef] - public ref FCommandDraw Draw + public ref FCommandSetPipeline SetPipeline { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return ref Anonymous.Draw; + return ref Anonymous.SetPipeline; } } [UnscopedRef] - public ref FCommandDispatch Dispatch + public ref FCommandSetBinding SetBinding { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return ref Anonymous.Dispatch; + return ref Anonymous.SetBinding; } } [UnscopedRef] - public ref FCommandBufferCopy BufferCopy + public ref FCommandDispatch Dispatch { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return ref Anonymous.BufferCopy; + return ref Anonymous.Dispatch; } } @@ -2816,58 +3400,38 @@ public Span _pad public partial struct _Anonymous_e__Union { [FieldOffset(0)] - [NativeTypeName("Coplt::FCommandTransition")] - public FCommandTransition Transition; - - [FieldOffset(0)] - [NativeTypeName("Coplt::FCommandPresent")] - public FCommandPresent Present; - - [FieldOffset(0)] - [NativeTypeName("Coplt::FCommandClearColor")] - public FCommandClearColor ClearColor; - - [FieldOffset(0)] - [NativeTypeName("Coplt::FCommandClearDepthStencil")] - public FCommandClearDepthStencil ClearDepthStencil; + [NativeTypeName("Coplt::FCommandType")] + public FCommandType Type; [FieldOffset(0)] - [NativeTypeName("Coplt::FCommandSetRenderTargets")] - public FCommandSetRenderTargets SetRenderTargets; + [NativeTypeName("Coplt::FCommandLabel")] + public FCommandLabel Label; [FieldOffset(0)] - [NativeTypeName("Coplt::FCommandSetViewportScissor")] - public FCommandSetViewportScissor SetViewportScissor; + [NativeTypeName("Coplt::FCommandBeginScope")] + public FCommandBeginScope BeginScope; [FieldOffset(0)] - [NativeTypeName("Coplt::FCommandBind")] - public FCommandBind Bind; + [NativeTypeName("Coplt::FCommandEndScope")] + public FCommandEndScope EndScope; [FieldOffset(0)] [NativeTypeName("Coplt::FCommandSetPipeline")] public FCommandSetPipeline SetPipeline; [FieldOffset(0)] - [NativeTypeName("Coplt::FCommandSetMeshBuffers")] - public FCommandSetMeshBuffers SetMeshBuffers; - - [FieldOffset(0)] - [NativeTypeName("Coplt::FCommandDraw")] - public FCommandDraw Draw; + [NativeTypeName("Coplt::FCommandSetBinding")] + public FCommandSetBinding SetBinding; [FieldOffset(0)] [NativeTypeName("Coplt::FCommandDispatch")] public FCommandDispatch Dispatch; [FieldOffset(0)] - [NativeTypeName("Coplt::FCommandBufferCopy")] - public FCommandBufferCopy BufferCopy; - - [FieldOffset(0)] - [NativeTypeName("u8[56]")] + [NativeTypeName("u8[32]")] public __pad_e__FixedBuffer _pad; - [InlineArray(56)] + [InlineArray(32)] public partial struct __pad_e__FixedBuffer { public byte e0; @@ -3702,6 +4266,8 @@ public static partial class Native public static readonly Guid IID_FGpuQueue = new Guid(0x95E60E28, 0xE387, 0x4055, 0x9B, 0x33, 0x2D, 0x23, 0xAF, 0x90, 0x1F, 0x8A); + public static readonly Guid IID_FGpuExecutor = new Guid(0xEDAB0989, 0xE0C2, 0x4B1E, 0x82, 0x6F, 0xC7, 0x33, 0x80, 0x08, 0x8F, 0xC6); + public static readonly Guid IID_FGpuView = new Guid(0xB3AEB8A5, 0x1FA6, 0x4866, 0x97, 0xEF, 0x1A, 0x5F, 0xA4, 0x01, 0xE1, 0x8F); public static readonly Guid IID_FGpuResource = new Guid(0xF99DCEEC, 0x2F0C, 0x4A28, 0xB6, 0x66, 0xBE, 0xB7, 0xC3, 0x52, 0x19, 0xD6); diff --git a/Coplt.Graphics.Native/Api/CMakeLists.txt b/Coplt.Graphics.Native/Api/CMakeLists.txt index fd6f952..97de59a 100644 --- a/Coplt.Graphics.Native/Api/CMakeLists.txt +++ b/Coplt.Graphics.Native/Api/CMakeLists.txt @@ -44,6 +44,7 @@ add_library(${target_name} STATIC Src/Blob.cc FFI/Context.h FFI/Binding.h + FFI/Executor.h ) set_target_properties(${target_name} PROPERTIES LINKER_LANGUAGE CXX) add_library(Coplt::Graphics::Api ALIAS ${target_name}) diff --git a/Coplt.Graphics.Native/Api/FFI/Command.h b/Coplt.Graphics.Native/Api/FFI/Command.h index 6b4f691..1296f5e 100644 --- a/Coplt.Graphics.Native/Api/FFI/Command.h +++ b/Coplt.Graphics.Native/Api/FFI/Command.h @@ -11,28 +11,43 @@ namespace Coplt enum class FCommandType : u32 { None, - // 手动资源过渡 - Transition, + // Render / Compute + End, + + Label, + BeginScope, + EndScope, + // 仅内部使用 Present, + + // 手动屏障 + Barrier, + ClearColor, ClearDepthStencil, - SetRenderTargets, - SetViewportScissor, + Bind, + + BufferCopy, + + Render, + Compute, + + // Render / Compute SetPipeline, + SetBinding, + + // Render + SetViewportScissor, SetMeshBuffers, Draw, + + // Render / Compute Dispatch, - BufferCopy, }; - enum class FCommandFlags : u32 - { - None = 0, - // 不要自动计算资源过渡 - DontTransition = 1 << 0, - }; + //////////////////////////////////////////////////////////////////////////////////////////////////// enum class FResourceRefType : u8 { @@ -81,7 +96,7 @@ namespace Coplt bool IsEmpty() const { - return ResourceIndex == COPLT_U32_MAX; + return ResourceIndex == 0; } #endif }; @@ -104,97 +119,94 @@ namespace Coplt f32 MaxDepth; }; - struct FCommandTransition + COPLT_ENUM_FLAGS(FDepthStencilClearFlags, u8) { - FResourceRef Resource{}; - FResourceState SrcState{}; - FResourceState DstState{}; + None = 0, + Depth = 1, + Stencil = 2, }; - struct FCommandPresent + struct FBindItem { - FResourceRef Image{}; + FCommandType Type{}; + FView View{}; + u32 Index{}; }; - struct FCommandClearColor + struct FUploadLoc { - // 有多少个 Rect - u32 RectCount{}; - // Payload 内的索引 - u32 RectIndex{}; - FResourceRef Image{}; - f32 Color[4]{}; + u32 Index{}; }; - COPLT_ENUM_FLAGS(FDepthStencilClearFlags, u8) + union FBufferRef { - None = 0, - Depth = 1, - Stencil = 2, + FResourceRef Buffer; + FUploadLoc Upload; }; - struct FCommandClearDepthStencil + enum class FBufferRefType : u8 { - // 有多少个 Rect - u32 RectCount{}; - // Payload 内的索引, 类型为 FRect - u32 RectIndex{}; - FResourceRef Image{}; - f32 Depth{}; - u8 Stencil{}; - FDepthStencilClearFlags Clear{}; + // GpuBuffer 对象资源引用 + Buffer = 0, + // 当前帧上下文中第几个上传缓冲区 + Upload, }; - struct FCommandSetRenderTargets + struct FBufferCopyRange { - // 可选 - FResourceRef Dsv{}; - u32 NumRtv{}; - FResourceRef Rtv[8]{}; + // Size 为 u64::max 时复制整个 + u64 Size{}; + u64 DstOffset{}; + u64 SrcOffset{}; + }; - // 有多少个 Viewport - u32 ViewportCount{}; - // Payload 内的索引, 类型为 FViewport - u32 ViewportIndex{}; - // 有多少个 Rect - u32 ScissorRectCount{}; - // Payload 内的索引, 类型为 FRect - u32 ScissorRectIndex{}; + enum class FResolveMode : u8 + { + Decompress, + Min, + Max, + Average, }; - struct FCommandSetViewportScissor + struct FResolveInfo { - // 有多少个 Viewport - u32 ViewportCount{}; - // Payload 内的索引 - u32 ViewportIndex{}; - // 有多少个 Rect - u32 ScissorRectCount{}; - // Payload 内的索引, 类型为 FRect - u32 ScissorRectIndex{}; + FResourceRef Src{}; + FResourceRef Dst{}; + FGraphicsFormat Format{}; + FResolveMode Mode{}; }; - struct FBindItem + enum class FLoadOp : u8 { - FView View{}; - u32 Index{}; + Load, + Clear, + Discard, + NoAccess, }; - struct FCommandBind + enum class FStoreOp : u8 { - // 要修改的绑定集 - FShaderBinding* Binding{}; - // 有多少个绑定修改 - u32 ItemCount{}; - // Payload 内的索引, 类型为 FBindItem - u32 ItemsIndex{}; + Store, + Discard, + Resolve, + NoAccess, }; - struct FCommandSetPipeline + struct FRenderInfo { - FShaderPipeline* Pipeline{}; // 可选 - FShaderBinding* Binding{}; + FResourceRef Dsv{}; + u32 NumRtv{}; + FResourceRef Rtv[8]{}; + // 类型为 FResolveInfo + u32 ResolveInfoIndex[8]{}; + f32 Color[4 * 8]{}; + f32 Depth{}; + u8 Stencil{}; + FLoadOp DsvLoadOp[2]{}; + FStoreOp DsvStoreOp[2]{}; + FLoadOp RtvLoadOp[8]{}; + FStoreOp RtvStoreOp[8]{}; }; struct FBufferRange @@ -209,127 +221,283 @@ namespace Coplt u32 Index{}; }; - struct FCommandSetMeshBuffers + struct FMeshBuffers { FMeshLayout* MeshLayout{}; - FGraphicsFormat IndexFormat{}; // 可选 FBufferRange IndexBuffer{}; // 0 .. 31 - u32 VertexStartSlot{}; - // 0 .. 31 u32 VertexBufferCount{}; // Payload 内的索引,类型为 FVertexBufferRange u32 VertexBuffersIndex{}; }; - struct FCommandDraw - { - // 可选 - FShaderPipeline* Pipeline{}; - // 可选 - FShaderBinding* Binding{}; - u32 VertexOrIndexCount{}; - u32 InstanceCount{}; - u32 FirstVertexOrIndex{}; - u32 FirstInstance{}; - // 仅 Indexed 使用 - u32 VertexOffset{}; - b8 Indexed{}; - }; - enum class FDispatchType : u8 { Compute, Mesh, }; - struct FCommandDispatch + //////////////////////////////////////////////////////////////////////////////////////////////////// + + struct FCommandBase { - // 可选 - FShaderPipeline* Pipeline{}; - // 可选 - FShaderBinding* Binding{}; - u32 GroupCountX{}; - u32 GroupCountY{}; - u32 GroupCountZ{}; - FDispatchType Type{}; + FCommandType Type{}; }; - struct FUploadLoc + //////////////////////////////////////////////////////////////////////////////////////////////////// + + struct FCommandLabel : FCommandBase { - u32 Index{}; + u32 StringIndex{}; + u32 StringLength{}; + FStrType StrType{}; }; - union FBufferRef + struct FCommandBeginScope : FCommandBase { - FResourceRef Buffer; - FUploadLoc Upload; + u32 StringIndex{}; + u32 StringLength{}; + FStrType StrType{}; }; - enum class FBufferRefType : u8 + struct FCommandEndScope : FCommandBase { - // GpuBuffer 对象资源引用 - Buffer = 0, - // 当前帧上下文中第几个上传缓冲区 - Upload, }; - struct FCommandBufferCopy + //////////////////////////////////////////////////////////////////////////////////////////////////// + + struct FCommandPresent : FCommandBase { - // Size 为 u64::max 时复制整个 - u64 Size{}; - u64 DstOffset{}; - u64 SrcOffset{}; + FResourceRef Image{}; + }; + + //////////////////////////////////////////////////////////////////////////////////////////////////// + + struct FCommandBarrier : FCommandBase + { + // todo + }; + + //////////////////////////////////////////////////////////////////////////////////////////////////// + + struct FCommandClearColor : FCommandBase + { + // 有多少个 Rect + u32 RectCount{}; + // Payload 内的索引 + u32 RectIndex{}; + FResourceRef Image{}; + f32 Color[4]{}; + }; + + struct FCommandClearDepthStencil : FCommandBase + { + // 有多少个 Rect + u32 RectCount{}; + // Payload 内的索引, 类型为 FRect + u32 RectIndex{}; + FResourceRef Image{}; + f32 Depth{}; + u8 Stencil{}; + FDepthStencilClearFlags Clear{}; + }; + + //////////////////////////////////////////////////////////////////////////////////////////////////// + + struct FCommandBind : FCommandBase + { + // 有多少个绑定修改 + u32 ItemCount{}; + // Payload 内的索引, 类型为 FBindItem + u32 ItemsIndex{}; + // 要修改的绑定集 + FShaderBinding* Binding{}; + }; + + //////////////////////////////////////////////////////////////////////////////////////////////////// + + struct FCommandBufferCopy : FCommandBase + { + // 类型为 FBufferCopyRange + u32 RangeIndex{}; FBufferRef Dst{}; FBufferRef Src{}; FBufferRefType DstType{}; FBufferRefType SrcType{}; }; - struct FCommandItem + //////////////////////////////////////////////////////////////////////////////////////////////////// + + struct FCommandRender : FCommandBase { - FCommandType Type{}; - FCommandFlags Flags{}; + // 类型为 FRenderInfo + u32 InfoIndex{}; + u32 CommandStartIndex{}; + }; + + struct FCommandCompute : FCommandBase + { + u32 CommandStartIndex{}; + }; + + //////////////////////////////////////////////////////////////////////////////////////////////////// + + struct FCommandSetPipeline : FCommandBase + { + FShaderPipeline* Pipeline{}; + }; + struct FCommandSetBinding : FCommandBase + { + FShaderBinding* Binding{}; + }; + + //////////////////////////////////////////////////////////////////////////////////////////////////// + + struct FCommandSetViewportScissor : FCommandBase + { + // 有多少个 Viewport + u32 ViewportCount{}; + // Payload 内的索引 + u32 ViewportIndex{}; + // 有多少个 Rect + u32 ScissorRectCount{}; + // Payload 内的索引, 类型为 FRect + u32 ScissorRectIndex{}; + }; + + struct FCommandSetMeshBuffers : FCommandBase + { + FGraphicsFormat IndexFormat{}; + // 0 .. 31 + u32 VertexStartSlot{}; + // 类型为 FMeshBuffers + u32 PayloadIndex{}; + }; + + struct FCommandDraw : FCommandBase + { + u32 VertexOrIndexCount{}; + u32 InstanceCount{}; + u32 FirstVertexOrIndex{}; + u32 FirstInstance{}; + // 仅 Indexed 使用 + u32 VertexOffset{}; + b8 Indexed{}; + }; + + //////////////////////////////////////////////////////////////////////////////////////////////////// + + struct FCommandDispatch : FCommandBase + { + u32 GroupCountX{}; + u32 GroupCountY{}; + u32 GroupCountZ{}; + FDispatchType Type{}; + }; + + //////////////////////////////////////////////////////////////////////////////////////////////////// + + struct FCommandItem + { union { - FCommandTransition Transition; + FCommandType Type{}; + + FCommandLabel Label; + FCommandBeginScope BeginScope; + FCommandEndScope EndScope; + FCommandPresent Present; + + FCommandBarrier Barrier; + FCommandClearColor ClearColor; FCommandClearDepthStencil ClearDepthStencil; - FCommandSetRenderTargets SetRenderTargets; - FCommandSetViewportScissor SetViewportScissor; + FCommandBind Bind; + + FCommandBufferCopy BufferCopy; + + FCommandRender Render; + FCommandCompute Compute; + + u8 _pad[32]; + }; + }; + + struct FRenderCommandItem + { + union + { + FCommandType Type{}; + + FCommandLabel Label; + FCommandBeginScope BeginScope; + FCommandEndScope EndScope; + FCommandSetPipeline SetPipeline; + FCommandSetBinding SetBinding; + + FCommandSetViewportScissor SetViewportScissor; FCommandSetMeshBuffers SetMeshBuffers; FCommandDraw Draw; + FCommandDispatch Dispatch; - FCommandBufferCopy BufferCopy; - u8 _pad[56]{}; + u8 _pad[32]; + }; + }; + + struct FComputeCommandItem + { + union + { + FCommandType Type{}; + + FCommandLabel Label; + FCommandBeginScope BeginScope; + FCommandEndScope EndScope; + + FCommandSetPipeline SetPipeline; + FCommandSetBinding SetBinding; + + FCommandDispatch Dispatch; + + u8 _pad[32]; }; }; + //////////////////////////////////////////////////////////////////////////////////////////////////// + struct FCommandSubmit { - // 有多少命令 - u32 CommandCount{}; - // 有多少资源 - u32 ResourceCount{}; - // 需要保证对象指针生命周期 >= FCommandSubmit 的生命周期,提交操作可能会修改此内存,提交后内存将无效 FCommandItem* Commands{}; - // 需要保证对象指针生命周期 >= FCommandSubmit 的生命周期,提交操作可能会修改此内存,提交后内存将无效 + FRenderCommandItem* RenderCommands{}; + FComputeCommandItem* ComputeCommands{}; FResourceMeta* Resources{}; - // 需要保证对象指针生命周期 >= FCommandSubmit 的生命周期,提交操作可能会修改此内存,提交后内存将无效 - u8* Payload{}; + FRenderInfo* RenderInfos{}; + FResolveInfo* ResolveInfos{}; + FRect* Rects{}; + FViewport* Viewports{}; + FMeshBuffers* MeshBuffers{}; + FVertexBufferRange* VertexBufferRanges{}; + FBufferCopyRange* BufferCopyRanges{}; + FBindItem* BindItems{}; + Char8* Str8{}; + Char16* Str16{}; + u32 CommandCount{}; + u32 ResourceCount{}; }; + //////////////////////////////////////////////////////////////////////////////////////////////////// + #ifdef FFI_SRC inline FResourceMeta& FResourceRef::Get(const FCommandSubmit& submit) const { - return submit.Resources[ResourceIndex]; + return submit.Resources[ResourceIndex - 1]; } #endif diff --git a/Coplt.Graphics.Native/Api/FFI/Executor.h b/Coplt.Graphics.Native/Api/FFI/Executor.h new file mode 100644 index 0000000..e697f5d --- /dev/null +++ b/Coplt.Graphics.Native/Api/FFI/Executor.h @@ -0,0 +1,12 @@ +#pragma once + +#include "GpuObject.h" + +namespace Coplt +{ + COPLT_INTERFACE_DEFINE(FGpuExecutor, "edab0989-e0c2-4b1e-826f-c73380088fc6", FGpuObject) + { + // 等待可重用,在提交后必须先等待才能再次提交 + virtual FResult Wait() noexcept = 0; + }; +} diff --git a/Coplt.Graphics.Native/Api/FFI/Output.h b/Coplt.Graphics.Native/Api/FFI/Output.h index 7024011..df80750 100644 --- a/Coplt.Graphics.Native/Api/FFI/Output.h +++ b/Coplt.Graphics.Native/Api/FFI/Output.h @@ -1,5 +1,6 @@ #pragma once +#include "Executor.h" #include "GpuObject.h" #include "States.h" #include "GraphicsFormat.h" @@ -61,7 +62,7 @@ namespace Coplt struct FCommandSubmit; - COPLT_INTERFACE_DEFINE(FGpuOutput, "f1c59cb4-7ee6-4ee2-80f4-07cc568920d2", FGpuObject) + COPLT_INTERFACE_DEFINE(FGpuOutput, "f1c59cb4-7ee6-4ee2-80f4-07cc568920d2", FGpuExecutor) { FResourceState m_state; // 外部不允许修改 @@ -76,11 +77,11 @@ namespace Coplt virtual FResult Resize(u32 Width, u32 Height) noexcept = 0; - // 提交命令并等待下帧可用 - virtual FResult Present(/* 可选 */ const FCommandSubmit* submit) noexcept = 0; - // 提交命令 - virtual FResult PresentNoWait(/* 可选 */ const FCommandSubmit* submit) noexcept = 0; - // 等待下帧可用 - virtual FResult WaitNextFrame() noexcept = 0; + // // 提交命令并等待下帧可用 + // virtual FResult Present(/* 可选 */ const FCommandSubmit* submit) noexcept = 0; + // // 提交命令 + // virtual FResult PresentNoWait(/* 可选 */ const FCommandSubmit* submit) noexcept = 0; + // // 等待下帧可用 + // virtual FResult WaitNextFrame() noexcept = 0; }; } diff --git a/Coplt.Graphics.Native/Api/FFI/Queue.h b/Coplt.Graphics.Native/Api/FFI/Queue.h index 81f7f69..f7156ab 100644 --- a/Coplt.Graphics.Native/Api/FFI/Queue.h +++ b/Coplt.Graphics.Native/Api/FFI/Queue.h @@ -45,5 +45,10 @@ namespace Coplt void* hwnd, FGpuOutput** out ) noexcept = 0; + + // 提交命令并等待执行器可用 + virtual FResult Submit(FGpuExecutor* Executor, const FCommandSubmit* submit) noexcept = 0; + // 提交命令但是不等待执行器可用,必须先等待才能重新使用此执行器提交 + virtual FResult SubmitNoWait(FGpuExecutor* Executor, const FCommandSubmit* submit) noexcept = 0; }; } diff --git a/Coplt.Graphics.Native/Api/Include/Object.h b/Coplt.Graphics.Native/Api/Include/Object.h index 537922c..8c50f35 100644 --- a/Coplt.Graphics.Native/Api/Include/Object.h +++ b/Coplt.Graphics.Native/Api/Include/Object.h @@ -229,6 +229,16 @@ namespace Coplt { return get() == nullptr; } + + bool operator==(T* ptr) const + { + return get() == ptr; + } + + bool operator==(const T& ref) const + { + return *get() == ref; + } }; template diff --git a/Coplt.Graphics.Native/D3d12/CMakeLists.txt b/Coplt.Graphics.Native/D3d12/CMakeLists.txt index cfb43eb..9268baa 100644 --- a/Coplt.Graphics.Native/D3d12/CMakeLists.txt +++ b/Coplt.Graphics.Native/D3d12/CMakeLists.txt @@ -43,6 +43,7 @@ add_library(${target_name} SHARED Src/DescriptorManager.h Src/DescriptorManager.cc Include/View.h + Src/Executor.h ) set_target_properties(${target_name} PROPERTIES LINKER_LANGUAGE CXX) set_target_properties(${target_name} PROPERTIES OUTPUT_NAME "Coplt.Graphics.Native.D3d12") diff --git a/Coplt.Graphics.Native/D3d12/Src/Command.cc b/Coplt.Graphics.Native/D3d12/Src/Command.cc index 50ee419..4d75726 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Command.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Command.cc @@ -27,8 +27,8 @@ void D3d12CommandInterpreter::Context::Reset() { ResetPipeline(); NumRtv = 0; - Dsv = {COPLT_U32_MAX}; - Ibv = {COPLT_U32_MAX}; + Dsv = {}; + Ibv = {}; NumVbv = 0; } @@ -52,7 +52,7 @@ void D3d12CommandInterpreter::CmdNext() void D3d12CommandInterpreter::ReqState(const FResourceRef ResSrc, const FResourceState ReqState) { - auto& state = m_states[ResSrc.ResourceIndex]; + auto& state = m_states[ResSrc.ResourceIndex - 1]; const auto old_state = state.CurrentState; const auto new_state = ChangeState(old_state, ToDx(ReqState)); const auto last_item_size = state.CurrentItemsSize; @@ -78,7 +78,7 @@ void D3d12CommandInterpreter::ReqState(const FResourceRef ResSrc, const FResourc void D3d12CommandInterpreter::MarkResUse(const FResourceRef ResSrc) { - auto& state = m_states[ResSrc.ResourceIndex]; + auto& state = m_states[ResSrc.ResourceIndex - 1]; state.CurrentItemsSize = m_items.size(); } @@ -93,7 +93,7 @@ void D3d12CommandInterpreter::AddBarrier(ResState& state, const FResourceRef Res barrier.Transition.StateBefore = state.LastState; barrier.Transition.StateAfter = state.CurrentState; m_barriers.push_back(barrier); - m_barrier_resources.push_back(ResSrc.ResourceIndex); + m_barrier_resources.push_back(ResSrc.ResourceIndex - 1); } void D3d12CommandInterpreter::BarNext() @@ -146,29 +146,37 @@ void D3d12CommandInterpreter::CollectBarrier(const FCommandSubmit& submit) switch (item.Type) { case FCommandType::None: - case FCommandType::Transition: - case FCommandType::SetViewportScissor: goto CmdNext; + case FCommandType::Label: + COPLT_THROW("TODO"); + case FCommandType::BeginScope: + COPLT_THROW("TODO"); + case FCommandType::EndScope: + COPLT_THROW("TODO"); case FCommandType::Present: goto Present; + case FCommandType::Barrier: + COPLT_THROW("TODO"); case FCommandType::ClearColor: goto ClearColor; case FCommandType::ClearDepthStencil: goto ClearDepthStencil; - case FCommandType::SetRenderTargets: - goto SetRenderTargets; case FCommandType::Bind: goto Bind; + case FCommandType::BufferCopy: + goto BufferCopy; + case FCommandType::Render: + COPLT_THROW("TODO"); + case FCommandType::Compute: + COPLT_THROW("TODO"); + case FCommandType::End: case FCommandType::SetPipeline: - goto SetPipeline; + case FCommandType::SetBinding: + case FCommandType::SetViewportScissor: case FCommandType::SetMeshBuffers: - goto SetMeshBuffers; case FCommandType::Draw: - goto Draw; case FCommandType::Dispatch: - goto Dispatch; - case FCommandType::BufferCopy: - goto BufferCopy; + COPLT_THROW("Subcommands cannot be placed in the main command list"); } COPLT_THROW_FMT("Unknown command type {}", static_cast(item.Type)); @@ -194,99 +202,12 @@ void D3d12CommandInterpreter::CollectBarrier(const FCommandSubmit& submit) ReqState(cmd.Image, FResourceState::DepthWrite); continue; } - SetRenderTargets: - { - const auto& cmd = item.SetRenderTargets; - if (!cmd.Dsv.IsEmpty()) - { - ReqState(cmd.Dsv, FResourceState::DepthWrite); - m_context.Dsv = cmd.Dsv; - } - m_context.NumRtv = std::min(cmd.NumRtv, 8u); - for (u32 n = 0; n < m_context.NumRtv; ++n) - { - ReqState(cmd.Rtv[n], FResourceState::RenderTarget); - m_context.Rtv[n] = cmd.Rtv[n]; - } - continue; - } Bind: { const auto& cmd = item.Bind; // todo continue; } - SetPipeline: - { - const auto& cmd = item.SetPipeline; - SetPipelineContext(cmd.Pipeline, i); - continue; - } - SetMeshBuffers: - { - const auto& cmd = item.SetMeshBuffers; - if (!cmd.IndexBuffer.Buffer.IsEmpty()) - { - ReqState(cmd.IndexBuffer.Buffer, FResourceState::IndexBuffer); - m_context.Ibv = cmd.IndexBuffer.Buffer; - } - const auto vbs = reinterpret_cast(&submit.Payload[cmd.VertexBuffersIndex]); - if (cmd.VertexStartSlot + cmd.VertexBufferCount >= 31) - { - COPLT_THROW_FMT( - "The number of input buffers is out of range, the maximum allowed input slots is 31; at command {}", - i - ); - } - for (u32 n = 0; n < cmd.VertexBufferCount; ++n) - { - const auto& vb = vbs[n]; - ReqState(vb.Buffer, FResourceState::VertexBuffer); - m_context.Vbv[cmd.VertexStartSlot + n] = vb.Buffer; - } - continue; - } - Graphics_MarkResUse: - { - const auto g_state = m_context.GPipeline->GetGraphicsState(); - if (g_state->DsvFormat != FGraphicsFormat::Unknown && !m_context.Dsv.IsEmpty()) - { - MarkResUse(m_context.Dsv); - } - const auto num_rts = std::min(m_context.NumRtv, static_cast(g_state->NumRts)); - for (u32 n = 0; n < num_rts; ++n) - { - const auto rt = m_context.Rtv[n]; - if (!rt.IsEmpty()) MarkResUse(rt); - } - if (const auto mesh_layout = m_context.GPipeline->GetMeshLayout()) - { - auto buffers = mesh_layout->GetBuffers(); - for (u32 n = 0; n < buffers.size(); ++n) - { - const auto vb = m_context.Vbv[n]; - if (!vb.IsEmpty()) MarkResUse(vb); - } - } - continue; - } - Draw: - { - const auto& cmd = item.Draw; - if (cmd.Pipeline != nullptr) SetPipelineContext(cmd.Pipeline, i); - if (m_context.Pipeline == nullptr) - COPLT_THROW_FMT("Pipeline not set at command {}", i); - goto Graphics_MarkResUse; - } - Dispatch: - { - const auto& cmd = item.Dispatch; - if (cmd.Pipeline != nullptr) SetPipelineContext(cmd.Pipeline, i); - if (m_context.Pipeline == nullptr) - COPLT_THROW_FMT("Pipeline not set at command {}", i); - if (cmd.Type == FDispatchType::Mesh && m_context.GPipeline) goto Graphics_MarkResUse; - continue; - } BufferCopy: { const auto& cmd = item.BufferCopy; @@ -312,6 +233,71 @@ void D3d12CommandInterpreter::CollectBarrier(const FCommandSubmit& submit) } continue; } + // SetMeshBuffers: + // { + // const auto& cmd = item.SetMeshBuffers; + // if (!cmd.IndexBuffer.Buffer.IsEmpty()) + // { + // ReqState(cmd.IndexBuffer.Buffer, FResourceState::IndexBuffer); + // m_context.Ibv = cmd.IndexBuffer.Buffer; + // } + // const auto vbs = reinterpret_cast(&submit.Payload[cmd.VertexBuffersIndex]); + // if (cmd.VertexStartSlot + cmd.VertexBufferCount >= 31) + // { + // COPLT_THROW_FMT( + // "The number of input buffers is out of range, the maximum allowed input slots is 31; at command {}", + // i + // ); + // } + // for (u32 n = 0; n < cmd.VertexBufferCount; ++n) + // { + // const auto& vb = vbs[n]; + // ReqState(vb.Buffer, FResourceState::VertexBuffer); + // m_context.Vbv[cmd.VertexStartSlot + n] = vb.Buffer; + // } + // continue; + // } + // Graphics_MarkResUse: + // { + // const auto g_state = m_context.GPipeline->GetGraphicsState(); + // if (g_state->DsvFormat != FGraphicsFormat::Unknown && !m_context.Dsv.IsEmpty()) + // { + // MarkResUse(m_context.Dsv); + // } + // const auto num_rts = std::min(m_context.NumRtv, static_cast(g_state->NumRts)); + // for (u32 n = 0; n < num_rts; ++n) + // { + // const auto rt = m_context.Rtv[n]; + // if (!rt.IsEmpty()) MarkResUse(rt); + // } + // if (const auto mesh_layout = m_context.GPipeline->GetMeshLayout()) + // { + // auto buffers = mesh_layout->GetBuffers(); + // for (u32 n = 0; n < buffers.size(); ++n) + // { + // const auto vb = m_context.Vbv[n]; + // if (!vb.IsEmpty()) MarkResUse(vb); + // } + // } + // continue; + // } + // Draw: + // { + // const auto& cmd = item.Draw; + // if (cmd.Pipeline != nullptr) SetPipelineContext(cmd.Pipeline, i); + // if (m_context.Pipeline == nullptr) + // COPLT_THROW_FMT("Pipeline not set at command {}", i); + // goto Graphics_MarkResUse; + // } + // Dispatch: + // { + // const auto& cmd = item.Dispatch; + // if (cmd.Pipeline != nullptr) SetPipelineContext(cmd.Pipeline, i); + // if (m_context.Pipeline == nullptr) + // COPLT_THROW_FMT("Pipeline not set at command {}", i); + // if (cmd.Type == FDispatchType::Mesh && m_context.GPipeline) goto Graphics_MarkResUse; + // continue; + // } } BarNext(); } @@ -344,41 +330,44 @@ void D3d12CommandInterpreter::Translate(const FCommandSubmit& submit) case FCommandType::None: case FCommandType::Present: continue; - case FCommandType::Transition: - goto Transition; + case FCommandType::Label: + COPLT_THROW("TODO"); + case FCommandType::BeginScope: + COPLT_THROW("TODO"); + case FCommandType::EndScope: + COPLT_THROW("TODO"); + case FCommandType::Barrier: + COPLT_THROW("TODO"); case FCommandType::ClearColor: goto ClearColor; case FCommandType::ClearDepthStencil: goto ClearDepthStencil; - case FCommandType::SetRenderTargets: - goto SetRenderTargets; - case FCommandType::SetViewportScissor: - goto SetViewportScissor; case FCommandType::Bind: goto Bind; + case FCommandType::BufferCopy: + goto BufferCopy; + case FCommandType::Render: + COPLT_THROW("TODO"); + case FCommandType::Compute: + COPLT_THROW("TODO"); + case FCommandType::End: case FCommandType::SetPipeline: - goto SetPipeline; + case FCommandType::SetBinding: + case FCommandType::SetViewportScissor: case FCommandType::SetMeshBuffers: - goto SetMeshBuffers; case FCommandType::Draw: - goto Draw; case FCommandType::Dispatch: - goto Dispatch; - case FCommandType::BufferCopy: - goto BufferCopy; + COPLT_THROW("Subcommands cannot be placed in the main command list"); } COPLT_THROW_FMT("Unknown command type {}", static_cast(item.Type)); - Transition: - COPLT_THROW("TODO"); - continue; ClearColor: { const auto& cmd = item.ClearColor; const auto rtv = GetRtv(cmd.Image.Get(submit)); cmd_pack->ClearRenderTargetView( rtv, cmd.Color, cmd.RectCount, - cmd.RectCount == 0 ? nullptr : reinterpret_cast(&submit.Payload[cmd.RectIndex]) + cmd.RectCount == 0 ? nullptr : reinterpret_cast(&submit.Rects[cmd.RectIndex]) ); continue; } @@ -391,141 +380,31 @@ void D3d12CommandInterpreter::Translate(const FCommandSubmit& submit) if (HasFlags(cmd.Clear, FDepthStencilClearFlags::Stencil)) flags |= D3D12_CLEAR_FLAG_STENCIL; cmd_pack->ClearDepthStencilView( dsv, flags, cmd.Depth, cmd.Stencil, cmd.RectCount, - cmd.RectCount == 0 ? nullptr : reinterpret_cast(&submit.Payload[cmd.RectIndex]) + cmd.RectCount == 0 ? nullptr : reinterpret_cast(&submit.Rects[cmd.RectIndex]) ); continue; } - SetRenderTargets: - { - const auto& cmd = item.SetRenderTargets; - auto dsv = nullptr; // todo - auto num_rtv = std::min(cmd.NumRtv, 8u); - D3D12_CPU_DESCRIPTOR_HANDLE rtvs[num_rtv]; - for (u32 n = 0; n < num_rtv; ++n) - { - rtvs[n] = GetRtv(cmd.Rtv[n].Get(submit)); - } - cmd_pack->OMSetRenderTargets(num_rtv, rtvs, false, dsv); - - auto viewport = reinterpret_cast(&submit.Payload[cmd.ViewportIndex]); - auto scissor = reinterpret_cast(&submit.Payload[cmd.ScissorRectIndex]); - if (cmd.ViewportCount > 0) cmd_pack->RSSetViewports(cmd.ViewportCount, viewport); - if (cmd.ScissorRectCount > 0) cmd_pack->RSSetScissorRects(cmd.ScissorRectCount, scissor); - continue; - } - SetViewportScissor: - { - const auto& cmd = item.SetViewportScissor; - auto viewport = reinterpret_cast(&submit.Payload[cmd.ViewportIndex]); - auto scissor = reinterpret_cast(&submit.Payload[cmd.ScissorRectIndex]); - if (cmd.ViewportCount > 0) cmd_pack->RSSetViewports(cmd.ViewportCount, viewport); - if (cmd.ScissorRectCount > 0) cmd_pack->RSSetScissorRects(cmd.ScissorRectCount, scissor); - continue; - } Bind: { const auto& cmd = item.Bind; // todo continue; } - SetPipeline: - { - const auto& cmd = item.SetPipeline; - SetPipeline(cmd_pack, cmd.Pipeline, i); - continue; - } - SetMeshBuffers: - { - const auto& cmd = item.SetMeshBuffers; - const auto defs = cmd.MeshLayout->GetBuffers(); - const auto vbs = reinterpret_cast(&submit.Payload[cmd.VertexBuffersIndex]); - if (!cmd.IndexBuffer.Buffer.IsEmpty()) - { - const auto resource = GetResource(cmd.IndexBuffer.Buffer.Get(submit)); - D3D12_INDEX_BUFFER_VIEW view{}; - view.BufferLocation = resource->GetGPUVirtualAddress() + cmd.IndexBuffer.Offset; - view.SizeInBytes = cmd.IndexBuffer.Size; - view.Format = Coplt::ToDx(cmd.IndexFormat); - cmd_pack->IASetIndexBuffer(&view); - } - { - D3D12_VERTEX_BUFFER_VIEW views[cmd.VertexBufferCount]; - for (u32 n = 0; n < cmd.VertexBufferCount; ++n) - { - auto& range = vbs[n]; - const auto& def = defs[range.Index]; - const auto resource = GetResource(range.Buffer.Get(submit)); - D3D12_VERTEX_BUFFER_VIEW view{}; - view.BufferLocation = resource->GetGPUVirtualAddress() + range.Offset; - view.SizeInBytes = range.Size; - view.StrideInBytes = def.Stride; - views[n] = view; - } - cmd_pack->IASetVertexBuffers(cmd.VertexStartSlot, cmd.VertexBufferCount, views); - } - continue; - } - Draw: - { - const auto& cmd = item.Draw; - if (cmd.Pipeline != nullptr) SetPipeline(cmd_pack, cmd.Pipeline, i); - if (m_context.Pipeline == nullptr) - COPLT_THROW_FMT("Pipeline not set at command {}", i); - const auto stages = m_context.Pipeline->GetStages(); - if (!HasFlags(stages, FShaderStageFlags::Vertex)) - COPLT_THROW("Non Vertex pipelines cannot use Draw"); - if (cmd.Indexed) - { - cmd_pack->DrawIndexedInstanced( - cmd.VertexOrIndexCount, cmd.InstanceCount, - cmd.FirstVertexOrIndex, cmd.VertexOffset, cmd.FirstInstance - ); - } - else - { - cmd_pack->DrawInstanced( - cmd.VertexOrIndexCount, cmd.InstanceCount, - cmd.FirstVertexOrIndex, cmd.FirstInstance - ); - } - continue; - } - Dispatch: - { - const auto& cmd = item.Dispatch; - if (cmd.Pipeline != nullptr) SetPipeline(cmd_pack, cmd.Pipeline, i); - FShaderStageFlags stages{}; - switch (cmd.Type) - { - case FDispatchType::Compute: - cmd_pack->Dispatch(cmd.GroupCountX, cmd.GroupCountY, cmd.GroupCountZ); - break; - case FDispatchType::Mesh: - if (!cmd_pack.m_list7) - COPLT_THROW("Mesh Shader is not supported on this device"); - cmd_pack.m_list7->DispatchMesh(cmd.GroupCountX, cmd.GroupCountY, cmd.GroupCountZ); - break; - default: - COPLT_THROW_FMT( - "Unknown dispatch type {} at command {}", static_cast(cmd.Type), i - ); - } - continue; - } BufferCopy: { const auto& cmd = item.BufferCopy; + const auto& range = submit.BufferCopyRanges[cmd.RangeIndex]; if (cmd.SrcType == FBufferRefType::Buffer && cmd.DstType == FBufferRefType::Buffer) { const auto dst = GetResource(cmd.Dst.Buffer.Get(submit)); const auto src = GetResource(cmd.Src.Buffer.Get(submit)); - if (cmd.Size == std::numeric_limits::max()) + if (range.Size == std::numeric_limits::max()) { cmd_pack->CopyResource(dst, src); } else { - cmd_pack->CopyBufferRegion(dst, cmd.DstOffset, src, cmd.SrcOffset, cmd.Size); + cmd_pack->CopyBufferRegion(dst, range.DstOffset, src, range.SrcOffset, range.Size); } } else if (cmd.SrcType == FBufferRefType::Upload && cmd.DstType == FBufferRefType::Buffer) @@ -534,10 +413,10 @@ void D3d12CommandInterpreter::Translate(const FCommandSubmit& submit) if (cmd.Src.Upload.Index >= m_queue->m_frame_context->m_upload_buffers.size()) COPLT_THROW_FMT("Index out of bounds at command {}", i); const auto& src_obj = m_queue->m_frame_context->m_upload_buffers[cmd.Src.Upload.Index]; - if (cmd.SrcOffset + cmd.Size >= src_obj.m_size) + if (range.SrcOffset + range.Size >= src_obj.m_size) COPLT_THROW_FMT("Size out of range at command {}", i); const auto src = src_obj.m_resource.m_resource.Get(); - cmd_pack->CopyBufferRegion(dst, cmd.DstOffset, src, cmd.SrcOffset, cmd.Size); + cmd_pack->CopyBufferRegion(dst, range.DstOffset, src, range.SrcOffset, range.Size); } else { @@ -548,6 +427,117 @@ void D3d12CommandInterpreter::Translate(const FCommandSubmit& submit) } continue; } + // SetRenderTargets: + // { + // const auto& cmd = item.SetRenderTargets; + // auto dsv = nullptr; // todo + // auto num_rtv = std::min(cmd.NumRtv, 8u); + // D3D12_CPU_DESCRIPTOR_HANDLE rtvs[num_rtv]; + // for (u32 n = 0; n < num_rtv; ++n) + // { + // rtvs[n] = GetRtv(cmd.Rtv[n].Get(submit)); + // } + // cmd_pack->OMSetRenderTargets(num_rtv, rtvs, false, dsv); + // + // auto viewport = reinterpret_cast(&submit.Payload[cmd.ViewportIndex]); + // auto scissor = reinterpret_cast(&submit.Payload[cmd.ScissorRectIndex]); + // if (cmd.ViewportCount > 0) cmd_pack->RSSetViewports(cmd.ViewportCount, viewport); + // if (cmd.ScissorRectCount > 0) cmd_pack->RSSetScissorRects(cmd.ScissorRectCount, scissor); + // continue; + // } + // SetViewportScissor: + // { + // const auto& cmd = item.SetViewportScissor; + // auto viewport = reinterpret_cast(&submit.Payload[cmd.ViewportIndex]); + // auto scissor = reinterpret_cast(&submit.Payload[cmd.ScissorRectIndex]); + // if (cmd.ViewportCount > 0) cmd_pack->RSSetViewports(cmd.ViewportCount, viewport); + // if (cmd.ScissorRectCount > 0) cmd_pack->RSSetScissorRects(cmd.ScissorRectCount, scissor); + // continue; + // } + // SetPipeline: + // { + // const auto& cmd = item.SetPipeline; + // SetPipeline(cmd_pack, cmd.Pipeline, i); + // continue; + // } + // SetMeshBuffers: + // { + // const auto& cmd = item.SetMeshBuffers; + // const auto defs = cmd.MeshLayout->GetBuffers(); + // const auto vbs = reinterpret_cast(&submit.Payload[cmd.VertexBuffersIndex]); + // if (!cmd.IndexBuffer.Buffer.IsEmpty()) + // { + // const auto resource = GetResource(cmd.IndexBuffer.Buffer.Get(submit)); + // D3D12_INDEX_BUFFER_VIEW view{}; + // view.BufferLocation = resource->GetGPUVirtualAddress() + cmd.IndexBuffer.Offset; + // view.SizeInBytes = cmd.IndexBuffer.Size; + // view.Format = Coplt::ToDx(cmd.IndexFormat); + // cmd_pack->IASetIndexBuffer(&view); + // } + // { + // D3D12_VERTEX_BUFFER_VIEW views[cmd.VertexBufferCount]; + // for (u32 n = 0; n < cmd.VertexBufferCount; ++n) + // { + // auto& range = vbs[n]; + // const auto& def = defs[range.Index]; + // const auto resource = GetResource(range.Buffer.Get(submit)); + // D3D12_VERTEX_BUFFER_VIEW view{}; + // view.BufferLocation = resource->GetGPUVirtualAddress() + range.Offset; + // view.SizeInBytes = range.Size; + // view.StrideInBytes = def.Stride; + // views[n] = view; + // } + // cmd_pack->IASetVertexBuffers(cmd.VertexStartSlot, cmd.VertexBufferCount, views); + // } + // continue; + // } + // Draw: + // { + // const auto& cmd = item.Draw; + // if (cmd.Pipeline != nullptr) SetPipeline(cmd_pack, cmd.Pipeline, i); + // if (m_context.Pipeline == nullptr) + // COPLT_THROW_FMT("Pipeline not set at command {}", i); + // const auto stages = m_context.Pipeline->GetStages(); + // if (!HasFlags(stages, FShaderStageFlags::Vertex)) + // COPLT_THROW("Non Vertex pipelines cannot use Draw"); + // if (cmd.Indexed) + // { + // cmd_pack->DrawIndexedInstanced( + // cmd.VertexOrIndexCount, cmd.InstanceCount, + // cmd.FirstVertexOrIndex, cmd.VertexOffset, cmd.FirstInstance + // ); + // } + // else + // { + // cmd_pack->DrawInstanced( + // cmd.VertexOrIndexCount, cmd.InstanceCount, + // cmd.FirstVertexOrIndex, cmd.FirstInstance + // ); + // } + // continue; + // } + // Dispatch: + // { + // const auto& cmd = item.Dispatch; + // if (cmd.Pipeline != nullptr) SetPipeline(cmd_pack, cmd.Pipeline, i); + // FShaderStageFlags stages{}; + // switch (cmd.Type) + // { + // case FDispatchType::Compute: + // cmd_pack->Dispatch(cmd.GroupCountX, cmd.GroupCountY, cmd.GroupCountZ); + // break; + // case FDispatchType::Mesh: + // if (!cmd_pack.m_list7) + // COPLT_THROW("Mesh Shader is not supported on this device"); + // cmd_pack.m_list7->DispatchMesh(cmd.GroupCountX, cmd.GroupCountY, cmd.GroupCountZ); + // break; + // default: + // COPLT_THROW_FMT( + // "Unknown dispatch type {} at command {}", static_cast(cmd.Type), i + // ); + // } + // continue; + // } } } } diff --git a/Coplt.Graphics.Native/D3d12/Src/Command.h b/Coplt.Graphics.Native/D3d12/Src/Command.h index 5116d6a..662a474 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Command.h +++ b/Coplt.Graphics.Native/D3d12/Src/Command.h @@ -63,8 +63,8 @@ namespace Coplt FResourceRef Rtv[8]; u32 NumRtv{}; - FResourceRef Dsv{COPLT_U32_MAX}; - FResourceRef Ibv{COPLT_U32_MAX}; + FResourceRef Dsv{}; + FResourceRef Ibv{}; FResourceRef Vbv[31]; u32 NumVbv{}; diff --git a/Coplt.Graphics.Native/D3d12/Src/Executor.h b/Coplt.Graphics.Native/D3d12/Src/Executor.h new file mode 100644 index 0000000..dce292c --- /dev/null +++ b/Coplt.Graphics.Native/D3d12/Src/Executor.h @@ -0,0 +1,14 @@ +#pragma once + +#include "../../Api/FFI/Executor.h" + +namespace Coplt +{ + struct D3d12GpuQueue; + + COPLT_INTERFACE_DEFINE(ID3d12GpuExecutor, "f9b5793d-b6e9-4b7e-8953-5fa07b815010", FGpuExecutor) + { + virtual void Submit(D3d12GpuQueue* Queue, const FCommandSubmit* submit) = 0; + virtual void SubmitNoWait(D3d12GpuQueue* Queue, const FCommandSubmit* submit) = 0; + }; +} diff --git a/Coplt.Graphics.Native/D3d12/Src/Output.cc b/Coplt.Graphics.Native/D3d12/Src/Output.cc index 0e48f5f..e827c0f 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Output.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Output.cc @@ -214,34 +214,32 @@ FResult D3d12GpuSwapChainOutput::Resize(const u32 Width, const u32 Height) noexc }); } -FResult D3d12GpuSwapChainOutput::Present(/* 可选 */ const FCommandSubmit* submit) noexcept +FResult D3d12GpuSwapChainOutput::Wait() noexcept { return feb([&] { std::lock_guard lock(m_queue->m_mutex); - Submit_NoLock(submit); - Present_NoLock(); WaitNextFrame_NoLock(); }); } -FResult D3d12GpuSwapChainOutput::PresentNoWait(/* 可选 */ const FCommandSubmit* submit) noexcept +void D3d12GpuSwapChainOutput::Submit(D3d12GpuQueue* Queue, const FCommandSubmit* submit) { - return feb([&] - { - std::lock_guard lock(m_queue->m_mutex); - Submit_NoLock(submit); - Present_NoLock(); - }); + if (Queue != m_queue) + COPLT_THROW("The executor does not belong to this queue"); + std::lock_guard lock(m_queue->m_mutex); + Submit_NoLock(submit); + Present_NoLock(); + WaitNextFrame_NoLock(); } -FResult D3d12GpuSwapChainOutput::WaitNextFrame() noexcept +void D3d12GpuSwapChainOutput::SubmitNoWait(D3d12GpuQueue* Queue, const FCommandSubmit* submit) { - return feb([&] - { - std::lock_guard lock(m_queue->m_mutex); - WaitNextFrame_NoLock(); - }); + if (Queue != m_queue) + COPLT_THROW("The executor does not belong to this queue"); + std::lock_guard lock(m_queue->m_mutex); + Submit_NoLock(submit); + Present_NoLock(); } void D3d12GpuSwapChainOutput::Submit_NoLock(const FCommandSubmit* submit) diff --git a/Coplt.Graphics.Native/D3d12/Src/Output.h b/Coplt.Graphics.Native/D3d12/Src/Output.h index 231395e..471d87b 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Output.h +++ b/Coplt.Graphics.Native/D3d12/Src/Output.h @@ -4,6 +4,7 @@ #include #include "Context.h" +#include "Executor.h" #include "Queue.h" #include "../FFI/Output.h" #include "../../Api/Include/Object.h" @@ -12,7 +13,7 @@ namespace Coplt { struct D3d12GpuDevice; - struct D3d12GpuSwapChainOutput final : Object + struct D3d12GpuSwapChainOutput final : Object { constexpr static UINT MaxBufferCount = 3; @@ -61,9 +62,10 @@ namespace Coplt FResult Resize(u32 Width, u32 Height) noexcept override; - FResult Present(/* 可选 */ const FCommandSubmit* submit) noexcept override; - FResult PresentNoWait(/* 可选 */ const FCommandSubmit* submit) noexcept override; - FResult WaitNextFrame() noexcept override; + FResult Wait() noexcept override; + + void Submit(D3d12GpuQueue* Queue, const FCommandSubmit* submit) override; + void SubmitNoWait(D3d12GpuQueue* Queue, const FCommandSubmit* submit) override; void Submit_NoLock(/* 可选 */ const FCommandSubmit* submit); void Present_NoLock(); diff --git a/Coplt.Graphics.Native/D3d12/Src/Queue.cc b/Coplt.Graphics.Native/D3d12/Src/Queue.cc index 1a22f12..02644e3 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Queue.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Queue.cc @@ -114,3 +114,25 @@ void D3d12GpuQueue::SubmitNoLock( m_context = m_frame_context.get(); m_submit_id++; } + +FResult D3d12GpuQueue::Submit(FGpuExecutor* Executor, const FCommandSubmit* submit) noexcept +{ + return feb([&] + { + const auto executor = Executor->QueryInterface(); + if (executor == nullptr) + COPLT_THROW("Executors from different backends"); + executor->Submit(this, submit); + }); +} + +FResult D3d12GpuQueue::SubmitNoWait(FGpuExecutor* Executor, const FCommandSubmit* submit) noexcept +{ + return feb([&] + { + const auto executor = Executor->QueryInterface(); + if (executor == nullptr) + COPLT_THROW("Executors from different backends"); + executor->SubmitNoWait(this, submit); + }); +} diff --git a/Coplt.Graphics.Native/D3d12/Src/Queue.h b/Coplt.Graphics.Native/D3d12/Src/Queue.h index a9c759f..4208ae3 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Queue.h +++ b/Coplt.Graphics.Native/D3d12/Src/Queue.h @@ -9,6 +9,7 @@ #include "../../Api/Include/Object.h" #include "../FFI/Queue.h" #include "Command.h" +#include "Executor.h" namespace Coplt { @@ -49,6 +50,9 @@ namespace Coplt void Submit(Rc& frame_context, /* 可选 */ const FCommandSubmit* submit); // 提交命令,并互换帧上下文,但是无锁,需要外部手动锁,参数提供的帧上下文必须可用 void SubmitNoLock(Rc& frame_context, /* 可选 */ const FCommandSubmit* submit); + + FResult Submit(FGpuExecutor* Executor, const FCommandSubmit* submit) noexcept override; + FResult SubmitNoWait(FGpuExecutor* Executor, const FCommandSubmit* submit) noexcept override; }; inline D3D12_COMMAND_LIST_TYPE ToDx(const FGpuQueueType value) diff --git a/Examples/Colorful/Example.cs b/Examples/Colorful/Example.cs index 93b0299..87b3397 100644 --- a/Examples/Colorful/Example.cs +++ b/Examples/Colorful/Example.cs @@ -61,8 +61,7 @@ protected override async Task LoadResources(CommandList cmd) protected override void Render(CommandList cmd, Time time) { cmd.Upload(ArgBuffer, [(float)time.Total.TotalSeconds]); - cmd.SetRenderTargets([Output]); - cmd.ClearColor(Output, new float4(0.83f, 0.8f, 0.97f, 1f)); - cmd.Draw(Pipeline, 4); + using var render = cmd.Render([new(Output, new float4(0.83f, 0.8f, 0.97f, 1f))]); + render.Draw(Pipeline, 4); } } diff --git a/Examples/HelloTriangle/Example.cs b/Examples/HelloTriangle/Example.cs index c37d141..4729064 100644 --- a/Examples/HelloTriangle/Example.cs +++ b/Examples/HelloTriangle/Example.cs @@ -9,7 +9,7 @@ public class Example(IntPtr Handle, uint Width, uint Height) : ExampleBase(Handl { private Shader Shader = null!; private GraphicsShaderPipeline Pipeline = null!; - + public override string Name => "Hello Triangle"; protected override async Task LoadResources(CommandList cmd) { @@ -33,8 +33,7 @@ protected override async Task LoadResources(CommandList cmd) } protected override void Render(CommandList cmd, Time time) { - cmd.SetRenderTargets([Output]); - cmd.ClearColor(Output, new float4(0.83f, 0.8f, 0.97f, 1f)); - cmd.Draw(Pipeline, 3); + using var render = cmd.Render([new(Output, new float4(0.83f, 0.8f, 0.97f, 1f))]); + render.Draw(Pipeline, 3); } } diff --git a/Examples/HelloTriangleVertex/Example.cs b/Examples/HelloTriangleVertex/Example.cs index ac2ee04..c1bb277 100644 --- a/Examples/HelloTriangleVertex/Example.cs +++ b/Examples/HelloTriangleVertex/Example.cs @@ -84,14 +84,13 @@ protected override async Task LoadResources(CommandList cmd) } protected override void Render(CommandList cmd, Time time) { - cmd.SetRenderTargets([Output]); - cmd.ClearColor(Output, new float4(0.83f, 0.8f, 0.97f, 1f)); - cmd.SetMeshBuffers( + using var render = cmd.Render([new(Output, new float4(0.83f, 0.8f, 0.97f, 1f))]); + render.SetMeshBuffers( MeshLayout, [ new(0, PositionColorBuffer), new(1, UvBuffer), ] ); - cmd.Draw(Pipeline, 3); + render.Draw(Pipeline, 3); } } From b1ed7ccaf284bac8d1b3a49941392b2388f311be Mon Sep 17 00:00:00 2001 From: U2A5F Date: Wed, 26 Feb 2025 22:41:00 +0800 Subject: [PATCH 11/23] save --- Coplt.Graphics.Core/Core/CommandList.cs | 78 ++++++------------------- Coplt.Graphics.Core/Core/GpuExecutor.cs | 44 +++++++++++++- Coplt.Graphics.Core/Core/GpuQueue.cs | 32 +++++++--- Coplt.Graphics.Core/Native/Native.cs | 9 +++ Coplt.Graphics.Native/Api/FFI/States.h | 10 ++++ Examples/Colorful/Example.cs | 7 ++- 6 files changed, 108 insertions(+), 72 deletions(-) diff --git a/Coplt.Graphics.Core/Core/CommandList.cs b/Coplt.Graphics.Core/Core/CommandList.cs index b045400..2c4f7a7 100644 --- a/Coplt.Graphics.Core/Core/CommandList.cs +++ b/Coplt.Graphics.Core/Core/CommandList.cs @@ -7,13 +7,6 @@ namespace Coplt.Graphics.Core; -[Flags] -public enum CommandFlags : uint -{ - None = 0, - DontTransition = 1 << 0, -} - public enum DispatchType : byte { Auto, @@ -87,7 +80,7 @@ internal void Reset() #region Submit - internal void Submit(GpuQueue Queue, GpuExecutor Executor, bool NoWait) + internal void BuildSubmitStruct(GpuExecutor Executor, bool NoWait) { fixed (FCommandItem* p_commands = CollectionsMarshal.AsSpan(m_commands)) fixed (FRenderCommandItem* p_render_commands = CollectionsMarshal.AsSpan(m_render_commands)) @@ -123,15 +116,7 @@ internal void Submit(GpuQueue Queue, GpuExecutor Executor, bool NoWait) CommandCount = (uint)m_commands.Count, ResourceCount = (uint)m_resource_metas.Count, }; - try - { - if (NoWait) Queue.m_ptr->SubmitNoWait(Executor.m_ptr, &submit).TryThrow(); - else Queue.m_ptr->Submit(Executor.m_ptr, &submit).TryThrow(); - } - finally - { - Reset(); - } + Queue.ActualSubmit(Executor, &submit, NoWait); } } @@ -257,7 +242,7 @@ public DebugScope Scope(ReadOnlySpan Name) #region Present - internal void Present(GpuOutput Output, CommandFlags Flags = CommandFlags.None) + internal void Present(GpuOutput Output) { var cmd = new FCommandPresent { @@ -265,8 +250,6 @@ internal void Present(GpuOutput Output, CommandFlags Flags = CommandFlags.None) Image = AddResource(Output), }; m_commands.Add(new() { Present = cmd }); - if ((Flags & CommandFlags.DontTransition) == 0) - Output.UnsafeChangeState(FResourceState.Present); } #endregion @@ -277,16 +260,14 @@ internal void Present(GpuOutput Output, CommandFlags Flags = CommandFlags.None) /// 使用 (0, 0, 0, 1) 清空 Rtv /// public void ClearColor( - Rtv Image, ReadOnlySpan Rects = default, - CommandFlags Flags = CommandFlags.None - ) where Rtv : IRtvRes => ClearColor(Image, new(0, 0, 0, 1), Rects, Flags); + Rtv Image, ReadOnlySpan Rects = default + ) where Rtv : IRtvRes => ClearColor(Image, new(0, 0, 0, 1), Rects); /// /// 使用指定的颜色清空 Rtv /// public void ClearColor( - Rtv Image, float4 Color, ReadOnlySpan Rects = default, - CommandFlags Flags = CommandFlags.None + Rtv Image, float4 Color, ReadOnlySpan Rects = default ) where Rtv : IRtvRes { if (!Image.TryRtv()) throw new ArgumentException($"Resource {Image} cannot be used as Rtv"); @@ -304,8 +285,6 @@ public void ClearColor( m_rects.AddRange(MemoryMarshal.Cast(Rects)); } m_commands.Add(new() { ClearColor = cmd }); - if ((Flags & CommandFlags.DontTransition) == 0) - Image.UnsafeChangeState(FResourceState.RenderTarget); } #endregion @@ -317,35 +296,31 @@ public void ClearColor( /// public void ClearDepthStencil( Dsv Image, - ReadOnlySpan Rects = default, - CommandFlags Flags = CommandFlags.None - ) where Dsv : IDsvRes => ClearDepthStencil(Image, 1, 0, DsvClear.All, Rects, Flags); + ReadOnlySpan Rects = default + ) where Dsv : IDsvRes => ClearDepthStencil(Image, 1, 0, DsvClear.All, Rects); /// /// 使用指定的深度清空 Dsv /// public void ClearDepthStencil( Dsv Image, float Depth, - ReadOnlySpan Rects = default, - CommandFlags Flags = CommandFlags.None - ) where Dsv : IDsvRes => ClearDepthStencil(Image, Depth, 0, DsvClear.Depth, Rects, Flags); + ReadOnlySpan Rects = default + ) where Dsv : IDsvRes => ClearDepthStencil(Image, Depth, 0, DsvClear.Depth, Rects); /// /// 使用指定的模板清空 Dsv /// public void ClearDepthStencil( Dsv Image, byte Stencil, - ReadOnlySpan Rects = default, - CommandFlags Flags = CommandFlags.None - ) where Dsv : IDsvRes => ClearDepthStencil(Image, 1, Stencil, DsvClear.Stencil, Rects, Flags); + ReadOnlySpan Rects = default + ) where Dsv : IDsvRes => ClearDepthStencil(Image, 1, Stencil, DsvClear.Stencil, Rects); /// /// 使用指定的深度和模板清空 Dsv /// public void ClearDepthStencil( Dsv Image, float Depth, byte Stencil, DsvClear Clear = DsvClear.All, - ReadOnlySpan Rects = default, - CommandFlags Flags = CommandFlags.None + ReadOnlySpan Rects = default ) where Dsv : IDsvRes { if (!Image.TryDsv()) throw new ArgumentException($"Resource {Image} cannot be used as Dsv"); @@ -365,8 +340,6 @@ public void ClearDepthStencil( m_rects.AddRange(MemoryMarshal.Cast(Rects)); } m_commands.Add(new() { ClearDepthStencil = cmd }); - if ((Flags & CommandFlags.DontTransition) == 0) - Image.UnsafeChangeState(FResourceState.DepthWrite); } #endregion @@ -374,7 +347,7 @@ public void ClearDepthStencil( #region Bind public void Bind( - ShaderBinding Binding, ReadOnlySpan Items, CommandFlags Flags = CommandFlags.None + ShaderBinding Binding, ReadOnlySpan Items ) { AddObject(Binding); @@ -418,8 +391,7 @@ public void Copy( GpuBuffer Src, ulong DstOffset = 0, ulong SrcOffset = 0, - ulong Size = ulong.MaxValue, - CommandFlags Flags = CommandFlags.None + ulong Size = ulong.MaxValue ) { if (Size != ulong.MaxValue) @@ -446,11 +418,6 @@ public void Copy( } ); m_commands.Add(new() { BufferCopy = cmd }); - if ((Flags & CommandFlags.DontTransition) == 0) - { - Dst.UnsafeChangeState(FResourceState.CopyDst); - Src.UnsafeChangeState(FResourceState.CopySrc); - } } #endregion @@ -460,15 +427,13 @@ public void Copy( public void Upload( GpuBuffer Dst, ReadOnlySpan Data, - ulong DstOffset = 0, - CommandFlags Flags = CommandFlags.None - ) where T : unmanaged => Upload(Dst, MemoryMarshal.AsBytes(Data), DstOffset, Flags); + ulong DstOffset = 0 + ) where T : unmanaged => Upload(Dst, MemoryMarshal.AsBytes(Data), DstOffset); public void Upload( GpuBuffer Dst, ReadOnlySpan Data, - ulong DstOffset = 0, - CommandFlags Flags = CommandFlags.None + ulong DstOffset = 0 ) { if (Data.Length == 0) return; @@ -492,15 +457,12 @@ public void Upload( } ); m_commands.Add(new() { BufferCopy = cmd }); - if ((Flags & CommandFlags.DontTransition) == 0) - Dst.UnsafeChangeState(FResourceState.CopyDst); } public void Upload( GpuBuffer Dst, UploadLoc Loc, - ulong DstOffset = 0, - CommandFlags Flags = CommandFlags.None + ulong DstOffset = 0 ) { if (Loc.SubmitId != m_queue.SubmitId) @@ -524,8 +486,6 @@ public void Upload( } ); m_commands.Add(new() { BufferCopy = cmd }); - if ((Flags & CommandFlags.DontTransition) == 0) - Dst.UnsafeChangeState(FResourceState.CopyDst); } #endregion diff --git a/Coplt.Graphics.Core/Core/GpuExecutor.cs b/Coplt.Graphics.Core/Core/GpuExecutor.cs index 3a8d037..3cb245e 100644 --- a/Coplt.Graphics.Core/Core/GpuExecutor.cs +++ b/Coplt.Graphics.Core/Core/GpuExecutor.cs @@ -11,6 +11,8 @@ public abstract unsafe partial class GpuExecutor internal FGpuExecutor* m_ptr; internal string? m_name; internal readonly GpuQueue m_queue; + internal CommandList? m_recycle_cmd_list; + internal readonly Lock m_wait_lock = new(); #endregion @@ -20,6 +22,8 @@ public abstract unsafe partial class GpuExecutor public GpuDevice Device => m_queue.m_device; public GpuQueue Queue => m_queue; + public bool NeedWait => m_recycle_cmd_list != null; + #endregion #region Ctor @@ -38,6 +42,7 @@ internal GpuExecutor(FGpuExecutor* ptr, string? name, GpuQueue queue) [Drop] private void Drop() { + Wait(true); if (ExchangeUtils.ExchangePtr(ref m_ptr, null, out var ptr) is null) return; ptr->Release(); } @@ -77,15 +82,48 @@ m_name is null #endregion + #region SetNeedWait + + internal void SetNeedWait(CommandList cmd) + { + if (Interlocked.CompareExchange(ref m_recycle_cmd_list, cmd, null) != null) + throw new InvalidOperationException("The current executor has not been waited and cannot be reused"); + } + + #endregion + #region Wait /// /// 等待可重用 /// - public void Wait() + public void Wait() => Wait(false); + + /// + /// 等待可重用 + /// + private void Wait(bool discard) { - using var _ = Queue.m_lock.EnterScope(); - m_ptr->Wait().TryThrow(); + re: + var recycle_cmd_list = m_recycle_cmd_list; + if (recycle_cmd_list == null) return; + using (m_wait_lock.EnterScope()) + { + if (recycle_cmd_list == m_recycle_cmd_list) goto re; + try + { + m_ptr->Wait().TryThrow(); + } + finally + { + if (!discard) + { + recycle_cmd_list.Reset(); + Queue.m_cmd_pool.Enqueue(recycle_cmd_list); + } + m_recycle_cmd_list = null; + } + } } #endregion diff --git a/Coplt.Graphics.Core/Core/GpuQueue.cs b/Coplt.Graphics.Core/Core/GpuQueue.cs index cf4321c..fd5564c 100644 --- a/Coplt.Graphics.Core/Core/GpuQueue.cs +++ b/Coplt.Graphics.Core/Core/GpuQueue.cs @@ -1,4 +1,5 @@ -using Coplt.Dropping; +using System.Collections.Concurrent; +using Coplt.Dropping; using Coplt.Graphics.Native; namespace Coplt.Graphics.Core; @@ -26,7 +27,8 @@ public sealed unsafe partial class GpuQueue internal string? m_name; internal readonly GpuDevice m_device; internal readonly Lock m_lock = new(); - internal readonly CommandList m_cmd; + internal CommandList m_current_cmd_list; + internal readonly ConcurrentQueue m_cmd_pool = new(); #endregion @@ -36,7 +38,7 @@ public sealed unsafe partial class GpuQueue public GpuDevice Device => m_device; public GpuQueueType QueueType => m_ptr->m_queue_type.FromFFI(); public SubmitId SubmitId => new(m_ptr->m_submit_id); - public CommandList CommandList => m_cmd; + public CommandList CommandList => m_current_cmd_list; #endregion @@ -47,7 +49,7 @@ internal GpuQueue(FGpuQueue* ptr, string? name, GpuDevice device) m_name = name; m_ptr = ptr; m_device = device; - m_cmd = new(this); + m_current_cmd_list = new(this); } #endregion @@ -104,13 +106,29 @@ public void Submit(GpuExecutor Executor, bool NoWait = false) using var _ = m_lock.EnterScope(); if (Executor is GpuOutput output) { - if (m_cmd.m_current_output != null && m_cmd.m_current_output != output) + if (m_current_cmd_list.m_current_output != null && m_current_cmd_list.m_current_output != output) throw new ArgumentException( $"The command is already used by another output and cannot be presented in this output" ); - m_cmd.Present(output); + m_current_cmd_list.Present(output); + } + m_current_cmd_list.BuildSubmitStruct(Executor, NoWait); + } + + internal void ActualSubmit(GpuExecutor Executor, FCommandSubmit* submit, bool NoWait) + { + if (NoWait) + { + m_ptr->SubmitNoWait(Executor.m_ptr, submit).TryThrow(); + if (!m_cmd_pool.TryDequeue(out var new_cmd_list)) new_cmd_list = new(this); + Executor.SetNeedWait(m_current_cmd_list); + m_current_cmd_list = new_cmd_list; + } + else + { + m_ptr->Submit(Executor.m_ptr, submit).TryThrow(); + m_current_cmd_list.Reset(); } - m_cmd.Submit(this, Executor, NoWait); } #endregion diff --git a/Coplt.Graphics.Core/Native/Native.cs b/Coplt.Graphics.Core/Native/Native.cs index 0d6a39a..49112ec 100644 --- a/Coplt.Graphics.Core/Native/Native.cs +++ b/Coplt.Graphics.Core/Native/Native.cs @@ -2325,6 +2325,15 @@ public enum FGraphicsFormat BC7_UNorm_sRGB = 99, } + [NativeTypeName("Coplt::u32")] + public enum FResLayout : uint + { + } + + public partial struct FResState + { + } + [NativeTypeName("Coplt::u32")] public enum FResourceState : uint { diff --git a/Coplt.Graphics.Native/Api/FFI/States.h b/Coplt.Graphics.Native/Api/FFI/States.h index f218663..e42afc3 100644 --- a/Coplt.Graphics.Native/Api/FFI/States.h +++ b/Coplt.Graphics.Native/Api/FFI/States.h @@ -5,6 +5,16 @@ namespace Coplt { + COPLT_ENUM_FLAGS(FResLayout, u32) + { + + }; + + struct FResState + { + + }; + COPLT_ENUM_FLAGS(FResourceState, u32) { // 手动管理资源状态,自动过渡时将忽略 diff --git a/Examples/Colorful/Example.cs b/Examples/Colorful/Example.cs index 87b3397..db404b7 100644 --- a/Examples/Colorful/Example.cs +++ b/Examples/Colorful/Example.cs @@ -60,8 +60,9 @@ protected override async Task LoadResources(CommandList cmd) } protected override void Render(CommandList cmd, Time time) { - cmd.Upload(ArgBuffer, [(float)time.Total.TotalSeconds]); - using var render = cmd.Render([new(Output, new float4(0.83f, 0.8f, 0.97f, 1f))]); - render.Draw(Pipeline, 4); + cmd.ClearColor(Output, new float4(0.83f, 0.8f, 0.97f, 1f)); + // cmd.Upload(ArgBuffer, [(float)time.Total.TotalSeconds]); + // using var render = cmd.Render([new(Output, new float4(0.83f, 0.8f, 0.97f, 1f))]); + // render.Draw(Pipeline, 4); } } From ba0777f8d75f568db107a78841c2086db5a7d8ec Mon Sep 17 00:00:00 2001 From: U2A5F Date: Thu, 27 Feb 2025 16:36:56 +0800 Subject: [PATCH 12/23] save --- .clang-format | 55 +++++++ .idea/codeStyles/Project.xml | 3 + .idea/editor.xml | 1 + Coplt.Graphics.Core/Core/GpuBuffer.cs | 4 +- Coplt.Graphics.Core/Core/GpuOutput.cs | 4 +- Coplt.Graphics.Core/Core/GpuResource.cs | 2 +- Coplt.Graphics.Core/Core/LegacyState.cs | 63 ++++++++ Coplt.Graphics.Core/Core/ResourceState.cs | 63 -------- Coplt.Graphics.Core/Core/Views.cs | 2 +- Coplt.Graphics.Core/Native/Native.cs | 159 +++++++++++++++++-- Coplt.Graphics.Native/Api/CMakeLists.txt | 1 + Coplt.Graphics.Native/Api/FFI/Command.h | 2 +- Coplt.Graphics.Native/Api/FFI/Features.h | 38 +++++ Coplt.Graphics.Native/Api/FFI/Output.h | 2 +- Coplt.Graphics.Native/Api/FFI/Resource.h | 2 +- Coplt.Graphics.Native/Api/FFI/States.h | 136 +++++++++++++--- Coplt.Graphics.Native/D3d12/Include/States.h | 36 ++--- Coplt.Graphics.Native/D3d12/Src/Buffer.cc | 2 +- Coplt.Graphics.Native/D3d12/Src/Command.cc | 16 +- Coplt.Graphics.Native/D3d12/Src/Command.h | 8 +- Coplt.Graphics.Native/D3d12/Src/Output.cc | 2 +- Coplt.Graphics.Native/D3d12/Src/Resource.cc | 8 +- Coplt.Graphics.Native/D3d12/Src/Resource.h | 4 +- 23 files changed, 461 insertions(+), 152 deletions(-) create mode 100644 .clang-format create mode 100644 Coplt.Graphics.Core/Core/LegacyState.cs delete mode 100644 Coplt.Graphics.Core/Core/ResourceState.cs create mode 100644 Coplt.Graphics.Native/Api/FFI/Features.h diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..5052497 --- /dev/null +++ b/.clang-format @@ -0,0 +1,55 @@ +--- +Language: Cpp +BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignOperands: false +AlignTrailingComments: false +AlwaysBreakTemplateDeclarations: Yes +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: false + BeforeCatch: true + BeforeElse: true + BeforeLambdaBody: true + BeforeWhile: true + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBraces: Custom +BreakConstructorInitializers: AfterColon +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 120 +ConstructorInitializerAllOnOneLineOrOnePerLine: false +IncludeCategories: + - Regex: '^<.*' + Priority: 1 + - Regex: '^".*' + Priority: 2 + - Regex: '.*' + Priority: 3 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IndentCaseBlocks: true +IndentPPDirectives: BeforeHash +IndentWidth: 4 +InsertNewlineAtEOF: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: All +PointerAlignment: Left +SpaceInEmptyParentheses: false +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +TabWidth: 4 +... diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 49f96f4..78cf9ef 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,5 +1,8 @@ + + diff --git a/.idea/editor.xml b/.idea/editor.xml index b0d69ef..4cf5e8f 100644 --- a/.idea/editor.xml +++ b/.idea/editor.xml @@ -1,6 +1,7 @@ + \ No newline at end of file diff --git a/Coplt.Graphics.Core/Core/DeviceRequires.cs b/Coplt.Graphics.Core/Core/DeviceRequires.cs new file mode 100644 index 0000000..59ce7a3 --- /dev/null +++ b/Coplt.Graphics.Core/Core/DeviceRequires.cs @@ -0,0 +1,143 @@ +using Coplt.Graphics.Native; + +namespace Coplt.Graphics.Core; + +public enum D3dFeatureLevel +{ + Unset = 0, + _12_1 = 0xc100, + _12_2 = 0xc200, +} + +public enum VulkanVersion +{ + Unset = 0, + _1_2 = 1002, + _1_3 = 1003, + _1_4 = 1004, +} + +public enum DeviceTypeRequire : byte +{ + Any, + Gpu, + IntegratedGpu, + DiscreteGpu, + VirtualGpu, + Cpu, +} + +public enum DeviceType : byte +{ + Other, + IntegratedGpu, + DiscreteGpu, + VirtualGpu, + Cpu, +} + +public enum Backend : byte +{ + None, + Dx12, + Vulkan, +}; + +public record struct DeviceRequires +{ + public D3dFeatureLevel D3dFeatureLevel; + public VulkanVersion VulkanVersion; + public DeviceTypeRequire DeviceType; + public DeviceFeatureRequires FeatureRequires; +} + +public enum ShaderModelLevel : uint +{ + Any = 0, + SM_5_1 = 0x51, + SM_6_0 = 0x60, + SM_6_1 = 0x61, + SM_6_2 = 0x62, + SM_6_3 = 0x63, + SM_6_4 = 0x64, + SM_6_5 = 0x65, + SM_6_6 = 0x66, + SM_6_7 = 0x67, + SM_6_8 = 0x68, + SM_6_9 = 0x69, +}; + +public record struct DeviceFeatureRequires +{ + /// + /// 兼容的 hlsl 着色器模型级别 + /// + public ShaderModelLevel ShaderModelLevel; + /// + /// 光追 + /// + public bool RayTracing; + /// + /// 网格着色器 + /// + public bool MeshShader; + /// + /// 描述符堆,dx 后端忽略,vk 使用 VK_EXT_descriptor_buffer + /// + public bool DescriptorHeap; + /// + /// 增强屏障,vk 后端忽略 + /// + public bool EnhancedBarriers; + /// + /// 假 · 无绑定, dx 后端后端忽略 + /// + public bool ArrBindless; + /// + /// 真 · 无绑定, dx 使用 dynamic resource,vk 使用 VK_EXT_mutable_descriptor_type + /// + public bool DynBindless; +} + +public record struct DeviceFeatures +{ + /// + /// 兼容的 hlsl 着色器模型级别 + /// + public ShaderModelLevel ShaderModelLevel; + /// + /// 光追 + /// + public bool RayTracing; + /// + /// 网格着色器 + /// + public bool MeshShader; + /// + /// 描述符堆,dx 后端忽略,vk 使用 VK_EXT_descriptor_buffer + /// + public bool DescriptorHeap; + /// + /// 增强屏障,vk 后端忽略 + /// + public bool EnhancedBarriers; + /// + /// 假 · 无绑定, dx 后端后端忽略 + /// + public bool ArrBindless; + /// + /// 真 · 无绑定, dx 使用 dynamic resource,vk 使用 VK_EXT_mutable_descriptor_type + /// + public bool DynBindless; + + public DeviceFeatures(in FDeviceFeatures native) + { + ShaderModelLevel = (ShaderModelLevel)native.ShaderModelLevel; + RayTracing = native.RayTracing; + MeshShader = native.MeshShader; + DescriptorHeap = native.DescriptorHeap; + EnhancedBarriers = native.EnhancedBarriers; + ArrBindless = native.ArrBindless; + DynBindless = native.DynBindless; + } +} diff --git a/Coplt.Graphics.Core/Core/GpuAdapter.cs b/Coplt.Graphics.Core/Core/GpuAdapter.cs new file mode 100644 index 0000000..1738b43 --- /dev/null +++ b/Coplt.Graphics.Core/Core/GpuAdapter.cs @@ -0,0 +1,64 @@ +using Coplt.Dropping; +using Coplt.Graphics.Native; + +namespace Coplt.Graphics.Core; + +[Dropping(Unmanaged = true)] +public sealed unsafe partial class GpuAdapter +{ + #region Fields + + internal FGpuAdapter* m_ptr; + internal readonly GraphicsInstance m_instance; + internal string? m_name; + internal string? m_driver; + internal string? m_driver_info; + + #endregion + + #region Props + + public FGpuAdapter* Ptr => m_ptr; + public GraphicsInstance Instance => m_instance; + public string Name => m_name ??= m_ptr->m_name.ToString(); + public string Driver => m_driver ??= m_ptr->m_driver.ToString(); + public string DriverInfo => m_driver_info ??= m_ptr->m_driver_info.ToString(); + public uint VendorId => m_ptr->m_vendor_id; + public uint DeviceId => m_ptr->m_device_id; + public D3dFeatureLevel D3dFeatureLevel => (D3dFeatureLevel)m_ptr->m_d3d_feature_level; + public VulkanVersion VulkanVersion => (VulkanVersion)m_ptr->m_vulkan_version; + public DeviceType DeviceType => (DeviceType)m_ptr->m_device_type; + public Backend Backend => (Backend)m_ptr->m_backend; + public DeviceFeatures Features => new(m_ptr->m_features); + + #endregion + + #region Ctor + + internal GpuAdapter(FGpuAdapter* ptr, GraphicsInstance instance) + { + m_ptr = ptr; + m_instance = instance; + } + + #endregion + + #region Drop + + [Drop] + private void Drop() + { + if (ExchangeUtils.ExchangePtr(ref m_ptr, null, out var ptr) is null) return; + ptr->Release(); + } + + #endregion + + #region ToString + + public override string ToString() => string.IsNullOrEmpty(Name) + ? $"{nameof(GpuAdapter)}(0x{(nuint)m_ptr:X})" + : $"{nameof(GpuAdapter)}({Name})"; + + #endregion +} diff --git a/Coplt.Graphics.Core/Core/GpuDevice.cs b/Coplt.Graphics.Core/Core/GpuDevice.cs index ae47851..426f154 100644 --- a/Coplt.Graphics.Core/Core/GpuDevice.cs +++ b/Coplt.Graphics.Core/Core/GpuDevice.cs @@ -9,42 +9,6 @@ namespace Coplt.Graphics.Core; -#region Enums - -public enum D3dFeatureLevel -{ - Unset = 0, - _12_1 = 0xc100, - _12_2 = 0xc200, -} - -public enum VulkanVersion -{ - Unset = 0, - _1_2 = 1002, - _1_3 = 1003, - _1_4 = 1004, -} - -public enum GpuPreference : byte -{ - HighPerformance = 0, - MinimumPower = 1, - Any = 255, -} - -#endregion - -#region GpuDeviceOptions - -public record struct GpuDeviceOptions -{ - public VulkanVersion VulkanVersion; - public D3dFeatureLevel D3dFeatureLevel; -} - -#endregion - [Dropping(Unmanaged = true)] public sealed unsafe partial class GpuDevice { @@ -52,6 +16,7 @@ public sealed unsafe partial class GpuDevice internal FGpuDevice* m_ptr; internal readonly GraphicsInstance m_instance; + internal readonly GpuAdapter m_adapter; internal string? m_name; [Drop] internal readonly GpuQueue m_main_queue; @@ -62,6 +27,7 @@ public sealed unsafe partial class GpuDevice public FGpuDevice* Ptr => m_ptr; public GraphicsInstance Instance => m_instance; + public GpuAdapter Adapter => m_adapter; public GpuQueue MainQueue => m_main_queue; public CommandList MainCommandList => MainQueue.CommandList; @@ -78,6 +44,7 @@ internal GpuDevice( m_name = name; m_ptr = ptr; m_main_queue = CreateMainQueue(Name: QueueName, Name8: QueueName8); + m_adapter = m_instance.m_ptr_to_adapters[(nuint)m_ptr->GetAdapter()]; } #endregion diff --git a/Coplt.Graphics.Core/Core/GraphicsInstance.cs b/Coplt.Graphics.Core/Core/GraphicsInstance.cs index fe7a4c1..fc82903 100644 --- a/Coplt.Graphics.Core/Core/GraphicsInstance.cs +++ b/Coplt.Graphics.Core/Core/GraphicsInstance.cs @@ -1,4 +1,5 @@ using System.Collections.Concurrent; +using System.Collections.Frozen; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; @@ -23,6 +24,8 @@ public unsafe partial class GraphicsInstance #region Fields internal FInstance* m_ptr; + internal readonly List m_adapters = new(); + internal readonly FrozenDictionary m_ptr_to_adapters; internal readonly ConcurrentDictionary m_string_cache = new(); internal readonly ConcurrentDictionary m_slot_id_cache = new(StringComparer.OrdinalIgnoreCase); internal readonly ConcurrentDictionary m_slot_id_name = new(); @@ -34,12 +37,30 @@ public unsafe partial class GraphicsInstance #region Props public FInstance* Ptr => m_ptr; + public bool DebugEnabled => m_ptr->m_debug_enabled; + public bool GpuBasedValidationEnabled => m_ptr->m_gpu_based_validation_enabled; + public ReadOnlySpan Adapters => CollectionsMarshal.AsSpan(m_adapters); #endregion #region Ctor - public GraphicsInstance(FInstance* ptr) => m_ptr = ptr; + public GraphicsInstance(FInstance* ptr) + { + m_ptr = ptr; + uint count = 0; + var adapters = m_ptr->GetAdapters(&count); + var ptr_to_adapters = new Dictionary(); + for (var i = 0; i < count; i++) + { + var adapter = adapters[i]; + adapter->AddRef(); + var obj = new GpuAdapter(adapter, this); + m_adapters.Add(obj); + ptr_to_adapters.Add((nuint)adapter, obj); + } + m_ptr_to_adapters = ptr_to_adapters.ToFrozenDictionary(); + } #endregion @@ -56,7 +77,19 @@ private void Drop() #region Load - public static GraphicsInstance LoadD3d12() => new(D3d12Native.Coplt_Graphics_D3d12_Create_Instance()); + public static GraphicsInstance LoadD3d12(bool Debug = false, bool GpuBasedValidation = false) + { + FInstance* ptr = default; + FResult r = default; + FInstanceCreateOptions f_options = new() + { + Debug = Debug, + GpuBasedValidation = GpuBasedValidation + }; + D3d12Native.Coplt_Graphics_D3d12_Create_Instance(&r, &f_options, &ptr); + r.TryThrow(); + return new(ptr); + } #endregion @@ -277,15 +310,12 @@ private SlotId AllocSlotId(string name) #region CreateDevice public GpuDevice CreateDevice( - GpuDeviceOptions options = default, - GpuPreference Preference = GpuPreference.HighPerformance, - string? Name = null, - ReadOnlySpan Name8 = default, - bool Debug = false + DeviceRequires requires = default, + string? Name = null, ReadOnlySpan Name8 = default ) { - var QueueName = !Debug || Name is null ? null : $"{Name} Main Queue"; - var QueueName8 = !Debug || Name8.Length == 0 ? Name8 : Utils.JoinUtf8String(Name8, " Main Queue"u8); + var QueueName = !DebugEnabled || Name is null ? null : $"{Name} Main Queue"; + var QueueName8 = !DebugEnabled || Name8.Length == 0 ? Name8 : Utils.JoinUtf8String(Name8, " Main Queue"u8); fixed (char* p_name = Name) fixed (byte* p_name8 = Name8) @@ -293,10 +323,22 @@ public GpuDevice CreateDevice( FGpuDeviceCreateOptions f_options = new() { Name = new(Name, Name8, p_name, p_name8), - D3dFeatureLevel = (FD3dFeatureLevel)options.D3dFeatureLevel, - VulkanVersion = (FVulkanVersion)options.VulkanVersion, - Preference = (FGpuPreference)Preference, - Debug = Debug + Requires = new() + { + D3dFeatureLevel = (FD3dFeatureLevel)requires.D3dFeatureLevel, + VulkanVersion = (FVulkanVersion)requires.VulkanVersion, + DeviceType = (FDeviceTypeRequire)requires.DeviceType, + FeatureRequires = new() + { + ShaderModelLevel = (FShaderModelLevel)requires.FeatureRequires.ShaderModelLevel, + RayTracing = requires.FeatureRequires.RayTracing, + MeshShader = requires.FeatureRequires.MeshShader, + DescriptorHeap = requires.FeatureRequires.DescriptorHeap, + EnhancedBarriers = requires.FeatureRequires.EnhancedBarriers, + ArrBindless = requires.FeatureRequires.ArrBindless, + DynBindless = requires.FeatureRequires.DynBindless, + } + } }; FGpuDevice* ptr; m_ptr->CreateDevice(&f_options, &ptr).TryThrow(); diff --git a/Coplt.Graphics.Core/Native/Native.D3d12.cs b/Coplt.Graphics.Core/Native/Native.D3d12.cs index 59b50b3..cb1eed9 100644 --- a/Coplt.Graphics.Core/Native/Native.D3d12.cs +++ b/Coplt.Graphics.Core/Native/Native.D3d12.cs @@ -14,6 +14,15 @@ public unsafe partial struct FD3d12Instance : INativeGuid public FInstance Base; } + [Guid("A3D7C62D-7CFD-42C1-AF7A-781170046CA5")] + [NativeTypeName("struct FD3d12GpuAdapter : Coplt::FGpuAdapter")] + public unsafe partial struct FD3d12GpuAdapter : INativeGuid + { + static Guid* INativeGuid.NativeGuid => (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in IID_FD3d12GpuAdapter)); + + public FGpuAdapter Base; + } + [Guid("DB7CE2BC-155A-4FCC-9F7F-137694191CA7")] [NativeTypeName("struct FD3d12GpuDevice : Coplt::FGpuDevice")] public unsafe partial struct FD3d12GpuDevice : FD3d12GpuDevice.Interface, INativeGuid @@ -56,10 +65,17 @@ public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, name); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FGpuAdapter *")] + public FGpuAdapter* GetAdapter() + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[5]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this)); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void* GetRawDevice() { - return ((delegate* unmanaged[Thiscall])(lpVtbl[5]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this)); + return ((delegate* unmanaged[Thiscall])(lpVtbl[6]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -67,7 +83,7 @@ public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) public FResult CreateMainQueue([NativeTypeName("const FMainQueueCreateOptions &")] FMainQueueCreateOptions* options, FGpuQueue** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[6]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[7]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -75,7 +91,7 @@ public FResult CreateMainQueue([NativeTypeName("const FMainQueueCreateOptions &" public FResult CreateShaderModule([NativeTypeName("const FShaderModuleCreateOptions &")] FShaderModuleCreateOptions* options, FShaderModule** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[7]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[8]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -83,7 +99,7 @@ public FResult CreateShaderModule([NativeTypeName("const FShaderModuleCreateOpti public FResult CreateShaderLayout([NativeTypeName("const FShaderLayoutCreateOptions &")] FShaderLayoutCreateOptions* options, FShaderLayout** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[8]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[9]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -91,7 +107,7 @@ public FResult CreateShaderLayout([NativeTypeName("const FShaderLayoutCreateOpti public FResult GetEmptyShaderLayout([NativeTypeName("const FGetEmptyShaderLayoutOptions &")] FGetEmptyShaderLayoutOptions* options, FShaderLayout** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[9]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[10]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -99,7 +115,7 @@ public FResult GetEmptyShaderLayout([NativeTypeName("const FGetEmptyShaderLayout public FResult CreateShaderInputLayout([NativeTypeName("const FShaderInputLayoutCreateOptions &")] FShaderInputLayoutCreateOptions* options, FShaderInputLayout** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[10]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[11]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -107,7 +123,7 @@ public FResult CreateShaderInputLayout([NativeTypeName("const FShaderInputLayout public FResult CreateShader([NativeTypeName("const FShaderCreateOptions &")] FShaderCreateOptions* options, FShader** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[11]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[12]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -115,7 +131,7 @@ public FResult CreateShader([NativeTypeName("const FShaderCreateOptions &")] FSh public FResult CreateShaderBinding([NativeTypeName("const FShaderBindingCreateOptions &")] FShaderBindingCreateOptions* options, FShaderBinding** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[12]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[13]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -123,7 +139,7 @@ public FResult CreateShaderBinding([NativeTypeName("const FShaderBindingCreateOp public FResult CreateMeshLayout([NativeTypeName("const FMeshLayoutCreateOptions &")] FMeshLayoutCreateOptions* options, FMeshLayout** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[13]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[14]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -131,7 +147,7 @@ public FResult CreateMeshLayout([NativeTypeName("const FMeshLayoutCreateOptions public FResult CreateGraphicsPipeline([NativeTypeName("const FGraphicsShaderPipelineCreateOptions &")] FGraphicsShaderPipelineCreateOptions* options, FGraphicsShaderPipeline** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[14]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[15]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -139,7 +155,7 @@ public FResult CreateGraphicsPipeline([NativeTypeName("const FGraphicsShaderPipe public FResult CreateBuffer([NativeTypeName("const FGpuBufferCreateOptions &")] FGpuBufferCreateOptions* options, FGpuBuffer** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[15]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[16]))((FD3d12GpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } public interface Interface : FGpuDevice.Interface @@ -673,11 +689,12 @@ public interface Interface : FGraphicsShaderPipeline.Interface public static unsafe partial class D3d12Native { [DllImport("Coplt.Graphics.Native.D3d12", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] - [return: NativeTypeName("Coplt::FInstance *")] - public static extern FInstance* Coplt_Graphics_D3d12_Create_Instance(); + public static extern void Coplt_Graphics_D3d12_Create_Instance([NativeTypeName("Coplt::FResult *")] FResult* r, [NativeTypeName("const Coplt::FInstanceCreateOptions &")] FInstanceCreateOptions* options, [NativeTypeName("Coplt::FInstance **")] FInstance** @out); public static readonly Guid IID_FD3d12Instance = new Guid(0x2F979FA9, 0x5CB0, 0x4396, 0xBB, 0x59, 0x16, 0x09, 0x4B, 0x0F, 0x9B, 0x1A); + public static readonly Guid IID_FD3d12GpuAdapter = new Guid(0xA3D7C62D, 0x7CFD, 0x42C1, 0xAF, 0x7A, 0x78, 0x11, 0x70, 0x04, 0x6C, 0xA5); + public static readonly Guid IID_FD3d12GpuDevice = new Guid(0xDB7CE2BC, 0x155A, 0x4FCC, 0x9F, 0x7F, 0x13, 0x76, 0x94, 0x19, 0x1C, 0xA7); public static readonly Guid IID_FD3d12GpuQueue = new Guid(0x11A59DB3, 0x49D8, 0x4158, 0xA2, 0x76, 0x5D, 0x80, 0xFD, 0x37, 0xD8, 0x5F); diff --git a/Coplt.Graphics.Core/Native/Native.cs b/Coplt.Graphics.Core/Native/Native.cs index 745c572..da9c19a 100644 --- a/Coplt.Graphics.Core/Native/Native.cs +++ b/Coplt.Graphics.Core/Native/Native.cs @@ -533,6 +533,14 @@ public interface Interface : FUnknown.Interface } } + [NativeTypeName("Coplt::u8")] + public enum FBackend : byte + { + None, + Dx12, + Vulkan, + } + [Guid("534B3C0C-098D-4157-8ADD-9B79EB5D690F")] [NativeTypeName("struct FAllocator : Coplt::FUnknown")] public unsafe partial struct FAllocator : FAllocator.Interface, INativeGuid @@ -619,29 +627,114 @@ public interface Interface : FUnknown.Interface } } - public partial struct FGpuDeviceCreateOptions + public partial struct FGpuAdapter { } - public partial struct FGpuDeviceCreateOptions + [Guid("B3BBBED6-E997-4BD5-BE53-0AAC0CA8114D")] + [NativeTypeName("struct FGpuAdapter : Coplt::FUnknown")] + public unsafe partial struct FGpuAdapter : FGpuAdapter.Interface, INativeGuid { + static Guid* INativeGuid.NativeGuid => (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in IID_FGpuAdapter)); + + public void** lpVtbl; + [NativeTypeName("Coplt::FStr8or16")] - public FStr8or16 Name; + public FStr8or16 m_name; + + [NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 m_driver; + + [NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 m_driver_info; + + [NativeTypeName("Coplt::u32")] + public uint m_vendor_id; + + [NativeTypeName("Coplt::u32")] + public uint m_device_id; [NativeTypeName("Coplt::FD3dFeatureLevel")] - public FD3dFeatureLevel D3dFeatureLevel; + public FD3dFeatureLevel m_d3d_feature_level; [NativeTypeName("Coplt::FVulkanVersion")] - public FVulkanVersion VulkanVersion; + public FVulkanVersion m_vulkan_version; - [NativeTypeName("Coplt::FGpuPreference")] - public FGpuPreference Preference; + [NativeTypeName("Coplt::FDeviceType")] + public FDeviceType m_device_type; - [NativeTypeName("Coplt::b8")] - public B8 Debug; + [NativeTypeName("Coplt::FBackend")] + public FBackend m_backend; - [NativeTypeName("Coplt::b8")] - public B8 GpuBasedValidation; + [NativeTypeName("Coplt::FDeviceFeatures")] + public FDeviceFeatures m_features; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + ((delegate* unmanaged[Thiscall])(lpVtbl[0]))((FGpuAdapter*)Unsafe.AsPointer(ref this)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("size_t")] + public nuint Release() + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[1]))((FGpuAdapter*)Unsafe.AsPointer(ref this)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("size_t")] + public nuint AddRef() + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[2]))((FGpuAdapter*)Unsafe.AsPointer(ref this)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void* QueryInterface([NativeTypeName("const Guid &")] Guid* id) + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[3]))((FGpuAdapter*)Unsafe.AsPointer(ref this), id); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::b8")] + public B8 IsSupport([NativeTypeName("const FDeviceRequires &")] FDeviceRequires* Requires) + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGpuAdapter*)Unsafe.AsPointer(ref this), Requires); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FResult")] + public FResult CreateDevice([NativeTypeName("const FGpuDeviceCreateOptions &")] FGpuDeviceCreateOptions* options, FGpuDevice** @out) + { + FResult result; + return *((delegate* unmanaged[Thiscall])(lpVtbl[5]))((FGpuAdapter*)Unsafe.AsPointer(ref this), &result, options, @out); + } + + public interface Interface : FUnknown.Interface + { + [return: NativeTypeName("Coplt::b8")] + B8 IsSupport([NativeTypeName("const FDeviceRequires &")] FDeviceRequires* Requires); + + [return: NativeTypeName("Coplt::FResult")] + FResult CreateDevice([NativeTypeName("const FGpuDeviceCreateOptions &")] FGpuDeviceCreateOptions* options, FGpuDevice** @out); + } + } + + public partial struct FGpuAdapter + { + } + + public partial struct FGpuDeviceCreateOptions + { + } + + public partial struct FGpuDeviceCreateOptions + { + [NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 Name; + + [NativeTypeName("Coplt::FDeviceRequires")] + public FDeviceRequires Requires; } public partial struct FGpuDevice @@ -690,10 +783,17 @@ public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) return *((delegate* unmanaged[Thiscall])(lpVtbl[4]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, name); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("Coplt::FGpuAdapter *")] + public FGpuAdapter* GetAdapter() + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[5]))((FGpuDevice*)Unsafe.AsPointer(ref this)); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void* GetRawDevice() { - return ((delegate* unmanaged[Thiscall])(lpVtbl[5]))((FGpuDevice*)Unsafe.AsPointer(ref this)); + return ((delegate* unmanaged[Thiscall])(lpVtbl[6]))((FGpuDevice*)Unsafe.AsPointer(ref this)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -701,7 +801,7 @@ public FResult SetName([NativeTypeName("const FStr8or16 &")] FStr8or16* name) public FResult CreateMainQueue([NativeTypeName("const FMainQueueCreateOptions &")] FMainQueueCreateOptions* options, FGpuQueue** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[6]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[7]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -709,7 +809,7 @@ public FResult CreateMainQueue([NativeTypeName("const FMainQueueCreateOptions &" public FResult CreateShaderModule([NativeTypeName("const FShaderModuleCreateOptions &")] FShaderModuleCreateOptions* options, FShaderModule** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[7]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[8]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -717,7 +817,7 @@ public FResult CreateShaderModule([NativeTypeName("const FShaderModuleCreateOpti public FResult CreateShaderLayout([NativeTypeName("const FShaderLayoutCreateOptions &")] FShaderLayoutCreateOptions* options, FShaderLayout** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[8]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[9]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -725,7 +825,7 @@ public FResult CreateShaderLayout([NativeTypeName("const FShaderLayoutCreateOpti public FResult GetEmptyShaderLayout([NativeTypeName("const FGetEmptyShaderLayoutOptions &")] FGetEmptyShaderLayoutOptions* options, FShaderLayout** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[9]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[10]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -733,7 +833,7 @@ public FResult GetEmptyShaderLayout([NativeTypeName("const FGetEmptyShaderLayout public FResult CreateShaderInputLayout([NativeTypeName("const FShaderInputLayoutCreateOptions &")] FShaderInputLayoutCreateOptions* options, FShaderInputLayout** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[10]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[11]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -741,7 +841,7 @@ public FResult CreateShaderInputLayout([NativeTypeName("const FShaderInputLayout public FResult CreateShader([NativeTypeName("const FShaderCreateOptions &")] FShaderCreateOptions* options, FShader** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[11]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[12]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -749,7 +849,7 @@ public FResult CreateShader([NativeTypeName("const FShaderCreateOptions &")] FSh public FResult CreateShaderBinding([NativeTypeName("const FShaderBindingCreateOptions &")] FShaderBindingCreateOptions* options, FShaderBinding** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[12]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[13]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -757,7 +857,7 @@ public FResult CreateShaderBinding([NativeTypeName("const FShaderBindingCreateOp public FResult CreateMeshLayout([NativeTypeName("const FMeshLayoutCreateOptions &")] FMeshLayoutCreateOptions* options, FMeshLayout** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[13]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[14]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -765,7 +865,7 @@ public FResult CreateMeshLayout([NativeTypeName("const FMeshLayoutCreateOptions public FResult CreateGraphicsPipeline([NativeTypeName("const FGraphicsShaderPipelineCreateOptions &")] FGraphicsShaderPipelineCreateOptions* options, FGraphicsShaderPipeline** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[14]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[15]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -773,11 +873,14 @@ public FResult CreateGraphicsPipeline([NativeTypeName("const FGraphicsShaderPipe public FResult CreateBuffer([NativeTypeName("const FGpuBufferCreateOptions &")] FGpuBufferCreateOptions* options, FGpuBuffer** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[15]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[16]))((FGpuDevice*)Unsafe.AsPointer(ref this), &result, options, @out); } public interface Interface : FGpuObject.Interface { + [return: NativeTypeName("Coplt::FGpuAdapter *")] + FGpuAdapter* GetAdapter(); + void* GetRawDevice(); [return: NativeTypeName("Coplt::FResult")] @@ -812,6 +915,15 @@ public interface Interface : FGpuObject.Interface } } + public partial struct FInstanceCreateOptions + { + [NativeTypeName("Coplt::b8")] + public B8 Debug; + + [NativeTypeName("Coplt::b8")] + public B8 GpuBasedValidation; + } + [Guid("CC2894BA-57C7-474A-B777-1A3E3A7C922C")] [NativeTypeName("struct FInstance : Coplt::FUnknown")] public unsafe partial struct FInstance : FInstance.Interface, INativeGuid @@ -823,6 +935,12 @@ public unsafe partial struct FInstance : FInstance.Interface, INativeGuid [NativeTypeName("Coplt::FAllocator *")] public FAllocator* m_allocator; + [NativeTypeName("Coplt::b8")] + public B8 m_debug_enabled; + + [NativeTypeName("Coplt::b8")] + public B8 m_gpu_based_validation_enabled; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { @@ -881,12 +999,19 @@ public FResult CreateBlob([NativeTypeName("Coplt::usize")] nuint size, FBlob** @ return *((delegate* unmanaged[Thiscall])(lpVtbl[7]))((FInstance*)Unsafe.AsPointer(ref this), &result, size, @out); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [return: NativeTypeName("FGpuAdapter *const *")] + public FGpuAdapter** GetAdapters([NativeTypeName("Coplt::u32 *")] uint* out_count) + { + return ((delegate* unmanaged[Thiscall])(lpVtbl[8]))((FInstance*)Unsafe.AsPointer(ref this), out_count); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] public FResult CreateDevice([NativeTypeName("const FGpuDeviceCreateOptions &")] FGpuDeviceCreateOptions* options, FGpuDevice** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[8]))((FInstance*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[9]))((FInstance*)Unsafe.AsPointer(ref this), &result, options, @out); } public interface Interface : FUnknown.Interface @@ -903,13 +1028,36 @@ public interface Interface : FUnknown.Interface [return: NativeTypeName("Coplt::FResult")] FResult CreateBlob([NativeTypeName("Coplt::usize")] nuint size, FBlob** @out); + [return: NativeTypeName("FGpuAdapter *const *")] + FGpuAdapter** GetAdapters([NativeTypeName("Coplt::u32 *")] uint* out_count); + [return: NativeTypeName("Coplt::FResult")] FResult CreateDevice([NativeTypeName("const FGpuDeviceCreateOptions &")] FGpuDeviceCreateOptions* options, FGpuDevice** @out); } } + [NativeTypeName("Coplt::u32")] + public enum FShaderModelLevel : uint + { + Any = 0, + SM_5_1 = 0x51, + SM_6_0 = 0x60, + SM_6_1 = 0x61, + SM_6_2 = 0x62, + SM_6_3 = 0x63, + SM_6_4 = 0x64, + SM_6_5 = 0x65, + SM_6_6 = 0x66, + SM_6_7 = 0x67, + SM_6_8 = 0x68, + SM_6_9 = 0x69, + } + public partial struct FDeviceFeatureRequires { + [NativeTypeName("Coplt::FShaderModelLevel")] + public FShaderModelLevel ShaderModelLevel; + [NativeTypeName("Coplt::b8")] public B8 RayTracing; @@ -931,6 +1079,9 @@ public partial struct FDeviceFeatureRequires public partial struct FDeviceFeatures { + [NativeTypeName("Coplt::FShaderModelLevel")] + public FShaderModelLevel ShaderModelLevel; + [NativeTypeName("Coplt::b8")] public B8 RayTracing; @@ -968,11 +1119,39 @@ public enum FD3dFeatureLevel } [NativeTypeName("Coplt::u8")] - public enum FGpuPreference : byte + public enum FDeviceTypeRequire : byte { - HighPerformance = 0, - MinimumPower = 1, - Any = 255, + Any, + Gpu, + IntegratedGpu, + DiscreteGpu, + VirtualGpu, + Cpu, + } + + [NativeTypeName("Coplt::u8")] + public enum FDeviceType : byte + { + Other, + IntegratedGpu, + DiscreteGpu, + VirtualGpu, + Cpu, + } + + public partial struct FDeviceRequires + { + [NativeTypeName("Coplt::FD3dFeatureLevel")] + public FD3dFeatureLevel D3dFeatureLevel; + + [NativeTypeName("Coplt::FVulkanVersion")] + public FVulkanVersion VulkanVersion; + + [NativeTypeName("Coplt::FDeviceTypeRequire")] + public FDeviceTypeRequire DeviceType; + + [NativeTypeName("Coplt::FDeviceFeatureRequires")] + public FDeviceFeatureRequires FeatureRequires; } [NativeTypeName("Coplt::u8")] @@ -4390,6 +4569,8 @@ public static partial class Native public static readonly Guid IID_FInstance = new Guid(0xCC2894BA, 0x57C7, 0x474A, 0xB7, 0x77, 0x1A, 0x3E, 0x3A, 0x7C, 0x92, 0x2C); + public static readonly Guid IID_FGpuAdapter = new Guid(0xB3BBBED6, 0xE997, 0x4BD5, 0xBE, 0x53, 0x0A, 0xAC, 0x0C, 0xA8, 0x11, 0x4D); + public static readonly Guid IID_FGpuDevice = new Guid(0x557F032D, 0xED50, 0x403A, 0xAD, 0xC5, 0x21, 0x4F, 0xDD, 0xBE, 0x6C, 0x6B); public static readonly Guid IID_FShaderModule = new Guid(0x5C0E1FDB, 0x2ACD, 0x4FCE, 0xB9, 0x85, 0x09, 0xE1, 0x2A, 0x7A, 0x1A, 0xAD); diff --git a/Coplt.Graphics.Core/Native/Str8or16.cs b/Coplt.Graphics.Core/Native/Str8or16.cs index 7524373..772c1e9 100644 --- a/Coplt.Graphics.Core/Native/Str8or16.cs +++ b/Coplt.Graphics.Core/Native/Str8or16.cs @@ -1,4 +1,6 @@ -namespace Coplt.Graphics.Native; +using System.Text; + +namespace Coplt.Graphics.Native; public unsafe partial struct FStr8or16 { @@ -33,4 +35,15 @@ public FStr8or16(string? name, ReadOnlySpan name8, char* p_name, byte* p_n throw new ArgumentOutOfRangeException(); } } + + public override string ToString() + { + if (len == 0) return ""; + return type switch + { + FStrType.Str16 => new ReadOnlySpan(str16, len).ToString(), + FStrType.Str8 => Encoding.UTF8.GetString(new ReadOnlySpan(str8, len)), + _ => "" + }; + } } diff --git a/Coplt.Graphics.Native/Api/CMakeLists.txt b/Coplt.Graphics.Native/Api/CMakeLists.txt index a615db1..5fca47a 100644 --- a/Coplt.Graphics.Native/Api/CMakeLists.txt +++ b/Coplt.Graphics.Native/Api/CMakeLists.txt @@ -46,6 +46,7 @@ add_library(${target_name} STATIC FFI/Binding.h FFI/Executor.h FFI/Features.h + FFI/Adapter.h ) set_target_properties(${target_name} PROPERTIES LINKER_LANGUAGE CXX) add_library(Coplt::Graphics::Api ALIAS ${target_name}) diff --git a/Coplt.Graphics.Native/Api/FFI/Adapter.h b/Coplt.Graphics.Native/Api/FFI/Adapter.h new file mode 100644 index 0000000..85aab46 --- /dev/null +++ b/Coplt.Graphics.Native/Api/FFI/Adapter.h @@ -0,0 +1,28 @@ +#pragma once + +#include "Object.h" +#include "Result.h" +#include "Features.h" +#include "Device.h" + +namespace Coplt +{ + + COPLT_INTERFACE_DEFINE(FGpuAdapter, "b3bbbed6-e997-4bd5-be53-0aac0ca8114d", FUnknown) + { + FStr8or16 m_name{}; + FStr8or16 m_driver{}; + FStr8or16 m_driver_info{}; + u32 m_vendor_id{}; + u32 m_device_id{}; + FD3dFeatureLevel m_d3d_feature_level{}; + FVulkanVersion m_vulkan_version{}; + FDeviceType m_device_type{}; + FBackend m_backend{}; + FDeviceFeatures m_features{}; + + virtual b8 IsSupport(const FDeviceRequires& Requires) noexcept = 0; + + virtual FResult CreateDevice(const FGpuDeviceCreateOptions& options, FGpuDevice** out) noexcept = 0; + }; +} diff --git a/Coplt.Graphics.Native/Api/FFI/Device.h b/Coplt.Graphics.Native/Api/FFI/Device.h index fabc56e..b058d69 100644 --- a/Coplt.Graphics.Native/Api/FFI/Device.h +++ b/Coplt.Graphics.Native/Api/FFI/Device.h @@ -1,6 +1,7 @@ #pragma once #include "Binding.h" +#include "Features.h" #include "GpuObject.h" #include "Layout.h" #include "Queue.h" @@ -25,28 +26,48 @@ namespace Coplt _12_2 = 0xc200, }; - enum class FGpuPreference : u8 + enum class FDeviceTypeRequire : u8 { - HighPerformance = 0, - MinimumPower = 1, - Any = 255, + Any, + Gpu, + IntegratedGpu, + DiscreteGpu, + VirtualGpu, + Cpu, }; - struct FGpuDeviceCreateOptions + enum class FDeviceType : u8 + { + Other, + IntegratedGpu, + DiscreteGpu, + VirtualGpu, + Cpu, + }; + + struct FDeviceRequires { - // 可选 - FStr8or16 Name{}; // 仅 dx 后端时可用 FD3dFeatureLevel D3dFeatureLevel{}; // 仅 vk 后端时可用 FVulkanVersion VulkanVersion{}; - FGpuPreference Preference{}; - b8 Debug{}; - b8 GpuBasedValidation{}; + FDeviceTypeRequire DeviceType{}; + FDeviceFeatureRequires FeatureRequires{}; + }; + + struct FGpuDeviceCreateOptions + { + // 可选 + FStr8or16 Name{}; + FDeviceRequires Requires{}; }; + struct FGpuAdapter; + COPLT_INTERFACE_DEFINE(FGpuDevice, "557f032d-ed50-403a-adc5-214fddbe6c6b", FGpuObject) { + virtual FGpuAdapter* GetAdapter() noexcept = 0; + // d3d12 返回 ID3D12Device* virtual void* GetRawDevice() noexcept = 0; @@ -55,19 +76,13 @@ namespace Coplt virtual FResult CreateShaderModule(const FShaderModuleCreateOptions& options, FShaderModule** out) noexcept = 0; virtual FResult CreateShaderLayout(const FShaderLayoutCreateOptions& options, FShaderLayout** out) noexcept = 0; virtual FResult GetEmptyShaderLayout(const FGetEmptyShaderLayoutOptions& options, FShaderLayout** out) noexcept = 0; - virtual FResult CreateShaderInputLayout( - const FShaderInputLayoutCreateOptions& options, FShaderInputLayout** out - ) noexcept = 0; + virtual FResult CreateShaderInputLayout(const FShaderInputLayoutCreateOptions& options, FShaderInputLayout** out) noexcept = 0; virtual FResult CreateShader(const FShaderCreateOptions& options, FShader** out) noexcept = 0; - virtual FResult CreateShaderBinding( - const FShaderBindingCreateOptions& options, FShaderBinding** out - ) noexcept = 0; + virtual FResult CreateShaderBinding(const FShaderBindingCreateOptions& options, FShaderBinding** out) noexcept = 0; virtual FResult CreateMeshLayout(const FMeshLayoutCreateOptions& options, FMeshLayout** out) noexcept = 0; - virtual FResult CreateGraphicsPipeline( - const FGraphicsShaderPipelineCreateOptions& options, FGraphicsShaderPipeline** out - ) noexcept = 0; + virtual FResult CreateGraphicsPipeline(const FGraphicsShaderPipelineCreateOptions& options, FGraphicsShaderPipeline** out) noexcept = 0; virtual FResult CreateBuffer(const FGpuBufferCreateOptions& options, FGpuBuffer** out) noexcept = 0; }; diff --git a/Coplt.Graphics.Native/Api/FFI/Features.h b/Coplt.Graphics.Native/Api/FFI/Features.h index bd8c174..d0f3d54 100644 --- a/Coplt.Graphics.Native/Api/FFI/Features.h +++ b/Coplt.Graphics.Native/Api/FFI/Features.h @@ -4,8 +4,26 @@ namespace Coplt { + enum class FShaderModelLevel : u32 + { + Any = 0, + SM_5_1 = 0x51, + SM_6_0 = 0x60, + SM_6_1 = 0x61, + SM_6_2 = 0x62, + SM_6_3 = 0x63, + SM_6_4 = 0x64, + SM_6_5 = 0x65, + SM_6_6 = 0x66, + SM_6_7 = 0x67, + SM_6_8 = 0x68, + SM_6_9 = 0x69, + }; + struct FDeviceFeatureRequires { + // 兼容的 hlsl 着色器模型级别 + FShaderModelLevel ShaderModelLevel{}; // 光追 b8 RayTracing{}; // 网格着色器 @@ -14,7 +32,7 @@ namespace Coplt b8 DescriptorHeap{}; // 增强屏障,vk 后端忽略 b8 EnhancedBarriers{}; - // 假 · 无绑定 + // 假 · 无绑定, dx 后端后端忽略 b8 ArrBindless{}; // 真 · 无绑定, dx 使用 dynamic resource,vk 使用 VK_EXT_mutable_descriptor_type b8 DynBindless{}; @@ -22,6 +40,8 @@ namespace Coplt struct FDeviceFeatures { + // 兼容的 hlsl 着色器模型级别 + FShaderModelLevel ShaderModelLevel{}; // 光追 b8 RayTracing{}; // 网格着色器 @@ -30,7 +50,7 @@ namespace Coplt b8 DescriptorHeap{}; // 增强屏障,vk 后端永远为 true b8 EnhancedBarriers{}; - // 假 · 无绑定 + // 假 · 无绑定, dx 后端永远为 true b8 ArrBindless{}; // 真 · 无绑定, dx 使用 dynamic resource,vk 使用 VK_EXT_mutable_descriptor_type b8 DynBindless{}; diff --git a/Coplt.Graphics.Native/Api/FFI/Instance.h b/Coplt.Graphics.Native/Api/FFI/Instance.h index 3708735..4bd19c5 100644 --- a/Coplt.Graphics.Native/Api/FFI/Instance.h +++ b/Coplt.Graphics.Native/Api/FFI/Instance.h @@ -6,6 +6,13 @@ namespace Coplt { + enum class FBackend : u8 + { + None, + Dx12, + Vulkan, + }; + COPLT_INTERFACE_DEFINE(FAllocator, "534b3c0c-098d-4157-8add-9b79eb5d690f", FUnknown) { virtual void* MemoryAlloc(size_t size) noexcept = 0; @@ -16,13 +23,22 @@ namespace Coplt virtual void MemoryFree(void* p, size_t align) noexcept = 0; }; + struct FGpuAdapter; struct FGpuDeviceCreateOptions; struct FGpuDevice; + struct FInstanceCreateOptions + { + b8 Debug{}; + b8 GpuBasedValidation{}; + }; + COPLT_INTERFACE_DEFINE(FInstance, "cc2894ba-57c7-474a-b777-1a3e3a7c922c", FUnknown) { // 外部只能读取 FAllocator* m_allocator{}; + b8 m_debug_enabled{}; + b8 m_gpu_based_validation_enabled{}; virtual FResult SetLogger(const FLogger& logger) noexcept = 0; @@ -31,6 +47,7 @@ namespace Coplt virtual FResult CreateBlob(usize size, FBlob** out) noexcept = 0; + virtual FGpuAdapter* const* GetAdapters(u32* out_count) noexcept = 0; virtual FResult CreateDevice(const FGpuDeviceCreateOptions& options, FGpuDevice** out) noexcept = 0; }; } diff --git a/Coplt.Graphics.Native/D3d12/CMakeLists.txt b/Coplt.Graphics.Native/D3d12/CMakeLists.txt index 9268baa..5ac43ed 100644 --- a/Coplt.Graphics.Native/D3d12/CMakeLists.txt +++ b/Coplt.Graphics.Native/D3d12/CMakeLists.txt @@ -44,6 +44,9 @@ add_library(${target_name} SHARED Src/DescriptorManager.cc Include/View.h Src/Executor.h + FFI/Adapter.h + Src/Adapter.h + Src/Adapter.cc ) set_target_properties(${target_name} PROPERTIES LINKER_LANGUAGE CXX) set_target_properties(${target_name} PROPERTIES OUTPUT_NAME "Coplt.Graphics.Native.D3d12") diff --git a/Coplt.Graphics.Native/D3d12/FFI/Adapter.h b/Coplt.Graphics.Native/D3d12/FFI/Adapter.h new file mode 100644 index 0000000..fd8ee22 --- /dev/null +++ b/Coplt.Graphics.Native/D3d12/FFI/Adapter.h @@ -0,0 +1,11 @@ +#pragma once + +#include "../../Api/FFI/Adapter.h" + +namespace Coplt +{ + COPLT_INTERFACE_DEFINE(FD3d12GpuAdapter, "a3d7c62d-7cfd-42c1-af7a-781170046ca5", FGpuAdapter) + { + + }; +} diff --git a/Coplt.Graphics.Native/D3d12/FFI/Library.h b/Coplt.Graphics.Native/D3d12/FFI/Library.h index afe12fe..66fcadd 100644 --- a/Coplt.Graphics.Native/D3d12/FFI/Library.h +++ b/Coplt.Graphics.Native/D3d12/FFI/Library.h @@ -2,4 +2,4 @@ #include "../../Api/FFI/Instance.h" -extern "C" COPLT_API Coplt::FInstance* Coplt_Graphics_D3d12_Create_Instance(); +extern "C" COPLT_API void Coplt_Graphics_D3d12_Create_Instance(Coplt::FResult* r, const Coplt::FInstanceCreateOptions& options, Coplt::FInstance** out); diff --git a/Coplt.Graphics.Native/D3d12/Src/Adapter.cc b/Coplt.Graphics.Native/D3d12/Src/Adapter.cc new file mode 100644 index 0000000..40856c7 --- /dev/null +++ b/Coplt.Graphics.Native/D3d12/Src/Adapter.cc @@ -0,0 +1,112 @@ +#include "Adapter.h" + +#include "directx/d3d12.h" +#include "directx/d3dx12_check_feature_support.h" + +#include "../../Api/Include/Error.h" + +using namespace Coplt; + +D3d12GpuAdapter::D3d12GpuAdapter( + Rc&& instance, ComPtr&& adapter +): m_instance(std::move(instance)), m_adapter(std::move(adapter)) +{ + m_backend = FBackend::Dx12; + + ComPtr device{}; + chr | D3D12CreateDevice(m_adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device)); + + CD3DX12FeatureSupport feature_support{}; + chr | feature_support.Init(device.Get()); + + m_d3d_feature_level = static_cast(feature_support.MaxSupportedFeatureLevel()); + + DXGI_ADAPTER_DESC1 desc1{}; + chr | m_adapter->GetDesc1(&desc1); + m_name_string = std::wstring(desc1.Description); + m_name = FStr8or16(m_name_string); + m_vendor_id = desc1.VendorId; + m_device_id = desc1.DeviceId; + + if (desc1.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) + { + m_device_type = FDeviceType::Cpu; + } + else if (feature_support.UMA()) + { + m_device_type = FDeviceType::IntegratedGpu; + } + else + { + m_device_type = FDeviceType::DiscreteGpu; + } + + LARGE_INTEGER li{}; + if (SUCCEEDED(m_adapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &li))) + { + const auto i = li.QuadPart; + m_driver_string = fmt::format(L"{}.{}.{}.{}", i >> 48, (i >> 32) & 0xFFFF, (i >> 16) & 0xFFFF, i & 0xFFFF); + m_driver = FStr8or16(m_driver_string); + } + + m_features.DescriptorHeap = true; + m_features.ArrBindless = true; + + m_features.ShaderModelLevel = static_cast(feature_support.HighestShaderModel()); + if (m_features.ShaderModelLevel >= FShaderModelLevel::SM_6_6) + { + m_features.DynBindless = true; + } + + if (feature_support.RaytracingTier() >= D3D12_RAYTRACING_TIER_1_0) m_features.RayTracing = true; + if (feature_support.MeshShaderTier() >= D3D12_MESH_SHADER_TIER_1) m_features.MeshShader = true; + if (feature_support.EnhancedBarriersSupported()) m_features.EnhancedBarriers = true; +} + +FResult D3d12GpuAdapter::CreateDevice(const FGpuDeviceCreateOptions& options, FGpuDevice** out) noexcept +{ + return feb([&] + { + *out = new D3d12GpuDevice(this->CloneThis(), options); + }); +} + +b8 D3d12GpuAdapter::IsSupport(const FDeviceRequires& Requires) noexcept +{ + switch (Requires.DeviceType) + { + case FDeviceTypeRequire::Any: + break; + case FDeviceTypeRequire::Gpu: + case FDeviceTypeRequire::VirtualGpu: + if (m_device_type != FDeviceType::DiscreteGpu && m_device_type != FDeviceType::IntegratedGpu) return false; + case FDeviceTypeRequire::IntegratedGpu: + if (m_device_type != FDeviceType::IntegratedGpu) return false; + break; + case FDeviceTypeRequire::DiscreteGpu: + if (m_device_type != FDeviceType::DiscreteGpu) return false; + break; + case FDeviceTypeRequire::Cpu: + if (m_device_type != FDeviceType::Cpu) return false; + break; + default: + return false; + } + if (Requires.D3dFeatureLevel > m_d3d_feature_level) + return false; + if (Requires.FeatureRequires.ShaderModelLevel > m_features.ShaderModelLevel) + return false; + if (Requires.FeatureRequires.RayTracing && !m_features.RayTracing) + return false; + if (Requires.FeatureRequires.MeshShader && !m_features.MeshShader) + return false; + if (Requires.FeatureRequires.DescriptorHeap && !m_features.DescriptorHeap) + return false; + if (Requires.FeatureRequires.EnhancedBarriers && !m_features.EnhancedBarriers) + return false; + if (Requires.FeatureRequires.ArrBindless && !m_features.ArrBindless) + return false; + if (Requires.FeatureRequires.DynBindless && !m_features.DynBindless) + return false; + return true; +} diff --git a/Coplt.Graphics.Native/D3d12/Src/Adapter.h b/Coplt.Graphics.Native/D3d12/Src/Adapter.h new file mode 100644 index 0000000..9f4f58b --- /dev/null +++ b/Coplt.Graphics.Native/D3d12/Src/Adapter.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +#include "Device.h" +#include "../../Api/Include/Object.h" +#include "../FFI/Adapter.h" + +namespace Coplt +{ + struct D3d12GpuAdapter final : Object + { + Rc m_instance{}; + ComPtr m_adapter{}; + std::wstring m_name_string{}; + std::wstring m_driver_string{}; + + explicit D3d12GpuAdapter(Rc&& instance, ComPtr&& adapter); + + FResult CreateDevice(const FGpuDeviceCreateOptions& options, FGpuDevice** out) noexcept override; + + b8 IsSupport(const FDeviceRequires& Requires) noexcept override; + }; +} diff --git a/Coplt.Graphics.Native/D3d12/Src/Device.cc b/Coplt.Graphics.Native/D3d12/Src/Device.cc index b668570..8e54792 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Device.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Device.cc @@ -1,10 +1,10 @@ #include "Device.h" #include "Binding.h" -#include "dxgi1_6.h" -#include "DescriptorManager.h" #include "../../Api/Src/Shader.h" +#include "Adapter.h" +#include "DescriptorManager.h" #include "Buffer.h" #include "GraphicsPipeline.h" #include "Layout.h" @@ -14,63 +14,6 @@ using namespace Coplt; namespace { - void GetAdapter( - IDXGIFactory4* factory, IDXGIAdapter1** out_adapter, - D3D_FEATURE_LEVEL feature_level, const FGpuDeviceCreateOptions& options - ) - { - ComPtr factory6{}; - ComPtr adapter{}; - if (SUCCEEDED(factory->QueryInterface(IID_PPV_ARGS(&factory6)))) - { - const DXGI_GPU_PREFERENCE preference = - options.Preference == FGpuPreference::HighPerformance - ? DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE - : options.Preference == FGpuPreference::MinimumPower - ? DXGI_GPU_PREFERENCE_MINIMUM_POWER - : DXGI_GPU_PREFERENCE_UNSPECIFIED; - for ( - UINT index = 0; - SUCCEEDED(factory6->EnumAdapterByGpuPreference(index, preference, IID_PPV_ARGS(&adapter))); - ++index) - { - DXGI_ADAPTER_DESC1 desc{}; - adapter->GetDesc1(&desc); - - if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) - { - continue; - } - - if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), feature_level, _uuidof(ID3D12Device), nullptr))) - { - break; - } - } - } - - if (adapter.Get() == nullptr) - { - for (UINT index = 0; SUCCEEDED(factory->EnumAdapters1(index, &adapter)); ++index) - { - DXGI_ADAPTER_DESC1 desc{}; - adapter->GetDesc1(&desc); - - if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) - { - continue; - } - - if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), feature_level, _uuidof(ID3D12Device), nullptr))) - { - break; - } - } - } - - *out_adapter = adapter.Detach(); - } - void debug_callback( D3D12_MESSAGE_CATEGORY Category, D3D12_MESSAGE_SEVERITY Severity, @@ -99,62 +42,20 @@ namespace } } -D3d12GpuDevice::D3d12GpuDevice( - Rc instance, - const FGpuDeviceCreateOptions& options -) : m_instance(std::move(instance)) +D3d12GpuDevice::D3d12GpuDevice(Rc&& adapter, const FGpuDeviceCreateOptions& options): + m_adapter(std::move(adapter)) { - UINT dxgi_flags = 0; + m_instance = m_adapter->m_instance; - if (options.Debug) - { - if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&m_debug_controller)))) - { - m_debug_controller->EnableDebugLayer(); - dxgi_flags |= DXGI_CREATE_FACTORY_DEBUG; - - if (options.GpuBasedValidation) - { - ComPtr debug1{}; - if (SUCCEEDED(m_debug_controller->QueryInterface(&debug1))) - { - debug1->SetEnableGPUBasedValidation(true); - } - ComPtr debug2{}; - if (SUCCEEDED(m_debug_controller->QueryInterface(&debug2))) - { - debug2->SetGPUBasedValidationFlags(D3D12_GPU_BASED_VALIDATION_FLAGS_DISABLE_STATE_TRACKING); - } - } - - ComPtr debug5{}; - if (SUCCEEDED(m_debug_controller->QueryInterface(&debug5))) - { - debug5->SetEnableAutoName(true); - } - } - else m_debug_controller = nullptr; - } - - chr | CreateDXGIFactory2(dxgi_flags, IID_PPV_ARGS(&m_factory)); - - const auto feature_level = - options.D3dFeatureLevel == FD3dFeatureLevel::Unset - ? D3D_FEATURE_LEVEL_12_2 - : static_cast(options.D3dFeatureLevel); - - GetAdapter(m_factory.Get(), &m_adapter, feature_level, options); - if (!m_adapter) - COPLT_THROW("No matching devices found"); - - chr | D3D12CreateDevice(m_adapter.Get(), feature_level, IID_PPV_ARGS(&m_device)); + const auto feature_level = static_cast(m_adapter->m_d3d_feature_level); + chr | D3D12CreateDevice(m_adapter->m_adapter.Get(), feature_level, IID_PPV_ARGS(&m_device)); D3D12MA::ALLOCATOR_DESC allocator_desc{}; D3D12MA::ALLOCATION_CALLBACKS allocation_callbacks{}; allocation_callbacks.pAllocate = [](auto size, auto align, auto data) { return mi_malloc_aligned(size, align); }; allocation_callbacks.pFree = [](auto ptr, auto data) { return mi_free(ptr); }; allocator_desc.pDevice = m_device.Get(); - allocator_desc.pAdapter = m_adapter.Get(); + allocator_desc.pAdapter = m_adapter->m_adapter.Get(); allocator_desc.pAllocationCallbacks = &allocation_callbacks; chr | CreateAllocator(&allocator_desc, &m_gpu_allocator); @@ -187,15 +88,31 @@ D3d12GpuDevice::~D3d12GpuDevice() } } +const Logger& D3d12GpuDevice::Logger() const noexcept +{ + return m_instance->Logger(); +} + +bool D3d12GpuDevice::Debug() const noexcept +{ + return m_instance->Debug(); +} + FResult D3d12GpuDevice::SetName(const FStr8or16& name) noexcept { return feb([&] { - if (!Debug()) return; + if (!Debug()) + return; chr | m_device >> SetNameEx(name); }); } +FGpuAdapter* D3d12GpuDevice::GetAdapter() noexcept +{ + return m_adapter.get(); +} + void* D3d12GpuDevice::GetRawDevice() noexcept { return m_device0.Get(); @@ -204,7 +121,8 @@ void* D3d12GpuDevice::GetRawDevice() noexcept const Rc& D3d12GpuDevice::GetEmptyLayout(FShaderLayoutFlags flags) { - if (!m_empty_layouts) m_empty_layouts = std::make_unique(); + if (!m_empty_layouts) + m_empty_layouts = std::make_unique(); return m_empty_layouts->GetOrAdd(flags, [&](auto& p) { const auto name = fmt::format(L"Empty Layout {}", static_cast(flags)); diff --git a/Coplt.Graphics.Native/D3d12/Src/Device.h b/Coplt.Graphics.Native/D3d12/Src/Device.h index 19f0f72..e7bd340 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Device.h +++ b/Coplt.Graphics.Native/D3d12/Src/Device.h @@ -1,6 +1,7 @@ #pragma once #include + #include "D3D12MemAlloc.h" #include "Instance.h" #include "../../Api/Include/HashMap.h" @@ -9,6 +10,7 @@ namespace Coplt { + struct D3d12GpuAdapter; struct DescriptorManager; struct D3d12ShaderLayout; struct D3d12MeshLayout; @@ -18,9 +20,7 @@ namespace Coplt using EmptyLayouts = HashMap>; Rc m_instance{}; - ComPtr m_debug_controller{}; - ComPtr m_factory{}; - ComPtr m_adapter{}; + Rc m_adapter{}; ComPtr m_device{}; ComPtr m_device0{}; ComPtr m_info_queue{}; @@ -30,25 +30,18 @@ namespace Coplt Rc m_empty_mesh_layout{}; DWORD m_callback_cookie{}; - explicit D3d12GpuDevice( - Rc instance, - const FGpuDeviceCreateOptions& options - ); + explicit D3d12GpuDevice(Rc&& adapter, const FGpuDeviceCreateOptions& options); ~D3d12GpuDevice() override; - const Logger& Logger() const noexcept - { - return m_instance->Logger(); - } + const Logger& Logger() const noexcept; - bool Debug() const noexcept - { - return m_debug_controller != nullptr; - } + bool Debug() const noexcept; FResult SetName(const FStr8or16& name) noexcept override; + FGpuAdapter* GetAdapter() noexcept override; + void* GetRawDevice() noexcept override; const Rc& GetEmptyLayout(FShaderLayoutFlags flags); diff --git a/Coplt.Graphics.Native/D3d12/Src/Instance.cc b/Coplt.Graphics.Native/D3d12/Src/Instance.cc index 1c2acbe..42017ea 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Instance.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Instance.cc @@ -1,14 +1,118 @@ #include "Instance.h" -#include "Device.h" #include "../../Api/Include/Error.h" +#include "Adapter.h" +#include "Device.h" using namespace Coplt; +D3d12Instance::D3d12Instance(const FInstanceCreateOptions& options) +{ + UINT dxgi_flags = 0; + + if (options.Debug) + { + if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&m_debug_controller)))) + { + m_debug_controller->EnableDebugLayer(); + dxgi_flags |= DXGI_CREATE_FACTORY_DEBUG; + m_debug_enabled = true; + + if (options.GpuBasedValidation) + { + ComPtr debug1{}; + if (SUCCEEDED(m_debug_controller->QueryInterface(&debug1))) + { + debug1->SetEnableGPUBasedValidation(true); + m_gpu_based_validation_enabled = true; + } + ComPtr debug2{}; + if (SUCCEEDED(m_debug_controller->QueryInterface(&debug2))) + { + debug2->SetGPUBasedValidationFlags(D3D12_GPU_BASED_VALIDATION_FLAGS_DISABLE_STATE_TRACKING); + } + } + + ComPtr debug5{}; + if (SUCCEEDED(m_debug_controller->QueryInterface(&debug5))) + { + debug5->SetEnableAutoName(true); + } + } + else + m_debug_controller = nullptr; + } + + chr | CreateDXGIFactory2(dxgi_flags, IID_PPV_ARGS(&m_factory)); + + if (SUCCEEDED(m_factory->QueryInterface(IID_PPV_ARGS(&m_factory6)))) + { + ComPtr adapter{}; + constexpr auto preference = DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE; + for ( + UINT index = 0; + SUCCEEDED(m_factory6->EnumAdapterByGpuPreference(index, preference, IID_PPV_ARGS(&adapter))); + ++index + ) + { + CreateAdapter(std::move(adapter)); + } + } + else + { + ComPtr adapter{}; + for (UINT index = 0; SUCCEEDED(m_factory->EnumAdapters1(index, &adapter)); ++index) + { + CreateAdapter(std::move(adapter)); + } + } + + m_f_adapters.reserve(m_adapters.size()); + for (const auto& adapter : m_adapters) + m_f_adapters.push_back(adapter.get()); +} + +void D3d12Instance::CreateAdapter(ComPtr&& adapter) +{ + m_adapters.push_back(new D3d12GpuAdapter(this->CloneThis(), std::move(adapter))); +} + FResult D3d12Instance::CreateDevice(const FGpuDeviceCreateOptions& options, FGpuDevice** out) noexcept { return feb([&] { - *out = new D3d12GpuDevice(this->CloneThis(), options); + FResult ret = FResult::None(); + std::vector results{}; + for (const auto& adapter : m_adapters) + { + if (!adapter->IsSupport(options.Requires)) + continue; + auto r = feb([&] + { + *out = new D3d12GpuDevice(adapter.Clone(), options); + }); + if (!r.IsError()) + goto end; + results.push_back(r); + } + for (auto& result : results) + { + Logger().Log(FLogLevel::Error, FLogType::Common, result.msg); + } + if (m_adapters.empty()) + Logger().Log(FLogLevel::Error, FLogType::Common, u"No physical gpu device is available."); + ret = FResult::Error(u"Creation failed. No matching device."); + end: + for (auto& result : results) + { + result.Drop(); + } + return ret; }); } + +FGpuAdapter* const* D3d12Instance::GetAdapters(u32* out_count) noexcept +{ + *out_count = m_f_adapters.size(); + return m_f_adapters.data(); +} diff --git a/Coplt.Graphics.Native/D3d12/Src/Instance.h b/Coplt.Graphics.Native/D3d12/Src/Instance.h index e86f6fe..7ed68c0 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Instance.h +++ b/Coplt.Graphics.Native/D3d12/Src/Instance.h @@ -1,16 +1,35 @@ #pragma once +#include +#include +#include + #include "../../Api/Include/Object.h" #include "../../Api/FFI/Instance.h" #include "../../Api/Include/InstanceBase.h" #include "../FFI/Instance.h" #include "../Include/Utils.h" -#include namespace Coplt { + struct D3d12GpuAdapter; + struct D3d12Instance final : InstanceBase> { + ComPtr m_debug_controller{}; + ComPtr m_factory{}; + ComPtr m_factory6{}; + std::vector> m_adapters{}; + std::vector m_f_adapters{}; + + explicit D3d12Instance(const FInstanceCreateOptions& options); + + void CreateAdapter(ComPtr&& adapter); + FResult CreateDevice(const FGpuDeviceCreateOptions& options, FGpuDevice** out) noexcept override; + + FGpuAdapter* const* GetAdapters(u32* out_count) noexcept override; + + bool Debug() const noexcept { return m_debug_enabled; } }; } diff --git a/Coplt.Graphics.Native/D3d12/Src/Library.cc b/Coplt.Graphics.Native/D3d12/Src/Library.cc index 894795e..07948fd 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Library.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Library.cc @@ -9,7 +9,10 @@ using namespace Coplt; -FInstance* Coplt_Graphics_D3d12_Create_Instance() +void Coplt_Graphics_D3d12_Create_Instance(FResult* r, const FInstanceCreateOptions& options, FInstance** out) { - return new D3d12Instance(); + *r = feb([&] + { + *out = new D3d12Instance(options); + }); } diff --git a/Coplt.Graphics.Native/D3d12/Src/Output.cc b/Coplt.Graphics.Native/D3d12/Src/Output.cc index 56d253a..d4aa121 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Output.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Output.cc @@ -130,7 +130,7 @@ D3d12GpuSwapChainOutput::D3d12GpuSwapChainOutput( } ComPtr swap_chain; - chr | m_device->m_factory->CreateSwapChainForHwnd( + chr | m_device->m_instance->m_factory->CreateSwapChainForHwnd( m_dx_queue.Get(), hwnd, &desc, diff --git a/Examples/ExampleBase/ExampleBase.cs b/Examples/ExampleBase/ExampleBase.cs index 90abbab..1fe687a 100644 --- a/Examples/ExampleBase/ExampleBase.cs +++ b/Examples/ExampleBase/ExampleBase.cs @@ -23,12 +23,21 @@ public void DoInitGraphics() { try { - Graphics = GraphicsInstance.LoadD3d12(); + Graphics = GraphicsInstance.LoadD3d12(Debug: true); Graphics.SetLogger( (level, _) => Log.IsEnabled(level.ToLogEventLevel()), (level, scope, msg) => Log.Write(level.ToLogEventLevel(), "[{Scope}] {Msg}", scope, msg) ); - Device = Graphics.CreateDevice(Debug: true, Name: "Main Device"); + Device = Graphics.CreateDevice(Name: "Main Device"); + var Adapter = Device.Adapter; + Log.Information( + "Selected device: {@Info}", + new + { + Adapter.Name, Adapter.VendorId, Adapter.DeviceId, Adapter.Driver, Adapter.Backend, + Adapter.Features.ShaderModelLevel + } + ); Output = Device.MainQueue.CreateOutputForHwnd( new() { From fde242aa6b2445ead383e65277facfe6be8b9a9e Mon Sep 17 00:00:00 2001 From: U2A5F Date: Thu, 27 Feb 2025 23:04:25 +0800 Subject: [PATCH 14/23] save --- Coplt.Graphics.Core/Core/GpuAdapter.cs | 27 ++++++++++++++++++++ Coplt.Graphics.Core/Core/GpuDevice.cs | 4 +-- Coplt.Graphics.Core/Core/GraphicsInstance.cs | 14 +++++----- Coplt.Graphics.Core/Native/Native.cs | 20 ++++++++++----- Coplt.Graphics.Native/Api/FFI/Device.h | 4 +++ Coplt.Graphics.Native/Api/FFI/Instance.h | 4 +-- Coplt.Graphics.Native/D3d12/Src/Instance.cc | 2 +- Coplt.Graphics.Native/D3d12/Src/Instance.h | 2 +- 8 files changed, 57 insertions(+), 20 deletions(-) diff --git a/Coplt.Graphics.Core/Core/GpuAdapter.cs b/Coplt.Graphics.Core/Core/GpuAdapter.cs index 1738b43..e54c54b 100644 --- a/Coplt.Graphics.Core/Core/GpuAdapter.cs +++ b/Coplt.Graphics.Core/Core/GpuAdapter.cs @@ -1,5 +1,6 @@ using Coplt.Dropping; using Coplt.Graphics.Native; +using Coplt.Graphics.Utilities; namespace Coplt.Graphics.Core; @@ -61,4 +62,30 @@ public override string ToString() => string.IsNullOrEmpty(Name) : $"{nameof(GpuAdapter)}({Name})"; #endregion + + #region CreateDevice + + public GpuDevice CreateDevice( + string? Name = null, ReadOnlySpan Name8 = default + ) + { + var QueueName = !Instance.DebugEnabled || Name is null ? null : $"{Name} Main Queue"; + var QueueName8 = !Instance.DebugEnabled || Name8.Length == 0 + ? Name8 + : Utils.JoinUtf8String(Name8, " Main Queue"u8); + + fixed (char* p_name = Name) + fixed (byte* p_name8 = Name8) + { + FGpuDeviceCreateOptions f_options = new() + { + Name = new(Name, Name8, p_name, p_name8), + }; + FGpuDevice* ptr; + m_ptr->CreateDevice(&f_options, &ptr).TryThrow(); + return new(ptr, Instance, this, Name, QueueName: QueueName, QueueName8: QueueName8); + } + } + + #endregion } diff --git a/Coplt.Graphics.Core/Core/GpuDevice.cs b/Coplt.Graphics.Core/Core/GpuDevice.cs index 426f154..90ab6b5 100644 --- a/Coplt.Graphics.Core/Core/GpuDevice.cs +++ b/Coplt.Graphics.Core/Core/GpuDevice.cs @@ -36,7 +36,7 @@ public sealed unsafe partial class GpuDevice #region Ctor internal GpuDevice( - FGpuDevice* ptr, GraphicsInstance instance, + FGpuDevice* ptr, GraphicsInstance instance, GpuAdapter? adapter, string? name, string? QueueName = null, ReadOnlySpan QueueName8 = default ) { @@ -44,7 +44,7 @@ internal GpuDevice( m_name = name; m_ptr = ptr; m_main_queue = CreateMainQueue(Name: QueueName, Name8: QueueName8); - m_adapter = m_instance.m_ptr_to_adapters[(nuint)m_ptr->GetAdapter()]; + m_adapter = adapter ?? m_instance.m_ptr_to_adapters[(nuint)m_ptr->GetAdapter()]; } #endregion diff --git a/Coplt.Graphics.Core/Core/GraphicsInstance.cs b/Coplt.Graphics.Core/Core/GraphicsInstance.cs index fc82903..5789ee2 100644 --- a/Coplt.Graphics.Core/Core/GraphicsInstance.cs +++ b/Coplt.Graphics.Core/Core/GraphicsInstance.cs @@ -320,15 +320,15 @@ public GpuDevice CreateDevice( fixed (char* p_name = Name) fixed (byte* p_name8 = Name8) { - FGpuDeviceCreateOptions f_options = new() + FGpuAutoSelectDeviceCreateOptions f_options = new() { - Name = new(Name, Name8, p_name, p_name8), - Requires = new() + Base = { Name = new(Name, Name8, p_name, p_name8) }, + Requires = { D3dFeatureLevel = (FD3dFeatureLevel)requires.D3dFeatureLevel, VulkanVersion = (FVulkanVersion)requires.VulkanVersion, DeviceType = (FDeviceTypeRequire)requires.DeviceType, - FeatureRequires = new() + FeatureRequires = { ShaderModelLevel = (FShaderModelLevel)requires.FeatureRequires.ShaderModelLevel, RayTracing = requires.FeatureRequires.RayTracing, @@ -337,12 +337,12 @@ public GpuDevice CreateDevice( EnhancedBarriers = requires.FeatureRequires.EnhancedBarriers, ArrBindless = requires.FeatureRequires.ArrBindless, DynBindless = requires.FeatureRequires.DynBindless, - } - } + }, + }, }; FGpuDevice* ptr; m_ptr->CreateDevice(&f_options, &ptr).TryThrow(); - return new(ptr, this, Name, QueueName: QueueName, QueueName8: QueueName8); + return new(ptr, this, null, Name, QueueName: QueueName, QueueName8: QueueName8); } } diff --git a/Coplt.Graphics.Core/Native/Native.cs b/Coplt.Graphics.Core/Native/Native.cs index da9c19a..6536f44 100644 --- a/Coplt.Graphics.Core/Native/Native.cs +++ b/Coplt.Graphics.Core/Native/Native.cs @@ -724,14 +724,14 @@ public partial struct FGpuAdapter { } - public partial struct FGpuDeviceCreateOptions + public partial struct FGpuAutoSelectDeviceCreateOptions { } - public partial struct FGpuDeviceCreateOptions + [NativeTypeName("struct FGpuAutoSelectDeviceCreateOptions : Coplt::FGpuDeviceCreateOptions")] + public partial struct FGpuAutoSelectDeviceCreateOptions { - [NativeTypeName("Coplt::FStr8or16")] - public FStr8or16 Name; + public FGpuDeviceCreateOptions Base; [NativeTypeName("Coplt::FDeviceRequires")] public FDeviceRequires Requires; @@ -1008,10 +1008,10 @@ public FResult CreateBlob([NativeTypeName("Coplt::usize")] nuint size, FBlob** @ [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NativeTypeName("Coplt::FResult")] - public FResult CreateDevice([NativeTypeName("const FGpuDeviceCreateOptions &")] FGpuDeviceCreateOptions* options, FGpuDevice** @out) + public FResult CreateDevice([NativeTypeName("const FGpuAutoSelectDeviceCreateOptions &")] FGpuAutoSelectDeviceCreateOptions* options, FGpuDevice** @out) { FResult result; - return *((delegate* unmanaged[Thiscall])(lpVtbl[9]))((FInstance*)Unsafe.AsPointer(ref this), &result, options, @out); + return *((delegate* unmanaged[Thiscall])(lpVtbl[9]))((FInstance*)Unsafe.AsPointer(ref this), &result, options, @out); } public interface Interface : FUnknown.Interface @@ -1032,7 +1032,7 @@ public interface Interface : FUnknown.Interface FGpuAdapter** GetAdapters([NativeTypeName("Coplt::u32 *")] uint* out_count); [return: NativeTypeName("Coplt::FResult")] - FResult CreateDevice([NativeTypeName("const FGpuDeviceCreateOptions &")] FGpuDeviceCreateOptions* options, FGpuDevice** @out); + FResult CreateDevice([NativeTypeName("const FGpuAutoSelectDeviceCreateOptions &")] FGpuAutoSelectDeviceCreateOptions* options, FGpuDevice** @out); } } @@ -1154,6 +1154,12 @@ public partial struct FDeviceRequires public FDeviceFeatureRequires FeatureRequires; } + public partial struct FGpuDeviceCreateOptions + { + [NativeTypeName("Coplt::FStr8or16")] + public FStr8or16 Name; + } + [NativeTypeName("Coplt::u8")] public enum FShaderStage : byte { diff --git a/Coplt.Graphics.Native/Api/FFI/Device.h b/Coplt.Graphics.Native/Api/FFI/Device.h index b058d69..7cc3655 100644 --- a/Coplt.Graphics.Native/Api/FFI/Device.h +++ b/Coplt.Graphics.Native/Api/FFI/Device.h @@ -59,6 +59,10 @@ namespace Coplt { // 可选 FStr8or16 Name{}; + }; + + struct FGpuAutoSelectDeviceCreateOptions : FGpuDeviceCreateOptions + { FDeviceRequires Requires{}; }; diff --git a/Coplt.Graphics.Native/Api/FFI/Instance.h b/Coplt.Graphics.Native/Api/FFI/Instance.h index 4bd19c5..b3dac0b 100644 --- a/Coplt.Graphics.Native/Api/FFI/Instance.h +++ b/Coplt.Graphics.Native/Api/FFI/Instance.h @@ -24,7 +24,7 @@ namespace Coplt }; struct FGpuAdapter; - struct FGpuDeviceCreateOptions; + struct FGpuAutoSelectDeviceCreateOptions; struct FGpuDevice; struct FInstanceCreateOptions @@ -48,6 +48,6 @@ namespace Coplt virtual FResult CreateBlob(usize size, FBlob** out) noexcept = 0; virtual FGpuAdapter* const* GetAdapters(u32* out_count) noexcept = 0; - virtual FResult CreateDevice(const FGpuDeviceCreateOptions& options, FGpuDevice** out) noexcept = 0; + virtual FResult CreateDevice(const FGpuAutoSelectDeviceCreateOptions& options, FGpuDevice** out) noexcept = 0; }; } diff --git a/Coplt.Graphics.Native/D3d12/Src/Instance.cc b/Coplt.Graphics.Native/D3d12/Src/Instance.cc index 42017ea..88cec45 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Instance.cc +++ b/Coplt.Graphics.Native/D3d12/Src/Instance.cc @@ -77,7 +77,7 @@ void D3d12Instance::CreateAdapter(ComPtr&& adapter) m_adapters.push_back(new D3d12GpuAdapter(this->CloneThis(), std::move(adapter))); } -FResult D3d12Instance::CreateDevice(const FGpuDeviceCreateOptions& options, FGpuDevice** out) noexcept +FResult D3d12Instance::CreateDevice(const FGpuAutoSelectDeviceCreateOptions& options, FGpuDevice** out) noexcept { return feb([&] { diff --git a/Coplt.Graphics.Native/D3d12/Src/Instance.h b/Coplt.Graphics.Native/D3d12/Src/Instance.h index 7ed68c0..5c0dfc3 100644 --- a/Coplt.Graphics.Native/D3d12/Src/Instance.h +++ b/Coplt.Graphics.Native/D3d12/Src/Instance.h @@ -26,7 +26,7 @@ namespace Coplt void CreateAdapter(ComPtr&& adapter); - FResult CreateDevice(const FGpuDeviceCreateOptions& options, FGpuDevice** out) noexcept override; + FResult CreateDevice(const FGpuAutoSelectDeviceCreateOptions& options, FGpuDevice** out) noexcept override; FGpuAdapter* const* GetAdapters(u32* out_count) noexcept override; From 8852be7a8d92406250736dd1c7186e400abed19f Mon Sep 17 00:00:00 2001 From: U2A5F Date: Fri, 28 Feb 2025 00:36:20 +0800 Subject: [PATCH 15/23] save --- .idea/codeStyles/Project.xml | 1 - Coplt.Graphics.Core/Core/CommandList.cs | 119 +++++++++++- Coplt.Graphics.Core/Native/Native.cs | 234 ++++++++++++++++++++---- Coplt.Graphics.Native/Api/FFI/Command.h | 104 +++++++++-- Coplt.Graphics.Native/Api/FFI/Shader.h | 2 +- Coplt.Graphics.Native/Api/FFI/States.h | 32 +--- 6 files changed, 404 insertions(+), 88 deletions(-) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 0c8e3aa..87250ae 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -2,7 +2,6 @@ diff --git a/Coplt.Graphics.Core/Core/CommandList.cs b/Coplt.Graphics.Core/Core/CommandList.cs index 2c4f7a7..c59e19d 100644 --- a/Coplt.Graphics.Core/Core/CommandList.cs +++ b/Coplt.Graphics.Core/Core/CommandList.cs @@ -14,6 +14,9 @@ public enum DispatchType : byte Mesh, } +/// +/// 命令列表,不支持多线程访问 +/// public sealed unsafe class CommandList { #region Fields @@ -24,6 +27,7 @@ public sealed unsafe class CommandList internal readonly List m_compute_commands = new(); internal readonly List m_resource_metas = new(); internal readonly List m_render_infos = new(); + internal readonly List m_compute_infos = new(); internal readonly List m_resolve_infos = new(); internal readonly List m_rects = new(); internal readonly List m_viewports = new(); @@ -31,11 +35,16 @@ public sealed unsafe class CommandList internal readonly List m_vertex_buffer_ranges = new(); internal readonly List m_buffer_copy_ranges = new(); internal readonly List m_bind_items = new(); + internal readonly List m_barriers = new(); internal readonly List m_string8 = new(); internal readonly List m_string16 = new(); internal readonly Dictionary m_resources = new(); internal readonly HashSet m_objects = new(); internal GpuOutput? m_current_output; + internal bool m_in_render_or_compute_scope; + internal int m_debug_scope_count; + internal int m_render_debug_scope_count; + internal int m_compute_debug_scope_count; #endregion @@ -61,16 +70,19 @@ internal void Reset() m_commands.Clear(); m_render_commands.Clear(); m_compute_commands.Clear(); + m_resource_metas.Clear(); m_render_infos.Clear(); + m_compute_infos.Clear(); m_resolve_infos.Clear(); m_rects.Clear(); m_viewports.Clear(); m_mesh_buffers.Clear(); m_vertex_buffer_ranges.Clear(); m_buffer_copy_ranges.Clear(); + m_bind_items.Clear(); + m_barriers.Clear(); m_string8.Clear(); m_string16.Clear(); - m_resource_metas.Clear(); m_resources.Clear(); m_objects.Clear(); m_current_output = null; @@ -82,11 +94,21 @@ internal void Reset() internal void BuildSubmitStruct(GpuExecutor Executor, bool NoWait) { + if (m_debug_scope_count != 0) + throw new InvalidOperationException( + "There is still Debug scope not ended, please check whether Dispose is missed." + ); + if (m_in_render_or_compute_scope) + throw new InvalidOperationException( + "There is still Render or Compute scope not ended, please check whether Dispose is missed." + ); + fixed (FCommandItem* p_commands = CollectionsMarshal.AsSpan(m_commands)) fixed (FRenderCommandItem* p_render_commands = CollectionsMarshal.AsSpan(m_render_commands)) fixed (FComputeCommandItem* p_compute_commands = CollectionsMarshal.AsSpan(m_compute_commands)) fixed (FResourceMeta* p_resources = CollectionsMarshal.AsSpan(m_resource_metas)) fixed (FRenderInfo* p_render_infos = CollectionsMarshal.AsSpan(m_render_infos)) + fixed (FComputeInfo* p_compute_infos = CollectionsMarshal.AsSpan(m_compute_infos)) fixed (FResolveInfo* p_resolve_infos = CollectionsMarshal.AsSpan(m_resolve_infos)) fixed (FRect* p_rects = CollectionsMarshal.AsSpan(m_rects)) fixed (FViewport* p_viewports = CollectionsMarshal.AsSpan(m_viewports)) @@ -94,6 +116,7 @@ internal void BuildSubmitStruct(GpuExecutor Executor, bool NoWait) fixed (FVertexBufferRange* p_vertex_buffer_ranges = CollectionsMarshal.AsSpan(m_vertex_buffer_ranges)) fixed (FBufferCopyRange* p_buffer_copy_ranges = CollectionsMarshal.AsSpan(m_buffer_copy_ranges)) fixed (FBindItem* p_bind_items = CollectionsMarshal.AsSpan(m_bind_items)) + fixed (FBarrier* p_barriers = CollectionsMarshal.AsSpan(m_barriers)) fixed (byte* p_string8 = CollectionsMarshal.AsSpan(m_string8)) fixed (char* p_string16 = CollectionsMarshal.AsSpan(m_string16)) { @@ -104,6 +127,7 @@ internal void BuildSubmitStruct(GpuExecutor Executor, bool NoWait) ComputeCommands = p_compute_commands, Resources = p_resources, RenderInfos = p_render_infos, + ComputeInfos = p_compute_infos, ResolveInfos = p_resolve_infos, Rects = p_rects, Viewports = p_viewports, @@ -111,6 +135,7 @@ internal void BuildSubmitStruct(GpuExecutor Executor, bool NoWait) VertexBufferRanges = p_vertex_buffer_ranges, BufferCopyRanges = p_buffer_copy_ranges, BindItems = p_bind_items, + Barriers = p_barriers, Str8 = p_string8, Str16 = p_string16, CommandCount = (uint)m_commands.Count, @@ -220,6 +245,7 @@ public DebugScope Scope(string Name) StrType = FStrType.Str16, }; m_commands.Add(new() { Label = cmd }); + m_debug_scope_count++; return new(this); } @@ -233,6 +259,7 @@ public DebugScope Scope(ReadOnlySpan Name) StrType = FStrType.Str8, }; m_commands.Add(new() { Label = cmd }); + m_debug_scope_count++; return new(this); } @@ -508,6 +535,13 @@ public RenderScope Render( string? Name = null, ReadOnlySpan Name8 = default ) { + #region Check Nested + + if (m_in_render_or_compute_scope) throw new InvalidOperationException("Cannot nest Render or Compute scopes"); + m_in_render_or_compute_scope = true; + + #endregion + #region Check Args if (Info.Dsv == null && Info.Rtvs.Length == 0) throw new ArgumentException("No any rtv or dsv provided"); @@ -517,10 +551,11 @@ public RenderScope Render( #region Cmd + var info_index = m_render_infos.Count; var cmd = new FCommandRender { Base = { Type = FCommandType.Render }, - InfoIndex = (uint)m_render_infos.Count, + InfoIndex = (uint)info_index, CommandStartIndex = (uint)m_render_commands.Count, }; @@ -655,7 +690,7 @@ public RenderScope Render( #region Scope - RenderScope scope = new(this, m_render_commands, debug_scope); + RenderScope scope = new(this, info_index, m_render_commands.Count, m_render_commands, debug_scope); #endregion @@ -680,6 +715,15 @@ public RenderScope Render( public ComputeScope Compute(string? Name = null, ReadOnlySpan Name8 = default) { + #region Check Nested + + if (m_in_render_or_compute_scope) throw new InvalidOperationException("Cannot nest Render or Compute scopes"); + m_in_render_or_compute_scope = true; + + #endregion + + #region Debug + var debug_scope = false; if (Name != null) { @@ -691,13 +735,24 @@ public ComputeScope Compute(string? Name = null, ReadOnlySpan Name8 = defa debug_scope = true; Scope(Name8); } + + #endregion + + #region Cmd and Scope + + var info_index = m_compute_infos.Count; + m_compute_infos.Add(new()); + var cmd = new FCommandCompute { Base = { Type = FCommandType.Compute }, + InfoIndex = (uint)info_index, CommandStartIndex = (uint)m_compute_commands.Count, }; m_commands.Add(new() { Compute = cmd }); - return new(this, m_compute_commands, debug_scope); + return new(this, info_index, m_compute_commands.Count, m_compute_commands, debug_scope); + + #endregion } #endregion @@ -707,39 +762,51 @@ public ComputeScope Compute(string? Name = null, ReadOnlySpan Name8 = defa #region DebugScope -public readonly struct DebugScope(CommandList self) : IDisposable +public struct DebugScope(CommandList self) : IDisposable { + private bool m_disposed; public void Dispose() { + if (m_disposed) throw new ObjectDisposedException(nameof(ComputeScope)); + m_disposed = true; var cmd = new FCommandEndScope { Base = { Type = FCommandType.EndScope }, }; self.m_commands.Add(new() { EndScope = cmd }); + self.m_debug_scope_count--; } } -public readonly struct RenderDebugScope(CommandList self) : IDisposable +public struct RenderDebugScope(CommandList self) : IDisposable { + private bool m_disposed; public void Dispose() { + if (m_disposed) throw new ObjectDisposedException(nameof(ComputeScope)); + m_disposed = true; var cmd = new FCommandEndScope { Base = { Type = FCommandType.EndScope }, }; self.m_render_commands.Add(new() { EndScope = cmd }); + self.m_render_debug_scope_count--; } } -public readonly struct ComputeDebugScope(CommandList self) : IDisposable +public struct ComputeDebugScope(CommandList self) : IDisposable { + private bool m_disposed; public void Dispose() { + if (m_disposed) throw new ObjectDisposedException(nameof(ComputeScope)); + m_disposed = true; var cmd = new FCommandEndScope { Base = { Type = FCommandType.EndScope }, }; self.m_compute_commands.Add(new() { EndScope = cmd }); + self.m_compute_debug_scope_count--; } } @@ -853,6 +920,8 @@ public RtvInfo(IRtvRes View, LoadOp Load) : this(View, Load, StoreOp.Sto public unsafe struct RenderScope( CommandList self, + int info_index, + int cmd_index, List m_commands, bool debug_scope ) : IDisposable @@ -861,6 +930,13 @@ bool debug_scope private ShaderPipeline? m_current_pipeline; private ShaderBinding? m_current_binding; + private bool m_disposed; + + #endregion + + #region Props + + internal ref FRenderInfo Info => ref CollectionsMarshal.AsSpan(self.m_render_infos)[info_index]; #endregion @@ -868,7 +944,15 @@ bool debug_scope public void Dispose() { + if (m_disposed) throw new ObjectDisposedException(nameof(ComputeScope)); + m_disposed = true; + if (self.m_render_debug_scope_count != 0) + throw new InvalidOperationException( + "There is still Debug scope not ended, please check whether Dispose is missed." + ); + Info.CommandCount = (uint)m_commands.Count - (uint)cmd_index; self.m_render_commands.Add(new() { Type = FCommandType.End }); + self.m_in_render_or_compute_scope = false; if (debug_scope) new DebugScope(self).Dispose(); } @@ -916,6 +1000,7 @@ public RenderDebugScope Scope(string Name) StrType = FStrType.Str16, }; m_commands.Add(new() { Label = cmd }); + self.m_render_debug_scope_count++; return new(self); } @@ -929,6 +1014,7 @@ public RenderDebugScope Scope(ReadOnlySpan Name) StrType = FStrType.Str8, }; m_commands.Add(new() { Label = cmd }); + self.m_render_debug_scope_count++; return new(self); } @@ -1186,6 +1272,8 @@ public void DispatchMesh( public unsafe struct ComputeScope( CommandList self, + int info_index, + int cmd_index, List m_commands, bool debug_scope ) : IDisposable @@ -1194,6 +1282,13 @@ bool debug_scope private ShaderPipeline? m_current_pipeline; private ShaderBinding? m_current_binding; + private bool m_disposed; + + #endregion + + #region Props + + internal ref FComputeInfo Info => ref CollectionsMarshal.AsSpan(self.m_compute_infos)[info_index]; #endregion @@ -1201,7 +1296,15 @@ bool debug_scope public void Dispose() { + if (m_disposed) throw new ObjectDisposedException(nameof(ComputeScope)); + m_disposed = true; + if (self.m_compute_debug_scope_count != 0) + throw new InvalidOperationException( + "There is still Debug scope not ended, please check whether Dispose is missed." + ); + Info.CommandCount = (uint)m_commands.Count - (uint)cmd_index; self.m_compute_commands.Add(new() { Type = FCommandType.End }); + self.m_in_render_or_compute_scope = false; if (debug_scope) new DebugScope(self).Dispose(); } @@ -1249,6 +1352,7 @@ public ComputeDebugScope Scope(string Name) StrType = FStrType.Str16, }; m_commands.Add(new() { Label = cmd }); + self.m_compute_debug_scope_count++; return new(self); } @@ -1262,6 +1366,7 @@ public ComputeDebugScope Scope(ReadOnlySpan Name) StrType = FStrType.Str8, }; m_commands.Add(new() { Label = cmd }); + self.m_compute_debug_scope_count++; return new(self); } diff --git a/Coplt.Graphics.Core/Native/Native.cs b/Coplt.Graphics.Core/Native/Native.cs index 6536f44..7625f89 100644 --- a/Coplt.Graphics.Core/Native/Native.cs +++ b/Coplt.Graphics.Core/Native/Native.cs @@ -1170,8 +1170,8 @@ public enum FShaderStage : byte Task = 4, } - [NativeTypeName("Coplt::u8")] - public enum FShaderStageFlags : byte + [NativeTypeName("Coplt::u32")] + public enum FShaderStageFlags : uint { None = 0, Compute = 1 << 0, @@ -2326,6 +2326,9 @@ public unsafe partial struct FCommandSubmit [NativeTypeName("Coplt::FRenderInfo *")] public FRenderInfo* RenderInfos; + [NativeTypeName("Coplt::FComputeInfo *")] + public FComputeInfo* ComputeInfos; + [NativeTypeName("Coplt::FResolveInfo *")] public FResolveInfo* ResolveInfos; @@ -2347,6 +2350,9 @@ public unsafe partial struct FCommandSubmit [NativeTypeName("Coplt::FBindItem *")] public FBindItem* BindItems; + [NativeTypeName("Coplt::FBarrier *")] + public FBarrier* Barriers; + [NativeTypeName("Coplt::Char8 *")] public byte* Str8; @@ -2632,33 +2638,6 @@ public enum FResAccess : uint VideoEncodeWrite = 1 << 22, } - [NativeTypeName("Coplt::u32")] - public enum FResUsage : uint - { - None = 0, - All = 1 << 0, - Draw = 1 << 1, - IndexInput = 1 << 2, - VertexShading = 1 << 3, - PixelShading = 1 << 4, - DepthStencil = 1 << 5, - RenderTarget = 1 << 6, - ComputeShading = 1 << 7, - RayTracing = 1 << 8, - Copy = 1 << 9, - Resolve = 1 << 10, - ExecuteIndirectOrPredication = 1 << 11, - AllShading = 1 << 12, - NonPixelShading = 1 << 13, - EmitRayTracingAccelerationStructurePostBuildInfo = 1 << 14, - ClearUAV = 1 << 15, - BuildRayTracingAccelerationStructure = 1 << 16, - CopyRayTracingAccelerationStructure = 1 << 17, - VideoDecode = 1 << 18, - VideoProcess = 1 << 19, - VideoEncode = 1 << 20, - } - public partial struct FResState { [NativeTypeName("Coplt::FResLayout")] @@ -2667,8 +2646,8 @@ public partial struct FResState [NativeTypeName("Coplt::FResAccess")] public FResAccess Access; - [NativeTypeName("Coplt::FResUsage")] - public FResUsage Usage; + [NativeTypeName("Coplt::FShaderStageFlags")] + public FShaderStageFlags Stages; } [NativeTypeName("Coplt::u32")] @@ -2753,19 +2732,180 @@ public partial struct FResourceRef public uint ResourceIndex; } + public partial struct FSubResourceRange + { + [NativeTypeName("Coplt::u32")] + public uint IndexOrFirstMipLevel; + + [NativeTypeName("Coplt::u32")] + public uint NumMipLevels; + + [NativeTypeName("Coplt::u32")] + public uint FirstArraySlices; + + [NativeTypeName("Coplt::u32")] + public uint NumArraySlices; + + [NativeTypeName("Coplt::u32")] + public uint FirstPlane; + + [NativeTypeName("Coplt::u32")] + public uint NumPlanes; + } + + [NativeTypeName("Coplt::u32")] + public enum FImageBarrierFlags : uint + { + None, + Discard, + } + + public partial struct FImageBarrier + { + [NativeTypeName("Coplt::FResAccess")] + public FResAccess AccessBefore; + + [NativeTypeName("Coplt::FResAccess")] + public FResAccess AccessAfter; + + [NativeTypeName("Coplt::FShaderStageFlags")] + public FShaderStageFlags StagesBefore; + + [NativeTypeName("Coplt::FShaderStageFlags")] + public FShaderStageFlags StagesAfter; + + [NativeTypeName("Coplt::FResLayout")] + public FResLayout LayoutBefore; + + [NativeTypeName("Coplt::FResLayout")] + public FResLayout LayoutAfter; + + [NativeTypeName("Coplt::FResourceRef")] + public FResourceRef Image; + + [NativeTypeName("Coplt::FSubResourceRange")] + public FSubResourceRange SubResourceRange; + + [NativeTypeName("Coplt::FImageBarrierFlags")] + public FImageBarrierFlags Flags; + } + + public partial struct FBufferBarrier + { + [NativeTypeName("Coplt::FResAccess")] + public FResAccess AccessBefore; + + [NativeTypeName("Coplt::FResAccess")] + public FResAccess AccessAfter; + + [NativeTypeName("Coplt::FShaderStageFlags")] + public FShaderStageFlags StagesBefore; + + [NativeTypeName("Coplt::FShaderStageFlags")] + public FShaderStageFlags StagesAfter; + + [NativeTypeName("Coplt::FResourceRef")] + public FResourceRef Buffer; + + [NativeTypeName("Coplt::u64")] + public ulong Offset; + + [NativeTypeName("Coplt::u64")] + public ulong Size; + } + + public partial struct FGlobalBarrier + { + [NativeTypeName("Coplt::FResAccess")] + public FResAccess AccessBefore; + + [NativeTypeName("Coplt::FResAccess")] + public FResAccess AccessAfter; + + [NativeTypeName("Coplt::FShaderStageFlags")] + public FShaderStageFlags StagesBefore; + + [NativeTypeName("Coplt::FShaderStageFlags")] + public FShaderStageFlags StagesAfter; + } + + [NativeTypeName("Coplt::u8")] + public enum FBarrierType : byte + { + None, + Global, + Buffer, + Image, + } + + public partial struct FBarrier + { + [NativeTypeName("Coplt::FBarrierType")] + public FBarrierType Type; + + [NativeTypeName("__AnonymousRecord_Command_L164_C9")] + public _Anonymous_e__Union Anonymous; + + [UnscopedRef] + public ref FGlobalBarrier Global + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.Global; + } + } + + [UnscopedRef] + public ref FBufferBarrier Buffer + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.Buffer; + } + } + + [UnscopedRef] + public ref FImageBarrier Image + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return ref Anonymous.Image; + } + } + + [StructLayout(LayoutKind.Explicit)] + public partial struct _Anonymous_e__Union + { + [FieldOffset(0)] + [NativeTypeName("Coplt::FGlobalBarrier")] + public FGlobalBarrier Global; + + [FieldOffset(0)] + [NativeTypeName("Coplt::FBufferBarrier")] + public FBufferBarrier Buffer; + + [FieldOffset(0)] + [NativeTypeName("Coplt::FImageBarrier")] + public FImageBarrier Image; + } + } + public partial struct FRect { [NativeTypeName("Coplt::u32")] - public uint left; + public uint Left; [NativeTypeName("Coplt::u32")] - public uint top; + public uint Top; [NativeTypeName("Coplt::u32")] - public uint right; + public uint Right; [NativeTypeName("Coplt::u32")] - public uint bottom; + public uint Bottom; } public partial struct FViewport @@ -2890,6 +3030,9 @@ public enum FStoreOp : byte public partial struct FRenderInfo { + [NativeTypeName("Coplt::u32")] + public uint CommandCount; + [NativeTypeName("Coplt::FResourceRef")] public FResourceRef Dsv; @@ -2966,6 +3109,12 @@ public partial struct _RtvStoreOp_e__FixedBuffer } } + public partial struct FComputeInfo + { + [NativeTypeName("Coplt::u32")] + public uint CommandCount; + } + public partial struct FBufferRange { [NativeTypeName("Coplt::FResourceRef")] @@ -3064,6 +3213,12 @@ public partial struct FCommandPresent public partial struct FCommandBarrier { public FCommandBase Base; + + [NativeTypeName("Coplt::u32")] + public uint BarrierIndex; + + [NativeTypeName("Coplt::u32")] + public uint BarrierCount; } [NativeTypeName("struct FCommandClearColor : Coplt::FCommandBase")] @@ -3167,6 +3322,9 @@ public partial struct FCommandCompute { public FCommandBase Base; + [NativeTypeName("Coplt::u32")] + public uint InfoIndex; + [NativeTypeName("Coplt::u32")] public uint CommandStartIndex; } @@ -3266,7 +3424,7 @@ public partial struct FCommandDispatch public partial struct FCommandItem { - [NativeTypeName("__AnonymousRecord_Command_L404_C9")] + [NativeTypeName("__AnonymousRecord_Command_L482_C9")] public _Anonymous_e__Union Anonymous; [UnscopedRef] @@ -3464,7 +3622,7 @@ public partial struct __pad_e__FixedBuffer public partial struct FRenderCommandItem { - [NativeTypeName("__AnonymousRecord_Command_L432_C9")] + [NativeTypeName("__AnonymousRecord_Command_L510_C9")] public _Anonymous_e__Union Anonymous; [UnscopedRef] @@ -3634,7 +3792,7 @@ public partial struct __pad_e__FixedBuffer public partial struct FComputeCommandItem { - [NativeTypeName("__AnonymousRecord_Command_L455_C9")] + [NativeTypeName("__AnonymousRecord_Command_L533_C9")] public _Anonymous_e__Union Anonymous; [UnscopedRef] diff --git a/Coplt.Graphics.Native/Api/FFI/Command.h b/Coplt.Graphics.Native/Api/FFI/Command.h index 68ff9e6..15d2c0c 100644 --- a/Coplt.Graphics.Native/Api/FFI/Command.h +++ b/Coplt.Graphics.Native/Api/FFI/Command.h @@ -61,7 +61,7 @@ namespace Coplt { union { - FGpuOutput* Output; + FGpuOutput* Output{}; FGpuBuffer* Buffer; // todo other }; @@ -69,7 +69,7 @@ namespace Coplt FLegacyState CurrentState{}; FResourceRefType Type{}; -#ifdef FFI_SRC + #ifdef FFI_SRC FUnknown* GetObjectPtr() const { switch (Type) @@ -83,7 +83,7 @@ namespace Coplt } return nullptr; } -#endif + #endif }; struct FResourceRef @@ -91,22 +91,90 @@ namespace Coplt // u32::max 表示 empty u32 ResourceIndex{}; -#ifdef FFI_SRC + #ifdef FFI_SRC FResourceMeta& Get(const FCommandSubmit& submit) const; bool IsEmpty() const { return ResourceIndex == 0; } -#endif + #endif + }; + + struct FSubResourceRange + { + u32 IndexOrFirstMipLevel{}; + u32 NumMipLevels{}; + u32 FirstArraySlices{}; + u32 NumArraySlices{}; + u32 FirstPlane{}; + u32 NumPlanes{}; + }; + + COPLT_ENUM_FLAGS(FImageBarrierFlags, u32) + { + None, + Discard, + }; + + struct FImageBarrier + { + FResAccess AccessBefore{}; + FResAccess AccessAfter{}; + FShaderStageFlags StagesBefore{}; + FShaderStageFlags StagesAfter{}; + FResLayout LayoutBefore{}; + FResLayout LayoutAfter{}; + FResourceRef Image{}; + FSubResourceRange SubResourceRange{}; + FImageBarrierFlags Flags{}; + }; + + struct FBufferBarrier + { + FResAccess AccessBefore{}; + FResAccess AccessAfter{}; + FShaderStageFlags StagesBefore{}; + FShaderStageFlags StagesAfter{}; + FResourceRef Buffer{}; + u64 Offset{}; + u64 Size{}; + }; + + struct FGlobalBarrier + { + FResAccess AccessBefore{}; + FResAccess AccessAfter{}; + FShaderStageFlags StagesBefore{}; + FShaderStageFlags StagesAfter{}; + }; + + enum class FBarrierType : u8 + { + None, + Global, + Buffer, + Image, + }; + + struct FBarrier + { + FBarrierType Type{}; + + union + { + FGlobalBarrier Global; + FBufferBarrier Buffer; + FImageBarrier Image; + }; }; struct FRect { - u32 left; - u32 top; - u32 right; - u32 bottom; + u32 Left; + u32 Top; + u32 Right; + u32 Bottom; }; struct FViewport @@ -194,6 +262,7 @@ namespace Coplt struct FRenderInfo { + u32 CommandCount{}; // 可选 FResourceRef Dsv{}; u32 NumRtv{}; @@ -209,6 +278,11 @@ namespace Coplt FStoreOp RtvStoreOp[8]{}; }; + struct FComputeInfo + { + u32 CommandCount{}; + }; + struct FBufferRange { FResourceRef Buffer{}; @@ -276,7 +350,9 @@ namespace Coplt struct FCommandBarrier : FCommandBase { - // todo + // Payload 内的索引,类型为 FBarrier + u32 BarrierIndex{}; + u32 BarrierCount{}; }; //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -338,6 +414,8 @@ namespace Coplt struct FCommandCompute : FCommandBase { + // 类型为 FComputeInfo + u32 InfoIndex{}; u32 CommandStartIndex{}; }; @@ -478,6 +556,7 @@ namespace Coplt FComputeCommandItem* ComputeCommands{}; FResourceMeta* Resources{}; FRenderInfo* RenderInfos{}; + FComputeInfo* ComputeInfos{}; FResolveInfo* ResolveInfos{}; FRect* Rects{}; FViewport* Viewports{}; @@ -485,6 +564,7 @@ namespace Coplt FVertexBufferRange* VertexBufferRanges{}; FBufferCopyRange* BufferCopyRanges{}; FBindItem* BindItems{}; + FBarrier* Barriers{}; Char8* Str8{}; Char16* Str16{}; u32 CommandCount{}; @@ -493,12 +573,12 @@ namespace Coplt //////////////////////////////////////////////////////////////////////////////////////////////////// -#ifdef FFI_SRC + #ifdef FFI_SRC inline FResourceMeta& FResourceRef::Get(const FCommandSubmit& submit) const { return submit.Resources[ResourceIndex - 1]; } -#endif + #endif } diff --git a/Coplt.Graphics.Native/Api/FFI/Shader.h b/Coplt.Graphics.Native/Api/FFI/Shader.h index 6ae15f6..ce254e0 100644 --- a/Coplt.Graphics.Native/Api/FFI/Shader.h +++ b/Coplt.Graphics.Native/Api/FFI/Shader.h @@ -14,7 +14,7 @@ namespace Coplt Task = 4, }; - COPLT_ENUM_FLAGS(FShaderStageFlags, u8) + COPLT_ENUM_FLAGS(FShaderStageFlags, u32) { None = 0, Compute = 1 << 0, diff --git a/Coplt.Graphics.Native/Api/FFI/States.h b/Coplt.Graphics.Native/Api/FFI/States.h index 894def2..dec0bb2 100644 --- a/Coplt.Graphics.Native/Api/FFI/States.h +++ b/Coplt.Graphics.Native/Api/FFI/States.h @@ -53,7 +53,7 @@ namespace Coplt FLegacyState::IndexBuffer | FLegacyState::VertexBuffer | FLegacyState::ConstantBuffer | FLegacyState::IndirectBuffer | FLegacyState::CopySrc | FLegacyState::ResolveSrc | FLegacyState::ShaderResource | FLegacyState::DepthRead - ); + ); } inline bool IsCompatible(const FLegacyState value, const FLegacyState other) @@ -130,36 +130,10 @@ namespace Coplt VideoEncodeWrite = 1 << 22, }; - COPLT_ENUM_FLAGS(FResUsage, u32) - { - None = 0, - All = 1 << 0, - Draw = 1 << 1, - IndexInput = 1 << 2, - VertexShading = 1 << 3, - PixelShading = 1 << 4, - DepthStencil = 1 << 5, - RenderTarget = 1 << 6, - ComputeShading = 1 << 7, - RayTracing = 1 << 8, - Copy = 1 << 9, - Resolve = 1 << 10, - ExecuteIndirectOrPredication = 1 << 11, - AllShading = 1 << 12, - NonPixelShading = 1 << 13, - EmitRayTracingAccelerationStructurePostBuildInfo = 1 << 14, - ClearUAV = 1 << 15, - BuildRayTracingAccelerationStructure = 1 << 16, - CopyRayTracingAccelerationStructure = 1 << 17, - VideoDecode = 1 << 18, - VideoProcess = 1 << 19, - VideoEncode = 1 << 20, - }; - struct FResState { FResLayout Layout{}; FResAccess Access{}; - FResUsage Usage{}; + FShaderStageFlags Stages{}; }; -}; +} From 6e67328241854115d749185d0ab9d9b547445814 Mon Sep 17 00:00:00 2001 From: U2A5F Date: Fri, 28 Feb 2025 00:45:26 +0800 Subject: [PATCH 16/23] save --- Coplt.Graphics.Core/Core/CommandList.cs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Coplt.Graphics.Core/Core/CommandList.cs b/Coplt.Graphics.Core/Core/CommandList.cs index c59e19d..83819d1 100644 --- a/Coplt.Graphics.Core/Core/CommandList.cs +++ b/Coplt.Graphics.Core/Core/CommandList.cs @@ -21,6 +21,7 @@ public sealed unsafe class CommandList { #region Fields + internal readonly GraphicsInstance m_instance; internal readonly GpuQueue m_queue; internal readonly List m_commands = new(); internal readonly List m_render_commands = new(); @@ -51,14 +52,16 @@ public sealed unsafe class CommandList #region Props public GpuQueue Queue => m_queue; + public bool DebugEnabled => m_instance.DebugEnabled; #endregion #region Ctor - internal CommandList(GpuQueue mQueue) + internal CommandList(GpuQueue queue) { - m_queue = mQueue; + m_queue = queue; + m_instance = queue.Device.Instance; } #endregion @@ -209,6 +212,7 @@ internal uint AddString(ReadOnlySpan str) public void Label(string Label) { + if (!DebugEnabled) return; var cmd = new FCommandLabel { Base = { Type = FCommandType.Label }, @@ -221,6 +225,7 @@ public void Label(string Label) public void Label(ReadOnlySpan Label) { + if (!DebugEnabled) return; var cmd = new FCommandLabel { Base = { Type = FCommandType.Label }, @@ -237,6 +242,7 @@ public void Label(ReadOnlySpan Label) public DebugScope Scope(string Name) { + if (!DebugEnabled) return new(this); var cmd = new FCommandLabel { Base = { Type = FCommandType.BeginScope }, @@ -251,6 +257,7 @@ public DebugScope Scope(string Name) public DebugScope Scope(ReadOnlySpan Name) { + if (!DebugEnabled) return new(this); var cmd = new FCommandLabel { Base = { Type = FCommandType.BeginScope }, @@ -769,6 +776,7 @@ public void Dispose() { if (m_disposed) throw new ObjectDisposedException(nameof(ComputeScope)); m_disposed = true; + if (!self.DebugEnabled) return; var cmd = new FCommandEndScope { Base = { Type = FCommandType.EndScope }, @@ -785,6 +793,7 @@ public void Dispose() { if (m_disposed) throw new ObjectDisposedException(nameof(ComputeScope)); m_disposed = true; + if (!self.DebugEnabled) return; var cmd = new FCommandEndScope { Base = { Type = FCommandType.EndScope }, @@ -801,6 +810,7 @@ public void Dispose() { if (m_disposed) throw new ObjectDisposedException(nameof(ComputeScope)); m_disposed = true; + if (!self.DebugEnabled) return; var cmd = new FCommandEndScope { Base = { Type = FCommandType.EndScope }, @@ -964,6 +974,7 @@ public void Dispose() public void Label(string Label) { + if (!self.DebugEnabled) return; var cmd = new FCommandLabel { Base = { Type = FCommandType.Label }, @@ -976,6 +987,7 @@ public void Label(string Label) public void Label(ReadOnlySpan Label) { + if (!self.DebugEnabled) return; var cmd = new FCommandLabel { Base = { Type = FCommandType.EndScope }, @@ -992,6 +1004,7 @@ public void Label(ReadOnlySpan Label) public RenderDebugScope Scope(string Name) { + if (!self.DebugEnabled) return new(self); var cmd = new FCommandLabel { Base = { Type = FCommandType.EndScope }, @@ -1006,6 +1019,7 @@ public RenderDebugScope Scope(string Name) public RenderDebugScope Scope(ReadOnlySpan Name) { + if (!self.DebugEnabled) return new(self); var cmd = new FCommandLabel { Base = { Type = FCommandType.EndScope }, @@ -1316,6 +1330,7 @@ public void Dispose() public void Label(string Label) { + if (!self.DebugEnabled) return; var cmd = new FCommandLabel { Base = { Type = FCommandType.Label }, @@ -1328,6 +1343,7 @@ public void Label(string Label) public void Label(ReadOnlySpan Label) { + if (!self.DebugEnabled) return; var cmd = new FCommandLabel { Base = { Type = FCommandType.EndScope }, @@ -1344,6 +1360,7 @@ public void Label(ReadOnlySpan Label) public ComputeDebugScope Scope(string Name) { + if (!self.DebugEnabled) return new(self); var cmd = new FCommandLabel { Base = { Type = FCommandType.EndScope }, @@ -1358,6 +1375,7 @@ public ComputeDebugScope Scope(string Name) public ComputeDebugScope Scope(ReadOnlySpan Name) { + if (!self.DebugEnabled) return new(self); var cmd = new FCommandLabel { Base = { Type = FCommandType.EndScope }, From 5ff308fa06db71b3434d7e0d4ca0d1cbc95026ed Mon Sep 17 00:00:00 2001 From: U2A5F Date: Fri, 28 Feb 2025 21:49:39 +0800 Subject: [PATCH 17/23] save --- .idea/editor.xml | 5 +- Coplt.Graphics.Core/Core/Barrier.cs | 230 +++++++ Coplt.Graphics.Core/Core/BufferRange.cs | 2 +- Coplt.Graphics.Core/Core/CommandList.cs | 145 +++- Coplt.Graphics.Core/Core/GpuBuffer.cs | 16 +- Coplt.Graphics.Core/Core/GpuOutput.cs | 20 +- Coplt.Graphics.Core/Core/GpuResource.cs | 2 +- Coplt.Graphics.Core/Core/ResState.cs | 136 ++++ Coplt.Graphics.Core/Core/Views.cs | 75 ++- Coplt.Graphics.Core/Native/Native.cs | 34 +- Coplt.Graphics.Native/Api/CMakeLists.txt | 1 + Coplt.Graphics.Native/Api/FFI/Command.h | 7 +- Coplt.Graphics.Native/Api/FFI/Common.h | 30 +- Coplt.Graphics.Native/Api/FFI/Resource.h | 2 +- Coplt.Graphics.Native/Api/FFI/States.h | 37 +- .../Api/Include/ChunkedVector.h | 152 +++++ Coplt.Graphics.Native/D3d12/Include/States.h | 166 +++++ Coplt.Graphics.Native/D3d12/Src/Buffer.cc | 16 +- Coplt.Graphics.Native/D3d12/Src/Buffer.h | 6 +- Coplt.Graphics.Native/D3d12/Src/Command.cc | 634 ++++++------------ Coplt.Graphics.Native/D3d12/Src/Command.h | 77 +-- Coplt.Graphics.Native/D3d12/Src/Context.cc | 2 +- Coplt.Graphics.Native/D3d12/Src/Resource.cc | 63 +- Coplt.Graphics.Native/D3d12/Src/Resource.h | 10 +- Examples/Colorful/Example.cs | 14 + 25 files changed, 1252 insertions(+), 630 deletions(-) create mode 100644 Coplt.Graphics.Core/Core/Barrier.cs create mode 100644 Coplt.Graphics.Core/Core/ResState.cs create mode 100644 Coplt.Graphics.Native/Api/Include/ChunkedVector.h diff --git a/.idea/editor.xml b/.idea/editor.xml index de2c91a..9e1bfff 100644 --- a/.idea/editor.xml +++ b/.idea/editor.xml @@ -241,6 +241,8 @@