From 5b96182652dec7b4ffc94425ec5e1a525a2c65a7 Mon Sep 17 00:00:00 2001 From: Amer Koleci Date: Tue, 20 Sep 2022 18:04:11 +0200 Subject: [PATCH] Lot of Dxgi, D3D11 and D3D12 goodies. --- src/Generator/Program.cs | 28 +- .../Generated/Graphics/Direct2D.cs | 10 +- .../Generated/Graphics/Direct3D11.cs | 22 +- .../Generated/Graphics/Dxgi.Common.cs | 2 +- src/Vortice.Win32/Generated/Graphics/Dxgi.cs | 2 +- .../Generated/Graphics/Dxgi/IDXGISwapChain.cs | 4 +- .../Graphics/Dxgi/IDXGISwapChain1.cs | 4 +- .../Graphics/Dxgi/IDXGISwapChain2.cs | 4 +- .../Graphics/Dxgi/IDXGISwapChain3.cs | 4 +- .../Graphics/Dxgi/IDXGISwapChain4.cs | 4 +- .../Graphics/Direct3D11.Manual.cs | 21 + .../Graphics/Direct3D11/BlendDescription.cs | 75 +++ .../Graphics/Direct3D11/BlendDescription1.cs | 76 +++ .../Graphics/Direct3D11/QueryDescription.cs | 18 + .../Graphics/Direct3D11/QueryDescription1.cs | 23 + .../Direct3D11/RasterizerDescription.cs | 48 ++ .../Direct3D11/RasterizerDescription1.cs | 49 ++ .../Direct3D11/RasterizerDescription2.cs | 50 ++ .../Graphics/Direct3D11/SamplerDescription.cs | 130 ++++ .../Direct3D11/Texture2DDescription1.cs | 64 ++ .../Direct3D11/Texture3DDescription1.cs | 59 ++ src/Vortice.Win32/Graphics/Direct3D12/Apis.cs | 369 ++++++++++++ src/Vortice.Win32/Graphics/Direct3D12/Box.cs | 57 ++ .../Graphics/Direct3D12/ClearValue.cs | 78 +++ .../Direct3D12/ResourceDescription.cs | 183 ++++++ .../Direct3D12/SubresourceFootprint.cs | 27 + .../Direct3D12/TextureCopyLocation.cs | 35 ++ .../Graphics/Dxgi/FormatHelper.cs | 560 ++++++++++++++++++ src/Vortice.Win32/Vortice.Win32.csproj | 2 +- 29 files changed, 1978 insertions(+), 30 deletions(-) create mode 100644 src/Vortice.Win32/Graphics/Direct3D11/BlendDescription.cs create mode 100644 src/Vortice.Win32/Graphics/Direct3D11/BlendDescription1.cs create mode 100644 src/Vortice.Win32/Graphics/Direct3D11/QueryDescription.cs create mode 100644 src/Vortice.Win32/Graphics/Direct3D11/QueryDescription1.cs create mode 100644 src/Vortice.Win32/Graphics/Direct3D11/RasterizerDescription.cs create mode 100644 src/Vortice.Win32/Graphics/Direct3D11/RasterizerDescription1.cs create mode 100644 src/Vortice.Win32/Graphics/Direct3D11/RasterizerDescription2.cs create mode 100644 src/Vortice.Win32/Graphics/Direct3D11/SamplerDescription.cs create mode 100644 src/Vortice.Win32/Graphics/Direct3D11/Texture2DDescription1.cs create mode 100644 src/Vortice.Win32/Graphics/Direct3D11/Texture3DDescription1.cs create mode 100644 src/Vortice.Win32/Graphics/Direct3D12/Apis.cs create mode 100644 src/Vortice.Win32/Graphics/Direct3D12/Box.cs create mode 100644 src/Vortice.Win32/Graphics/Direct3D12/ClearValue.cs create mode 100644 src/Vortice.Win32/Graphics/Direct3D12/ResourceDescription.cs create mode 100644 src/Vortice.Win32/Graphics/Direct3D12/SubresourceFootprint.cs create mode 100644 src/Vortice.Win32/Graphics/Direct3D12/TextureCopyLocation.cs create mode 100644 src/Vortice.Win32/Graphics/Dxgi/FormatHelper.cs diff --git a/src/Generator/Program.cs b/src/Generator/Program.cs index ba9e1ce..3207b0b 100644 --- a/src/Generator/Program.cs +++ b/src/Generator/Program.cs @@ -786,6 +786,13 @@ public static class Program { "NUM_D3D12_GPU_BASED_VALIDATION_SHADER_PATCH_MODES", "Count" }, { "D3D12_MESSAGE_CALLBACK_IGNORE_FILTERS", "IgnoreFilters" }, { "D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_AS", "AS" }, + + // D2D1 + { "D2D1_BUFFER_PRECISION_8BPC_UNORM", "Precision8BitUnorm" }, + { "D2D1_BUFFER_PRECISION_8BPC_UNORM_SRGB", "Precision8BitUnormSrgb" }, + { "D2D1_BUFFER_PRECISION_16BPC_UNORM", "Precision16BitUnorm" }, + { "D2D1_BUFFER_PRECISION_16BPC_FLOAT", "Precision16BitFloat" }, + { "D2D1_BUFFER_PRECISION_32BPC_FLOAT", "Precision32BitFloat" }, }; private static readonly Dictionary s_generatedEnums = new() @@ -818,17 +825,18 @@ public static class Program "PF" // D3D_PF_ }; - private static readonly Dictionary s_typesNameRemap = new() { // Generated { "DXGI_MAP", "MapFlags" }, { "DXGI_ENUM_MODES", "EnumModesFlags" }, { "DXGI_MWA", "WindowAssociationFlags" }, + { "DXGI_PRESENT", "PresentFlags" }, // D3D11 { "D3D11_RLDO_FLAGS", "ReportLiveDeviceObjectFlags" }, { "D3D11_1_CREATE_DEVICE_CONTEXT_STATE_FLAG", "CreateDeviceContextStateFlags" }, + { "D3D11_QUERY", "QueryType" }, // D3D12 { "D3D12_RLDO_FLAGS", "ReportLiveDeviceObjectFlags" }, @@ -868,10 +876,19 @@ public static class Program { "D3D11_TEXTURE2D_DESC::BindFlags", "D3D11_BIND_FLAG" }, { "D3D11_TEXTURE2D_DESC::CPUAccessFlags", "D3D11_CPU_ACCESS_FLAG" }, { "D3D11_TEXTURE2D_DESC::MiscFlags", "D3D11_RESOURCE_MISC_FLAG" }, + { "D3D11_TEXTURE2D_DESC1::BindFlags", "D3D11_BIND_FLAG" }, + { "D3D11_TEXTURE2D_DESC1::CPUAccessFlags", "D3D11_CPU_ACCESS_FLAG" }, + { "D3D11_TEXTURE2D_DESC1::MiscFlags", "D3D11_RESOURCE_MISC_FLAG" }, { "D3D11_TEXTURE3D_DESC::BindFlags", "D3D11_BIND_FLAG" }, { "D3D11_TEXTURE3D_DESC::CPUAccessFlags", "D3D11_CPU_ACCESS_FLAG" }, { "D3D11_TEXTURE3D_DESC::MiscFlags", "D3D11_RESOURCE_MISC_FLAG" }, + { "D3D11_TEXTURE3D_DESC1::BindFlags", "D3D11_BIND_FLAG" }, + { "D3D11_TEXTURE3D_DESC1::CPUAccessFlags", "D3D11_CPU_ACCESS_FLAG" }, + { "D3D11_TEXTURE3D_DESC1::MiscFlags", "D3D11_RESOURCE_MISC_FLAG" }, + + { "D3D11_QUERY_DESC::MiscFlags", "D3D11_QUERY_MISC_FLAG" }, + { "D3D11_QUERY_DESC1::MiscFlags", "D3D11_QUERY_MISC_FLAG" }, { "D3D11_FEATURE_DATA_FORMAT_SUPPORT::OutFormatSupport", "D3D11_FORMAT_SUPPORT" }, { "D3D11_FEATURE_DATA_FORMAT_SUPPORT2::OutFormatSupport2", "D3D11_FORMAT_SUPPORT2" }, @@ -894,6 +911,11 @@ public static class Program // DXGI { "IDXGIDevice::CreateSurface::Usage", "DXGI_USAGE" }, { "IDXGIOutput::GetDisplayModeList::Flags", "DXGI_ENUM_MODES" }, + { "IDXGISwapChain::Present::Flags", "DXGI_PRESENT" }, + { "IDXGISwapChain1::Present::Flags", "DXGI_PRESENT" }, + { "IDXGISwapChain2::Present::Flags", "DXGI_PRESENT" }, + { "IDXGISwapChain3::Present::Flags", "DXGI_PRESENT" }, + { "IDXGISwapChain4::Present::Flags", "DXGI_PRESENT" }, // D3D11 { "ID3D11DeviceContext::Map::MapFlags", "D3D11_MAP_FLAG" }, @@ -2393,6 +2415,10 @@ public static class Program { sb.Append("Srgb"); } + else if (part.Equals("BIAS", StringComparison.OrdinalIgnoreCase)) + { + sb.Append("Bias"); + } else if (part.Equals("SHAREDEXP", StringComparison.OrdinalIgnoreCase)) { sb.Append("SharedExp"); diff --git a/src/Vortice.Win32/Generated/Graphics/Direct2D.cs b/src/Vortice.Win32/Generated/Graphics/Direct2D.cs index c9a29f1..1a2b883 100644 --- a/src/Vortice.Win32/Generated/Graphics/Direct2D.cs +++ b/src/Vortice.Win32/Generated/Graphics/Direct2D.cs @@ -3399,19 +3399,19 @@ public enum BufferPrecision : uint Unknown = 0, /// /// D2D1_BUFFER_PRECISION_8BPC_UNORM - _8bpcUnorm = 1, + Precision8BitUnorm = 1, /// /// D2D1_BUFFER_PRECISION_8BPC_UNORM_SRGB - _8bpcUnormSrgb = 2, + Precision8BitUnormSrgb = 2, /// /// D2D1_BUFFER_PRECISION_16BPC_UNORM - _16bpcUnorm = 3, + Precision16BitUnorm = 3, /// /// D2D1_BUFFER_PRECISION_16BPC_FLOAT - _16bpcFloat = 4, + Precision16BitFloat = 4, /// /// D2D1_BUFFER_PRECISION_32BPC_FLOAT - _32bpcFloat = 5, + Precision32BitFloat = 5, } /// diff --git a/src/Vortice.Win32/Generated/Graphics/Direct3D11.cs b/src/Vortice.Win32/Generated/Graphics/Direct3D11.cs index 6a74387..646ba46 100644 --- a/src/Vortice.Win32/Generated/Graphics/Direct3D11.cs +++ b/src/Vortice.Win32/Generated/Graphics/Direct3D11.cs @@ -2849,7 +2849,7 @@ public enum AsyncGetDataFlags : int /// /// D3D11_QUERY -public enum Query : int +public enum QueryType : int { /// /// D3D11_QUERY_EVENT @@ -10066,10 +10066,10 @@ public partial struct SamplerDescription public partial struct QueryDescription { /// - public Query Query; + public QueryType Query; /// - public uint MiscFlags; + public QueryMiscFlags MiscFlags; } /// @@ -11862,13 +11862,13 @@ public partial struct Texture2DDescription1 public Usage Usage; /// - public uint BindFlags; + public BindFlags BindFlags; /// - public uint CPUAccessFlags; + public CpuAccessFlags CPUAccessFlags; /// - public uint MiscFlags; + public ResourceMiscFlags MiscFlags; /// public TextureLayout TextureLayout; @@ -11897,13 +11897,13 @@ public partial struct Texture3DDescription1 public Usage Usage; /// - public uint BindFlags; + public BindFlags BindFlags; /// - public uint CPUAccessFlags; + public CpuAccessFlags CPUAccessFlags; /// - public uint MiscFlags; + public ResourceMiscFlags MiscFlags; /// public TextureLayout TextureLayout; @@ -12552,10 +12552,10 @@ public partial struct UnorderedAccessViewDescription1 public partial struct QueryDescription1 { /// - public Query Query; + public QueryType Query; /// - public uint MiscFlags; + public QueryMiscFlags MiscFlags; /// public ContextType ContextType; diff --git a/src/Vortice.Win32/Generated/Graphics/Dxgi.Common.cs b/src/Vortice.Win32/Generated/Graphics/Dxgi.Common.cs index b986a55..e335feb 100644 --- a/src/Vortice.Win32/Generated/Graphics/Dxgi.Common.cs +++ b/src/Vortice.Win32/Generated/Graphics/Dxgi.Common.cs @@ -378,7 +378,7 @@ public enum Format : uint B8G8R8X8Unorm = 88, /// /// DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM - R10G10B10XRBIASA2Unorm = 89, + R10G10B10XRBiasA2Unorm = 89, /// /// DXGI_FORMAT_B8G8R8A8_TYPELESS B8G8R8A8Typeless = 90, diff --git a/src/Vortice.Win32/Generated/Graphics/Dxgi.cs b/src/Vortice.Win32/Generated/Graphics/Dxgi.cs index c1bdb5b..2d83765 100644 --- a/src/Vortice.Win32/Generated/Graphics/Dxgi.cs +++ b/src/Vortice.Win32/Generated/Graphics/Dxgi.cs @@ -1698,7 +1698,7 @@ public enum EnumModesFlags : uint /// DXGI_PRESENT [Flags] -public enum Present : uint +public enum PresentFlags : uint { None = 0, /// DXGI_PRESENT_TEST diff --git a/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain.cs b/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain.cs index 8f1d474..6bb90ca 100644 --- a/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain.cs +++ b/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain.cs @@ -118,9 +118,9 @@ public unsafe partial struct IDXGISwapChain /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [VtblIndex(8)] - public HResult Present(uint SyncInterval, uint Flags) + public HResult Present(uint SyncInterval, PresentFlags Flags) { - return ((delegate* unmanaged[Stdcall])(lpVtbl[8]))((IDXGISwapChain*)Unsafe.AsPointer(ref this), SyncInterval, Flags); + return ((delegate* unmanaged[Stdcall])(lpVtbl[8]))((IDXGISwapChain*)Unsafe.AsPointer(ref this), SyncInterval, Flags); } /// diff --git a/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain1.cs b/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain1.cs index 86cdf0a..8d7ea34 100644 --- a/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain1.cs +++ b/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain1.cs @@ -118,9 +118,9 @@ public unsafe partial struct IDXGISwapChain1 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [VtblIndex(8)] - public HResult Present(uint SyncInterval, uint Flags) + public HResult Present(uint SyncInterval, PresentFlags Flags) { - return ((delegate* unmanaged[Stdcall])(lpVtbl[8]))((IDXGISwapChain1*)Unsafe.AsPointer(ref this), SyncInterval, Flags); + return ((delegate* unmanaged[Stdcall])(lpVtbl[8]))((IDXGISwapChain1*)Unsafe.AsPointer(ref this), SyncInterval, Flags); } /// diff --git a/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain2.cs b/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain2.cs index b264e01..30035fa 100644 --- a/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain2.cs +++ b/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain2.cs @@ -118,9 +118,9 @@ public unsafe partial struct IDXGISwapChain2 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [VtblIndex(8)] - public HResult Present(uint SyncInterval, uint Flags) + public HResult Present(uint SyncInterval, PresentFlags Flags) { - return ((delegate* unmanaged[Stdcall])(lpVtbl[8]))((IDXGISwapChain2*)Unsafe.AsPointer(ref this), SyncInterval, Flags); + return ((delegate* unmanaged[Stdcall])(lpVtbl[8]))((IDXGISwapChain2*)Unsafe.AsPointer(ref this), SyncInterval, Flags); } /// diff --git a/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain3.cs b/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain3.cs index 4d78b86..c01a340 100644 --- a/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain3.cs +++ b/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain3.cs @@ -118,9 +118,9 @@ public unsafe partial struct IDXGISwapChain3 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [VtblIndex(8)] - public HResult Present(uint SyncInterval, uint Flags) + public HResult Present(uint SyncInterval, PresentFlags Flags) { - return ((delegate* unmanaged[Stdcall])(lpVtbl[8]))((IDXGISwapChain3*)Unsafe.AsPointer(ref this), SyncInterval, Flags); + return ((delegate* unmanaged[Stdcall])(lpVtbl[8]))((IDXGISwapChain3*)Unsafe.AsPointer(ref this), SyncInterval, Flags); } /// diff --git a/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain4.cs b/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain4.cs index 41aff37..f3e2e87 100644 --- a/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain4.cs +++ b/src/Vortice.Win32/Generated/Graphics/Dxgi/IDXGISwapChain4.cs @@ -118,9 +118,9 @@ public unsafe partial struct IDXGISwapChain4 /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [VtblIndex(8)] - public HResult Present(uint SyncInterval, uint Flags) + public HResult Present(uint SyncInterval, PresentFlags Flags) { - return ((delegate* unmanaged[Stdcall])(lpVtbl[8]))((IDXGISwapChain4*)Unsafe.AsPointer(ref this), SyncInterval, Flags); + return ((delegate* unmanaged[Stdcall])(lpVtbl[8]))((IDXGISwapChain4*)Unsafe.AsPointer(ref this), SyncInterval, Flags); } /// diff --git a/src/Vortice.Win32/Graphics/Direct3D11.Manual.cs b/src/Vortice.Win32/Graphics/Direct3D11.Manual.cs index 92abbbf..f6fdcde 100644 --- a/src/Vortice.Win32/Graphics/Direct3D11.Manual.cs +++ b/src/Vortice.Win32/Graphics/Direct3D11.Manual.cs @@ -59,6 +59,27 @@ public partial struct AuthenticatedProtectionFlags public static unsafe partial class Apis { + public static HResult D3D11CreateDevice( + IDXGIAdapter* adapter, + DriverType driverType, + CreateDeviceFlags flags, + ID3D11Device** ppDevice, + FeatureLevel* pFeatureLevel, + ID3D11DeviceContext** ppImmediateContext) + { + return D3D11CreateDevice( + adapter, + driverType, + IntPtr.Zero, + flags, + null, + 0u, + D3D11_SDK_VERSION, + ppDevice, + pFeatureLevel, + ppImmediateContext); + } + public static HResult D3D11CreateDevice( IDXGIAdapter* pAdapter, DriverType driverType, diff --git a/src/Vortice.Win32/Graphics/Direct3D11/BlendDescription.cs b/src/Vortice.Win32/Graphics/Direct3D11/BlendDescription.cs new file mode 100644 index 0000000..8d85062 --- /dev/null +++ b/src/Vortice.Win32/Graphics/Direct3D11/BlendDescription.cs @@ -0,0 +1,75 @@ +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +using static Win32.Graphics.Direct3D11.Apis; + +namespace Win32.Graphics.Direct3D11; + +public unsafe partial struct BlendDescription +{ + /// + /// A built-in description with settings for opaque blend, that is overwriting the source with the destination data. + /// + public static readonly BlendDescription Opaque = new(Blend.One, Blend.Zero); + + /// + /// A built-in description with settings for alpha blend, that is blending the source and destination data using alpha. + /// + public static readonly BlendDescription AlphaBlend = new(Blend.One, Blend.InvSrcAlpha); + + /// + /// A built-in description with settings for additive blend, that is adding the destination data to the source data without using alpha. + /// + public static readonly BlendDescription Additive = new(Blend.SrcAlpha, Blend.One); + + /// + /// A built-in description with settings for blending with non-premultipled alpha, that is blending source and destination data using alpha while assuming the color data contains no alpha information. + /// + public static readonly BlendDescription NonPremultiplied = new(Blend.SrcAlpha, Blend.InvSrcAlpha); + + /// + /// Initializes a new instance of the struct. + /// + /// The source blend. + /// The destination blend. + public BlendDescription(Blend sourceBlend, Blend destinationBlend) + : this(sourceBlend, destinationBlend, sourceBlend, destinationBlend) + { + } + + /// + /// Initializes a new instance of the struct. + /// + /// The source blend. + /// The destination blend. + /// The source alpha blend. + /// The destination alpha blend. + public BlendDescription(Blend sourceBlend, Blend destinationBlend, Blend srcBlendAlpha, Blend destBlendAlpha) + : this() + { + AlphaToCoverageEnable = false; + IndependentBlendEnable = false; + + for (int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + RenderTarget[i].SrcBlend = sourceBlend; + RenderTarget[i].DestBlend = destinationBlend; + RenderTarget[i].BlendOp = BlendOp.Add; + RenderTarget[i].SrcBlendAlpha = srcBlendAlpha; + RenderTarget[i].DestBlendAlpha = destBlendAlpha; + RenderTarget[i].BlendOpAlpha = BlendOp.Add; + RenderTarget[i].RenderTargetWriteMask = ColorWriteEnable.All; + RenderTarget[i].BlendEnable = IsBlendEnabled(ref RenderTarget[i]); + } + } + + private static bool IsBlendEnabled(ref RenderTargetBlendDescription renderTarget) + { + return renderTarget.BlendOp != BlendOp.Add + || renderTarget.SrcBlend != Blend.One + || renderTarget.DestBlendAlpha != Blend.Zero + || renderTarget.BlendOp != BlendOp.Add + || renderTarget.SrcBlend != Blend.One + || renderTarget.DestBlend != Blend.Zero; + } +} diff --git a/src/Vortice.Win32/Graphics/Direct3D11/BlendDescription1.cs b/src/Vortice.Win32/Graphics/Direct3D11/BlendDescription1.cs new file mode 100644 index 0000000..73e0fb7 --- /dev/null +++ b/src/Vortice.Win32/Graphics/Direct3D11/BlendDescription1.cs @@ -0,0 +1,76 @@ +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +using static Win32.Graphics.Direct3D11.Apis; + +namespace Win32.Graphics.Direct3D11; + +public unsafe partial struct BlendDescription1 +{ + /// + /// A built-in description with settings for opaque blend, that is overwriting the source with the destination data. + /// + public static readonly BlendDescription1 Opaque = new(Blend.One, Blend.Zero); + + /// + /// A built-in description with settings for alpha blend, that is blending the source and destination data using alpha. + /// + public static readonly BlendDescription1 AlphaBlend = new(Blend.One, Blend.InvSrcAlpha); + + /// + /// A built-in description with settings for additive blend, that is adding the destination data to the source data without using alpha. + /// + public static readonly BlendDescription1 Additive = new(Blend.SrcAlpha, Blend.One); + + /// + /// A built-in description with settings for blending with non-premultipled alpha, that is blending source and destination data using alpha while assuming the color data contains no alpha information. + /// + public static readonly BlendDescription NonPremultiplied = new(Blend.SrcAlpha, Blend.InvSrcAlpha); + + /// + /// Initializes a new instance of the struct. + /// + /// The source blend. + /// The destination blend. + public BlendDescription1(Blend sourceBlend, Blend destinationBlend) + : this(sourceBlend, destinationBlend, sourceBlend, destinationBlend) + { + } + + /// + /// Initializes a new instance of the struct. + /// + /// The source blend. + /// The destination blend. + /// The source alpha blend. + /// The destination alpha blend. + public BlendDescription1(Blend sourceBlend, Blend destinationBlend, Blend srcBlendAlpha, Blend destBlendAlpha) + : this() + { + AlphaToCoverageEnable = false; + IndependentBlendEnable = false; + + for (int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + RenderTarget[i].SrcBlend = sourceBlend; + RenderTarget[i].DestBlend = destinationBlend; + RenderTarget[i].BlendOp = BlendOp.Add; + RenderTarget[i].SrcBlendAlpha = srcBlendAlpha; + RenderTarget[i].DestBlendAlpha = destBlendAlpha; + RenderTarget[i].BlendOpAlpha = BlendOp.Add; + RenderTarget[i].LogicOp = LogicOp.Noop; + RenderTarget[i].RenderTargetWriteMask = ColorWriteEnable.All; + RenderTarget[i].BlendEnable = IsBlendEnabled(ref RenderTarget[i]); + } + } + + private static bool IsBlendEnabled(ref RenderTargetBlendDescription1 renderTarget) + { + return renderTarget.BlendOp != BlendOp.Add + || renderTarget.SrcBlend != Blend.One + || renderTarget.DestBlendAlpha != Blend.Zero + || renderTarget.BlendOp != BlendOp.Add + || renderTarget.SrcBlend != Blend.One + || renderTarget.DestBlend != Blend.Zero; + } +} diff --git a/src/Vortice.Win32/Graphics/Direct3D11/QueryDescription.cs b/src/Vortice.Win32/Graphics/Direct3D11/QueryDescription.cs new file mode 100644 index 0000000..0f9b51c --- /dev/null +++ b/src/Vortice.Win32/Graphics/Direct3D11/QueryDescription.cs @@ -0,0 +1,18 @@ +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +namespace Win32.Graphics.Direct3D11; + +public unsafe partial struct QueryDescription +{ + /// + /// Initializes a new instance of the struct. + /// + /// Type of query (see ). + /// Miscellaneous flags (see ). + public QueryDescription(QueryType queryType, QueryMiscFlags miscFlags = QueryMiscFlags.None) + { + Query = queryType; + MiscFlags = miscFlags; + } +} diff --git a/src/Vortice.Win32/Graphics/Direct3D11/QueryDescription1.cs b/src/Vortice.Win32/Graphics/Direct3D11/QueryDescription1.cs new file mode 100644 index 0000000..a0a685f --- /dev/null +++ b/src/Vortice.Win32/Graphics/Direct3D11/QueryDescription1.cs @@ -0,0 +1,23 @@ +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +namespace Win32.Graphics.Direct3D11; + +public unsafe partial struct QueryDescription1 +{ + /// + /// Initializes a new instance of the struct. + /// + /// Type of query (see ). + /// Miscellaneous flags (see ). + /// A value that specifies the context for the query. + public QueryDescription1( + QueryType queryType, + QueryMiscFlags miscFlags = QueryMiscFlags.None, + ContextType contextType = ContextType.All) + { + Query = queryType; + MiscFlags = miscFlags; + ContextType = contextType; + } +} diff --git a/src/Vortice.Win32/Graphics/Direct3D11/RasterizerDescription.cs b/src/Vortice.Win32/Graphics/Direct3D11/RasterizerDescription.cs new file mode 100644 index 0000000..3998bfb --- /dev/null +++ b/src/Vortice.Win32/Graphics/Direct3D11/RasterizerDescription.cs @@ -0,0 +1,48 @@ +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +using static Win32.Graphics.Direct3D11.Apis; + +namespace Win32.Graphics.Direct3D11; + +public unsafe partial struct RasterizerDescription +{ + /// + /// A built-in description with settings with settings for not culling any primitives. + /// + public static readonly RasterizerDescription CullNone = new(CullMode.None, FillMode.Solid); + + /// + /// A built-in description with settings for culling primitives with clockwise winding order. + /// + public static readonly RasterizerDescription CullFront = new(CullMode.Front, FillMode.Solid); + + /// + /// A built-in description with settings for culling primitives with counter-clockwise winding order. + /// + public static readonly RasterizerDescription CullBack = new(CullMode.Back, FillMode.Solid); + + /// + /// A built-in description with settings for not culling any primitives and wireframe fill mode. + /// + public static readonly RasterizerDescription Wireframe = new(CullMode.None, FillMode.Wireframe); + + /// + /// Initializes a new instance of the class. + /// + /// A value that specifies that triangles facing the specified direction are not drawn.. + /// A value that specifies the fill mode to use when rendering. + public RasterizerDescription(CullMode cullMode, FillMode fillMode) + { + CullMode = cullMode; + FillMode = fillMode; + FrontCounterClockwise = false; + DepthBias = (int)D3D11_DEFAULT_DEPTH_BIAS; + DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP; + SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + DepthClipEnable = true; + ScissorEnable = false; + MultisampleEnable = true; + AntialiasedLineEnable = false; + } +} diff --git a/src/Vortice.Win32/Graphics/Direct3D11/RasterizerDescription1.cs b/src/Vortice.Win32/Graphics/Direct3D11/RasterizerDescription1.cs new file mode 100644 index 0000000..1243a74 --- /dev/null +++ b/src/Vortice.Win32/Graphics/Direct3D11/RasterizerDescription1.cs @@ -0,0 +1,49 @@ +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +using static Win32.Graphics.Direct3D11.Apis; + +namespace Win32.Graphics.Direct3D11; + +public unsafe partial struct RasterizerDescription1 +{ + /// + /// A built-in description with settings with settings for not culling any primitives. + /// + public static readonly RasterizerDescription1 CullNone = new(CullMode.None, FillMode.Solid); + + /// + /// A built-in description with settings for culling primitives with clockwise winding order. + /// + public static readonly RasterizerDescription1 CullFront = new(CullMode.Front, FillMode.Solid); + + /// + /// A built-in description with settings for culling primitives with counter-clockwise winding order. + /// + public static readonly RasterizerDescription1 CullBack = new(CullMode.Back, FillMode.Solid); + + /// + /// A built-in description with settings for not culling any primitives and wireframe fill mode. + /// + public static readonly RasterizerDescription1 Wireframe = new(CullMode.None, FillMode.Wireframe); + + /// + /// Initializes a new instance of the class. + /// + /// A value that specifies that triangles facing the specified direction are not drawn.. + /// A value that specifies the fill mode to use when rendering. + public RasterizerDescription1(CullMode cullMode, FillMode fillMode) + { + CullMode = cullMode; + FillMode = fillMode; + FrontCounterClockwise = false; + DepthBias = (int)D3D11_DEFAULT_DEPTH_BIAS; + DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP; + SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + DepthClipEnable = true; + ScissorEnable = false; + MultisampleEnable = true; + AntialiasedLineEnable = false; + ForcedSampleCount = 0; + } +} diff --git a/src/Vortice.Win32/Graphics/Direct3D11/RasterizerDescription2.cs b/src/Vortice.Win32/Graphics/Direct3D11/RasterizerDescription2.cs new file mode 100644 index 0000000..d6375a2 --- /dev/null +++ b/src/Vortice.Win32/Graphics/Direct3D11/RasterizerDescription2.cs @@ -0,0 +1,50 @@ +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +using static Win32.Graphics.Direct3D11.Apis; + +namespace Win32.Graphics.Direct3D11; + +public unsafe partial struct RasterizerDescription2 +{ + /// + /// A built-in description with settings with settings for not culling any primitives. + /// + public static readonly RasterizerDescription2 CullNone = new(CullMode.None, FillMode.Solid); + + /// + /// A built-in description with settings for culling primitives with clockwise winding order. + /// + public static readonly RasterizerDescription2 CullFront = new(CullMode.Front, FillMode.Solid); + + /// + /// A built-in description with settings for culling primitives with counter-clockwise winding order. + /// + public static readonly RasterizerDescription2 CullBack = new(CullMode.Back, FillMode.Solid); + + /// + /// A built-in description with settings for not culling any primitives and wireframe fill mode. + /// + public static readonly RasterizerDescription2 Wireframe = new(CullMode.None, FillMode.Wireframe); + + /// + /// Initializes a new instance of the class. + /// + /// A value that specifies that triangles facing the specified direction are not drawn.. + /// A value that specifies the fill mode to use when rendering. + public RasterizerDescription2(CullMode cullMode, FillMode fillMode) + { + CullMode = cullMode; + FillMode = fillMode; + FrontCounterClockwise = false; + DepthBias = (int)D3D11_DEFAULT_DEPTH_BIAS; + DepthBiasClamp = D3D11_DEFAULT_DEPTH_BIAS_CLAMP; + SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + DepthClipEnable = true; + ScissorEnable = false; + MultisampleEnable = true; + AntialiasedLineEnable = false; + ForcedSampleCount = 0; + ConservativeRaster = ConservativeRasterizationMode.Off; + } +} diff --git a/src/Vortice.Win32/Graphics/Direct3D11/SamplerDescription.cs b/src/Vortice.Win32/Graphics/Direct3D11/SamplerDescription.cs new file mode 100644 index 0000000..a82fd6e --- /dev/null +++ b/src/Vortice.Win32/Graphics/Direct3D11/SamplerDescription.cs @@ -0,0 +1,130 @@ +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +using static Win32.Graphics.Direct3D11.Apis; + +namespace Win32.Graphics.Direct3D11; + +public unsafe partial struct SamplerDescription +{ + public static readonly SamplerDescription PointWrap = new(Filter.MinMagMipPoint, TextureAddressMode.Wrap); + public static readonly SamplerDescription PointClamp = new(Filter.MinMagMipPoint, TextureAddressMode.Clamp); + + public static readonly SamplerDescription LinearWrap = new(Filter.MinMagMipLinear, TextureAddressMode.Wrap); + public static readonly SamplerDescription LinearClamp = new(Filter.MinMagMipLinear, TextureAddressMode.Clamp); + + public static readonly SamplerDescription AnisotropicWrap = new(Filter.Anisotropic, TextureAddressMode.Wrap, 0.0f, D3D11_MAX_MAXANISOTROPY); + public static readonly SamplerDescription AnisotropicClamp = new(Filter.Anisotropic, TextureAddressMode.Clamp, 0.0f, D3D11_MAX_MAXANISOTROPY); + + /// + /// Initializes a new instance of the struct. + /// + /// Filtering method to use when sampling a texture. + /// Method to use for resolving a u texture coordinate that is outside the 0 to 1 range. + /// Method to use for resolving a v texture coordinate that is outside the 0 to 1 range. + /// Method to use for resolving a w texture coordinate that is outside the 0 to 1 range. + /// Offset from the calculated mipmap level. + /// Clamping value used if or is specified in Filter. Valid values are between 1 and 16. + /// A function that compares sampled data against existing sampled data. + /// Border color to use if is specified for AddressU, AddressV, or AddressW. + /// Lower end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap level and any level higher than that is less detailed. + /// Upper end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap level and any level higher than that is less detailed. This value must be greater than or equal to MinLOD. + public SamplerDescription( + Filter filter, + TextureAddressMode addressU, + TextureAddressMode addressV, + TextureAddressMode addressW, + float mipLODBias, + uint maxAnisotropy, + ComparisonFunc comparisonFunction, + Color4 borderColor, + float minLOD, + float maxLOD) + { + Filter = filter; + AddressU = addressU; + AddressV = addressV; + AddressW = addressW; + MipLODBias = mipLODBias; + MaxAnisotropy = maxAnisotropy; + ComparisonFunc = comparisonFunction; + BorderColor[0] = borderColor.R; + BorderColor[1] = borderColor.G; + BorderColor[2] = borderColor.B; + BorderColor[3] = borderColor.A; + MinLOD = minLOD; + MaxLOD = maxLOD; + } + + /// + /// Initializes a new instance of the struct. + /// + /// Filtering method to use when sampling a texture. + /// Method to use for resolving a u texture coordinate that is outside the 0 to 1 range. + /// Method to use for resolving a v texture coordinate that is outside the 0 to 1 range. + /// Method to use for resolving a w texture coordinate that is outside the 0 to 1 range. + /// Offset from the calculated mipmap level. + /// Clamping value used if or is specified in Filter. Valid values are between 1 and 16. + /// A function that compares sampled data against existing sampled data. + /// Lower end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap level and any level higher than that is less detailed. + /// Upper end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap level and any level higher than that is less detailed. This value must be greater than or equal to MinLOD. + public SamplerDescription( + Filter filter, + TextureAddressMode addressU, + TextureAddressMode addressV, + TextureAddressMode addressW, + float mipLODBias = 0.0f, + uint maxAnisotropy = 1, + ComparisonFunc comparisonFunction = ComparisonFunc.Never, + float minLOD = float.MinValue, + float maxLOD = float.MaxValue) + { + Filter = filter; + AddressU = addressU; + AddressV = addressV; + AddressW = addressW; + MipLODBias = mipLODBias; + MaxAnisotropy = maxAnisotropy; + ComparisonFunc = comparisonFunction; + BorderColor[0] = 1.0f; + BorderColor[1] = 1.0f; + BorderColor[2] = 1.0f; + BorderColor[3] = 1.0f; + MinLOD = minLOD; + MaxLOD = maxLOD; + } + + /// + /// Initializes a new instance of the struct. + /// + /// Filtering method to use when sampling a texture. + /// Method to use for resolving a u, v e w texture coordinate that is outside the 0 to 1 range. + /// Offset from the calculated mipmap level. + /// Clamping value used if or is specified in Filter. Valid values are between 1 and 16. + /// A function that compares sampled data against existing sampled data. + /// Lower end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap level and any level higher than that is less detailed. + /// Upper end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap level and any level higher than that is less detailed. This value must be greater than or equal to MinLOD. + public SamplerDescription( + Filter filter, + TextureAddressMode address, + float mipLODBias = 0.0f, + uint maxAnisotropy = 1, + ComparisonFunc comparisonFunction = ComparisonFunc.Never, + float minLOD = float.MinValue, + float maxLOD = float.MaxValue) + { + Filter = filter; + AddressU = address; + AddressV = address; + AddressW = address; + MipLODBias = mipLODBias; + MaxAnisotropy = maxAnisotropy; + ComparisonFunc = comparisonFunction; + BorderColor[0] = 1.0f; + BorderColor[1] = 1.0f; + BorderColor[2] = 1.0f; + BorderColor[3] = 1.0f; + MinLOD = minLOD; + MaxLOD = maxLOD; + } +} diff --git a/src/Vortice.Win32/Graphics/Direct3D11/Texture2DDescription1.cs b/src/Vortice.Win32/Graphics/Direct3D11/Texture2DDescription1.cs new file mode 100644 index 0000000..e71c740 --- /dev/null +++ b/src/Vortice.Win32/Graphics/Direct3D11/Texture2DDescription1.cs @@ -0,0 +1,64 @@ +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +using Win32.Graphics.Dxgi.Common; +using static Win32.Graphics.Direct3D11.Apis; + +namespace Win32.Graphics.Direct3D11; + +public partial struct Texture2DDescription1 +{ + /// + /// Initializes a new instance of the struct. + /// + /// Texture format. + /// Texture width (in texels). + /// Texture height (in texels). + /// Number of textures in the array. + /// The maximum number of mipmap levels in the texture. + /// The for binding to pipeline stages. + /// Value that identifies how the texture is to be read from and written to. + /// The to specify the types of CPU access allowed. + /// Specifies multisampling parameters for the texture. + /// Specifies multisampling parameters for the texture. + /// The that identify other, less common resource options. + /// A value that identifies the layout of the texture. + public Texture2DDescription1( + Format format, + uint width, + uint height, + uint arraySize = 1, + uint mipLevels = 0, + BindFlags bindFlags = BindFlags.ShaderResource, + Usage usage = Usage.Default, + CpuAccessFlags cpuAccessFlags = CpuAccessFlags.None, + uint sampleCount = 1, + uint sampleQuality = 0, + ResourceMiscFlags miscFlags = ResourceMiscFlags.None, + TextureLayout textureLayout = TextureLayout.Undefined) + { + if (format == Format.Unknown) + throw new ArgumentException($"format need to be valid", nameof(format)); + + if (width < 1 || width > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION) + throw new ArgumentException($"Width need to be in range 1-{D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION}", nameof(width)); + + if (height < 1 || height > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION) + throw new ArgumentException($"Height need to be in range 1-{D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION}", nameof(height)); + + if (arraySize < 1 || arraySize > D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION) + throw new ArgumentException($"Array size need to be in range 1-{D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION}", nameof(arraySize)); + + Width = width; + Height = height; + MipLevels = mipLevels; + ArraySize = arraySize; + Format = format; + SampleDesc = new(sampleCount, sampleQuality); + Usage = usage; + BindFlags = bindFlags; + CPUAccessFlags = cpuAccessFlags; + MiscFlags = miscFlags; + TextureLayout = textureLayout; + } +} diff --git a/src/Vortice.Win32/Graphics/Direct3D11/Texture3DDescription1.cs b/src/Vortice.Win32/Graphics/Direct3D11/Texture3DDescription1.cs new file mode 100644 index 0000000..7dc8899 --- /dev/null +++ b/src/Vortice.Win32/Graphics/Direct3D11/Texture3DDescription1.cs @@ -0,0 +1,59 @@ +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +using Win32.Graphics.Dxgi.Common; +using static Win32.Graphics.Direct3D11.Apis; + +namespace Win32.Graphics.Direct3D11; + +public partial struct Texture3DDescription1 +{ + /// + /// Initializes a new instance of the struct. + /// + /// Texture width (in texels). + /// Texture height (in texels). + /// Texture depth (in texels). + /// Texture format. + /// The maximum number of mipmap levels in the texture. + /// The for binding to pipeline stages. + /// Value that identifies how the texture is to be read from and written to. + /// The to specify the types of CPU access allowed. + /// The that identify other, less common resource options. + /// A value that identifies the layout of the texture. + public Texture3DDescription1( + Format format, + uint width, + uint height, + uint depth, + uint mipLevels = 0, + BindFlags bindFlags = BindFlags.ShaderResource, + Usage usage = Usage.Default, + CpuAccessFlags cpuAccessFlags = CpuAccessFlags.None, + ResourceMiscFlags miscFlags = ResourceMiscFlags.None, + TextureLayout textureLayout = TextureLayout.Undefined) + { + if (format == Format.Unknown) + throw new ArgumentException($"format need to be valid", nameof(format)); + + if (width < 1 || width > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) + throw new ArgumentException($"Width need to be in range 1-{D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION}", nameof(width)); + + if (height < 1 || height > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) + throw new ArgumentException($"Height need to be in range 1-{D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION}", nameof(height)); + + if (depth < 1 || depth > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) + throw new ArgumentException($"Depth need to be in range 1-{D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION}", nameof(depth)); + + Width = width; + Height = height; + Depth = depth; + MipLevels = mipLevels; + Format = format; + Usage = usage; + BindFlags = bindFlags; + CPUAccessFlags = cpuAccessFlags; + MiscFlags = miscFlags; + TextureLayout = textureLayout; + } +} diff --git a/src/Vortice.Win32/Graphics/Direct3D12/Apis.cs b/src/Vortice.Win32/Graphics/Direct3D12/Apis.cs new file mode 100644 index 0000000..df9a9bd --- /dev/null +++ b/src/Vortice.Win32/Graphics/Direct3D12/Apis.cs @@ -0,0 +1,369 @@ +// Copyright © Tanner Gooding and Contributors. Licensed under the MIT License (MIT). See License.md in the repository root for more information. + +// Ported from d3dx12.h in DirectX-Graphics-Samples commit a7a87f1853b5540f10920518021d91ae641033fb +// Original source is Copyright © Microsoft. All rights reserved. Licensed under the MIT License (MIT). +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +using Win32.Graphics.Dxgi.Common; +using static Win32.Apis; + +namespace Win32.Graphics.Direct3D12; + +public static unsafe partial class Apis +{ + public static uint D3D12CalcSubresource(uint MipSlice, uint ArraySlice, uint PlaneSlice, uint MipLevels, uint ArraySize) + { + return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize; + } + + public static bool D3D12IsLayoutOpaque(TextureLayout Layout) + { + return Layout == TextureLayout.Unknown || Layout == TextureLayout.L64KbUndefinedSwizzle; + } + + public static void D3D12DecomposeSubresource( + uint Subresource, + uint MipLevels, + uint ArraySize, + out uint MipSlice, + out uint ArraySlice, + out uint PlaneSlice) + { + MipSlice = Subresource % MipLevels; + ArraySlice = (Subresource / MipLevels) % ArraySize; + PlaneSlice = Subresource / (MipLevels * ArraySize); + } + + public static void MemcpySubresource( + MemcpyDest* pDest, + SubresourceData* pSrc, + nuint RowSizeInBytes, + uint NumRows, + uint NumSlices) + { + for (var z = 0u; z < NumSlices; ++z) + { + var pDestSlice = (byte*)pDest->pData + pDest->SlicePitch * z; + var pSrcSlice = (byte*)pSrc->pData + pSrc->SlicePitch * (nint)z; + + for (var y = 0u; y < NumRows; ++y) + { + Buffer.MemoryCopy( + pSrcSlice + pSrc->RowPitch * (nint)y, + pDestSlice + pDest->RowPitch * y, + RowSizeInBytes, + RowSizeInBytes + ); + } + } + } + + public static void MemcpySubresource( + MemcpyDest* pDest, + void* pResourceData, + SubresourceInfo* pSrc, + nuint RowSizeInBytes, uint NumRows, uint NumSlices) + { + for (var z = 0u; z < NumSlices; ++z) + { + var pDestSlice = (byte*)pDest->pData + pDest->SlicePitch * z; + var pSrcSlice = ((byte*)pResourceData + pSrc->Offset) + pSrc->DepthPitch * (nint)z; + + for (var y = 0u; y < NumRows; ++y) + { + Buffer.MemoryCopy( + pSrcSlice + pSrc->RowPitch * (nint)y, + pDestSlice + pDest->RowPitch * y, + (ulong)RowSizeInBytes, + (ulong)RowSizeInBytes + ); + } + } + } + + public static byte D3D12GetFormatPlaneCount(ID3D12Device* device, Format format) + { + FeatureDataFormatInfo formatInfo = new FeatureDataFormatInfo + { + Format = format, + PlaneCount = 0, + }; + + if (device->CheckFeatureSupport(Feature.FormatInfo, &formatInfo, (uint)(sizeof(FeatureDataFormatInfo))).Failure) + { + return 0; + } + + return formatInfo.PlaneCount; + } + + public static ulong GetRequiredIntermediateSize(ID3D12Resource* pDestinationResource, uint FirstSubresource, uint NumSubresources) + { + var Desc = pDestinationResource->GetDesc(); + ulong RequiredSize = 0; + + ID3D12Device* pDevice = null; + _ = pDestinationResource->GetDevice(__uuidof(), (void**)&pDevice); + + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, null, null, null, &RequiredSize); + _ = pDevice->Release(); + + return RequiredSize; + } + + + + public static ulong UpdateSubresources( + ID3D12GraphicsCommandList* pCmdList, + ID3D12Resource* pDestinationResource, + ID3D12Resource* pIntermediate, + uint FirstSubresource, + uint NumSubresources, + ulong RequiredSize, + PlacedSubresourceFootprint* pLayouts, + uint* pNumRows, + ulong* pRowSizesInBytes, + SubresourceData* pSrcData) + { + ResourceDescription IntermediateDesc = pIntermediate->GetDesc(); + ResourceDescription DestinationDesc = pDestinationResource->GetDesc(); + + if (IntermediateDesc.Dimension != ResourceDimension.Buffer || + IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || + RequiredSize > unchecked((ulong)-1) || + (DestinationDesc.Dimension == ResourceDimension.Buffer && (FirstSubresource != 0 || NumSubresources != 1))) + { + return 0; + } + + byte* pData; + HResult hr = pIntermediate->Map(0, null, (void**)(&pData)); + + if (hr.Failure) + { + return 0; + } + + for (uint i = 0; i < NumSubresources; ++i) + { + if (pRowSizesInBytes[i] > unchecked((nuint)(-1))) + { + return 0; + } + + MemcpyDest DestData = new MemcpyDest + { + pData = pData + pLayouts[i].Offset, + RowPitch = pLayouts[i].Footprint.RowPitch, + SlicePitch = pLayouts[i].Footprint.RowPitch * pNumRows[i], + }; + MemcpySubresource(&DestData, &pSrcData[i], unchecked((nuint)(pRowSizesInBytes[i])), pNumRows[i], pLayouts[i].Footprint.Depth); + } + + pIntermediate->Unmap(0, null); + if (DestinationDesc.Dimension == ResourceDimension.Buffer) + { + pCmdList->CopyBufferRegion(pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width); + } + else + { + for (uint i = 0; i < NumSubresources; ++i) + { + TextureCopyLocation Dst = new(pDestinationResource, i + FirstSubresource); + TextureCopyLocation Src = new(pIntermediate, pLayouts[i]); + + pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, null); + } + } + + return RequiredSize; + } + + public static ulong UpdateSubresources( + ID3D12GraphicsCommandList* pCmdList, + ID3D12Resource* pDestinationResource, + ID3D12Resource* pIntermediate, + uint FirstSubresource, + uint NumSubresources, + ulong RequiredSize, + PlacedSubresourceFootprint* pLayouts, + uint* pNumRows, + ulong* pRowSizesInBytes, + void* pResourceData, + SubresourceInfo* pSrcData) + { + var IntermediateDesc = pIntermediate->GetDesc(); + var DestinationDesc = pDestinationResource->GetDesc(); + + if (IntermediateDesc.Dimension != ResourceDimension.Buffer || + IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || + RequiredSize > unchecked((nuint)(-1)) || + (DestinationDesc.Dimension == ResourceDimension.Buffer && (FirstSubresource != 0 || NumSubresources != 1))) + { + return 0; + } + + byte* pData; + HResult hr = pIntermediate->Map(0, null, (void**)&pData); + + if (hr.Failure) + { + return 0; + } + + for (var i = 0u; i < NumSubresources; ++i) + { + if (pRowSizesInBytes[i] > unchecked((nuint)(-1))) + { + return 0; + } + + MemcpyDest DestData = new MemcpyDest + { + pData = pData + pLayouts[i].Offset, + RowPitch = (nuint)pLayouts[i].Footprint.RowPitch, + SlicePitch = (nuint)(pLayouts[i].Footprint.RowPitch * pNumRows[i]) + }; + + MemcpySubresource(&DestData, pResourceData, &pSrcData[i], (nuint)pRowSizesInBytes[i], pNumRows[i], pLayouts[i].Footprint.Depth); + } + pIntermediate->Unmap(0, null); + + if (DestinationDesc.Dimension == ResourceDimension.Buffer) + { + pCmdList->CopyBufferRegion(pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width); + } + else + { + for (var i = 0u; i < NumSubresources; ++i) + { + TextureCopyLocation Dst = new(pDestinationResource, i + FirstSubresource); + TextureCopyLocation Src = new(pIntermediate, pLayouts[i]); + pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, null); + } + } + return RequiredSize; + } + + //public static ulong UpdateSubresources(ID3D12GraphicsCommandList* pCmdList, ID3D12Resource* pDestinationResource, ID3D12Resource* pIntermediate, [NativeTypeName("UINT64")] ulong IntermediateOffset, uint FirstSubresource, uint NumSubresources, D3D12_SUBRESOURCE_DATA* pSrcData) + //{ + // ulong RequiredSize = 0; + // ulong MemToAlloc = (ulong)(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(uint) + sizeof(ulong)) * NumSubresources; + + // if (MemToAlloc > unchecked((nuint)(-1))) + // { + // return 0; + // } + + // var pMem = HeapAlloc(GetProcessHeap(), 0, (nuint)MemToAlloc); + + // if (pMem == null) + // { + // return 0; + // } + + // var pLayouts = (D3D12_PLACED_SUBRESOURCE_FOOTPRINT*)pMem; + // ulong* pRowSizesInBytes = (ulong*)(pLayouts + NumSubresources); + // uint* pNumRows = (uint*)(pRowSizesInBytes + NumSubresources); + + // var Desc = pDestinationResource->GetDesc(); + + // ID3D12Device* pDevice = null; + // _ = pDestinationResource->GetDevice(__uuidof(), (void**)&pDevice); + + // pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize); + // _ = pDevice->Release(); + + // ulong Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData); + // _ = HeapFree(GetProcessHeap(), 0, pMem); + // return Result; + //} + + //public static ulong UpdateSubresources(ID3D12GraphicsCommandList* pCmdList, ID3D12Resource* pDestinationResource, ID3D12Resource* pIntermediate, [NativeTypeName("UINT64")] ulong IntermediateOffset, uint FirstSubresource, uint NumSubresources, [NativeTypeName("const void *")] void* pResourceData, [NativeTypeName("D3D12_SUBRESOURCE_INFO *")] D3D12_SUBRESOURCE_INFO* pSrcData) + //{ + // ulong RequiredSize = 0; + // ulong MemToAlloc = (ulong)(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(uint) + sizeof(ulong)) * NumSubresources; + + // if (MemToAlloc > unchecked((nuint)(-1))) + // { + // return 0; + // } + + // var pMem = HeapAlloc(GetProcessHeap(), 0, (nuint)MemToAlloc); + + // if (pMem == null) + // { + // return 0; + // } + + // var pLayouts = (D3D12_PLACED_SUBRESOURCE_FOOTPRINT*)pMem; + // ulong* pRowSizesInBytes = (ulong*)(pLayouts + NumSubresources); + // uint* pNumRows = (uint*)(pRowSizesInBytes + NumSubresources); + + // var Desc = pDestinationResource->GetDesc(); + + // ID3D12Device* pDevice = null; + // _ = pDestinationResource->GetDevice(__uuidof(), (void**)&pDevice); + + // pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize); + // _ = pDevice->Release(); + + // ulong Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pResourceData, pSrcData); + // _ = HeapFree(GetProcessHeap(), 0, pMem); + // return Result; + //} + + public static ulong UpdateSubresources( + uint MaxSubresources, + ID3D12GraphicsCommandList* pCmdList, + ID3D12Resource* pDestinationResource, + ID3D12Resource* pIntermediate, + ulong IntermediateOffset, + uint FirstSubresource, + uint NumSubresources, + SubresourceData* pSrcData) + { + ulong RequiredSize = 0; + PlacedSubresourceFootprint* Layouts = stackalloc PlacedSubresourceFootprint[(int)MaxSubresources]; + uint* NumRows = stackalloc uint[(int)MaxSubresources]; + ulong* RowSizesInBytes = stackalloc ulong[(int)MaxSubresources]; + + var Desc = pDestinationResource->GetDesc(); + + ID3D12Device* pDevice = null; + _ = pDestinationResource->GetDevice(__uuidof(), (void**)&pDevice); + + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize); + _ = pDevice->Release(); + + return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData); + } + + public static ulong UpdateSubresources( + uint MaxSubresources, + ID3D12GraphicsCommandList* pCmdList, + ID3D12Resource* pDestinationResource, + ID3D12Resource* pIntermediate, + ulong IntermediateOffset, + uint FirstSubresource, + uint NumSubresources, + void* pResourceData, + SubresourceInfo* pSrcData) + { + ulong RequiredSize = 0; + PlacedSubresourceFootprint* Layouts = stackalloc PlacedSubresourceFootprint[(int)MaxSubresources]; + uint* NumRows = stackalloc uint[(int)MaxSubresources]; + ulong* RowSizesInBytes = stackalloc ulong[(int)MaxSubresources]; + + var Desc = pDestinationResource->GetDesc(); + + ID3D12Device* pDevice = null; + _ = pDestinationResource->GetDevice(__uuidof(), (void**)&pDevice); + + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize); + _ = pDevice->Release(); + + return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pResourceData, pSrcData); + } +} diff --git a/src/Vortice.Win32/Graphics/Direct3D12/Box.cs b/src/Vortice.Win32/Graphics/Direct3D12/Box.cs new file mode 100644 index 0000000..ff83ad0 --- /dev/null +++ b/src/Vortice.Win32/Graphics/Direct3D12/Box.cs @@ -0,0 +1,57 @@ +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +namespace Win32.Graphics.Direct3D12; + +public unsafe partial struct Box : IEquatable +{ + public Box(int left, int right) + { + this.left = (uint)left; + top = 0; + front = 0; + this.right = (uint)right; + bottom = 1; + back = 1; + } + + public Box(int Left, int Top, int Right, int Bottom) + { + left = (uint)Left; + top = (uint)Top; + front = 0; + right = (uint)Right; + bottom = (uint)Bottom; + back = 1; + } + + public Box(int Left, int Top, int Front, int Right, int Bottom, int Back) + { + left = (uint)Left; + top = (uint)Top; + front = (uint)Front; + right = (uint)Right; + bottom = (uint)Bottom; + back = (uint)Back; + } + + public static bool operator ==(in Box left, in Box right) + => (left.left == right.left) + && (left.top == right.top) + && (left.front == right.front) + && (left.right == right.right) + && (left.bottom == right.bottom) + && (left.back == right.back); + + public static bool operator !=(in Box left, in Box right) + => !(left == right); + + public override bool Equals(object? obj) => (obj is Box other) && Equals(other); + + public bool Equals(Box other) => this == other; + + public override int GetHashCode() + { + return HashCode.Combine(left, top, front, right, bottom, back); + } +} diff --git a/src/Vortice.Win32/Graphics/Direct3D12/ClearValue.cs b/src/Vortice.Win32/Graphics/Direct3D12/ClearValue.cs new file mode 100644 index 0000000..2e0ddc2 --- /dev/null +++ b/src/Vortice.Win32/Graphics/Direct3D12/ClearValue.cs @@ -0,0 +1,78 @@ +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +using Win32.Graphics.Dxgi.Common; + +namespace Win32.Graphics.Direct3D12; + +public unsafe partial struct ClearValue : IEquatable +{ + public ClearValue(Format format, float* color) + { + Unsafe.SkipInit(out this); + + Format = format; + Anonymous.Color[0] = color[0]; + Anonymous.Color[1] = color[1]; + Anonymous.Color[2] = color[2]; + Anonymous.Color[3] = color[3]; + } + + public ClearValue(Format format, float depth, byte stencil) + { + Format = format; + Anonymous.DepthStencil.Depth = depth; + Anonymous.DepthStencil.Stencil = stencil; + } + + public static bool operator ==(in ClearValue left, in ClearValue right) + { + if (left.Format != right.Format) + { + return false; + } + + if (left.Format == Format.D24UnormS8Uint || + left.Format == Format.D16Unorm || + left.Format == Format.D32Float || + left.Format == Format.D32FloatS8X24Uint) + { + return (left.Anonymous.DepthStencil.Depth == right.Anonymous.DepthStencil.Depth) && (left.Anonymous.DepthStencil.Stencil == right.Anonymous.DepthStencil.Stencil); + } + else + { + return (left.Anonymous.Color[0] == right.Anonymous.Color[0]) && (left.Anonymous.Color[1] == right.Anonymous.Color[1]) && (left.Anonymous.Color[2] == right.Anonymous.Color[2]) && (left.Anonymous.Color[3] == right.Anonymous.Color[3]); + } + } + + public static bool operator !=(in ClearValue left, in ClearValue right) + => !(left == right); + + public override bool Equals(object? obj) => (obj is ClearValue other) && Equals(other); + + public bool Equals(ClearValue other) => this == other; + + public override int GetHashCode() + { + var hashCode = new HashCode(); + { + hashCode.Add(Format); + + if (Format == Format.D24UnormS8Uint || + Format == Format.D16Unorm || + Format == Format.D32Float || + Format == Format.D32FloatS8X24Uint) + { + hashCode.Add(Anonymous.DepthStencil); + } + else + { + hashCode.Add(Anonymous.Color[0]); + hashCode.Add(Anonymous.Color[1]); + hashCode.Add(Anonymous.Color[2]); + hashCode.Add(Anonymous.Color[3]); + } + } + return hashCode.ToHashCode(); + } +} diff --git a/src/Vortice.Win32/Graphics/Direct3D12/ResourceDescription.cs b/src/Vortice.Win32/Graphics/Direct3D12/ResourceDescription.cs new file mode 100644 index 0000000..a0fb902 --- /dev/null +++ b/src/Vortice.Win32/Graphics/Direct3D12/ResourceDescription.cs @@ -0,0 +1,183 @@ +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +using Win32.Graphics.Dxgi.Common; +using static Win32.Graphics.Direct3D12.Apis; + +namespace Win32.Graphics.Direct3D12; + +public unsafe partial struct ResourceDescription : IEquatable +{ + /// + /// Initializes a new instance of the struct. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public ResourceDescription( + ResourceDimension dimension, + ulong alignment, + ulong width, + uint height, + ushort depthOrArraySize, + ushort mipLevels, + Format format, + uint sampleCount, + uint sampleQuality, + TextureLayout layout, + ResourceFlags flags) + { + Dimension = dimension; + Alignment = alignment; + Width = width; + Height = height; + DepthOrArraySize = depthOrArraySize; + MipLevels = mipLevels; + Format = format; + SampleDesc = new(sampleCount, sampleQuality); + Layout = layout; + Flags = flags; + } + + public static ResourceDescription Buffer(in ResourceAllocationInfo resourceAllocInfo, ResourceFlags flags = ResourceFlags.None) + { + return new ResourceDescription( + ResourceDimension.Buffer, + resourceAllocInfo.Alignment, + resourceAllocInfo.SizeInBytes, + 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, flags); + } + + public static ResourceDescription Buffer( + ulong sizeInBytes, + ResourceFlags flags = ResourceFlags.None, + ulong alignment = 0) + { + return new ResourceDescription(ResourceDimension.Buffer, alignment, sizeInBytes, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, flags); + } + + public static ResourceDescription Tex1D(Format format, + ulong width, + ushort arraySize = 1, + ushort mipLevels = 0, + ResourceFlags flags = ResourceFlags.None, + TextureLayout layout = TextureLayout.Unknown, + ulong alignment = 0) + { + return new ResourceDescription(ResourceDimension.Texture1D, alignment, width, 1, arraySize, mipLevels, format, 1, 0, layout, flags); + } + + public static ResourceDescription Tex2D(Format format, + ulong width, + uint height, + ushort arraySize = 1, + ushort mipLevels = 0, + uint sampleCount = 1, + uint sampleQuality = 0, + ResourceFlags flags = ResourceFlags.None, + TextureLayout layout = TextureLayout.Unknown, + ulong alignment = 0) + { + return new ResourceDescription(ResourceDimension.Texture2D, + alignment, + width, + height, + arraySize, + mipLevels, + format, + sampleCount, + sampleQuality, + layout, + flags); + } + + public static ResourceDescription Texture3D(Format format, + ulong width, + uint height, + ushort depth, + ushort mipLevels = 0, + ResourceFlags flags = ResourceFlags.None, + TextureLayout layout = TextureLayout.Unknown, + ulong alignment = 0) + { + return new ResourceDescription( + ResourceDimension.Texture3D, + alignment, + width, + height, + depth, + mipLevels, + format, + 1, + 0, + layout, + flags); + } + + public ushort Depth => ((Dimension == ResourceDimension.Texture3D) ? DepthOrArraySize : (ushort)(1)); + + public ushort ArraySize => ((Dimension != ResourceDimension.Texture3D) ? DepthOrArraySize : (ushort)(1)); + + public byte GetPlaneCount(ID3D12Device* pDevice) + { + return D3D12GetFormatPlaneCount(pDevice, Format); + } + + public uint GetSubresources(ID3D12Device* pDevice) + { + return MipLevels * (uint)ArraySize * GetPlaneCount(pDevice); + } + + public uint CalcSubresource(uint MipSlice, uint ArraySlice, uint PlaneSlice) + { + return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize); + } + + public static bool operator ==(in ResourceDescription left, in ResourceDescription right) + { + return (left.Dimension == right.Dimension) + && (left.Alignment == right.Alignment) + && (left.Width == right.Width) + && (left.Height == right.Height) + && (left.DepthOrArraySize == right.DepthOrArraySize) + && (left.MipLevels == right.MipLevels) + && (left.Format == right.Format) + && (left.SampleDesc.Count == right.SampleDesc.Count) + && (left.SampleDesc.Quality == right.SampleDesc.Quality) + && (left.Layout == right.Layout) + && (left.Flags == right.Flags); + } + + public static bool operator !=(in ResourceDescription l, in ResourceDescription r) + => !(l == r); + + public override bool Equals(object? obj) => (obj is ResourceDescription other) && Equals(other); + + public bool Equals(ResourceDescription other) => this == other; + + public override int GetHashCode() + { + var hashCode = new HashCode(); + { + hashCode.Add(Dimension); + hashCode.Add(Alignment); + hashCode.Add(Width); + hashCode.Add(Height); + hashCode.Add(DepthOrArraySize); + hashCode.Add(MipLevels); + hashCode.Add(Format); + hashCode.Add(SampleDesc); + hashCode.Add(Layout); + hashCode.Add(Flags); + } + return hashCode.ToHashCode(); + } +} diff --git a/src/Vortice.Win32/Graphics/Direct3D12/SubresourceFootprint.cs b/src/Vortice.Win32/Graphics/Direct3D12/SubresourceFootprint.cs new file mode 100644 index 0000000..edee862 --- /dev/null +++ b/src/Vortice.Win32/Graphics/Direct3D12/SubresourceFootprint.cs @@ -0,0 +1,27 @@ +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +using Win32.Graphics.Dxgi.Common; + +namespace Win32.Graphics.Direct3D12; + +public unsafe partial struct SubresourceFootprint +{ + public SubresourceFootprint(Format format, uint width, uint height, uint depth, uint rowPitch) + { + Format = format; + Width = width; + Height = height; + Depth = depth; + RowPitch = rowPitch; + } + + public SubresourceFootprint(in ResourceDescription resourceDesc, uint rowPitch) + { + Format = resourceDesc.Format; + Width = (uint)resourceDesc.Width; + Height = resourceDesc.Height; + Depth = (resourceDesc.Dimension == ResourceDimension.Texture3D ? resourceDesc.DepthOrArraySize : 1u); + RowPitch = rowPitch; + } +} diff --git a/src/Vortice.Win32/Graphics/Direct3D12/TextureCopyLocation.cs b/src/Vortice.Win32/Graphics/Direct3D12/TextureCopyLocation.cs new file mode 100644 index 0000000..2d9fc11 --- /dev/null +++ b/src/Vortice.Win32/Graphics/Direct3D12/TextureCopyLocation.cs @@ -0,0 +1,35 @@ +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +namespace Win32.Graphics.Direct3D12; + +public unsafe partial struct TextureCopyLocation +{ + public TextureCopyLocation(ID3D12Resource* resource) + { + Unsafe.SkipInit(out this); + + pResource = resource; + Type = TextureCopyType.SubresourceIndex; + Anonymous.PlacedFootprint = new PlacedSubresourceFootprint(); + } + + public TextureCopyLocation(ID3D12Resource* resource, in PlacedSubresourceFootprint footprint) + { + Unsafe.SkipInit(out this); + + pResource = resource; + Type = TextureCopyType.PlacedFootprint; + Anonymous.PlacedFootprint = footprint; + } + + public TextureCopyLocation(ID3D12Resource* resource, uint subresourceIndex) + { + Unsafe.SkipInit(out this); + + pResource = resource; + Type = TextureCopyType.SubresourceIndex; + Anonymous.PlacedFootprint = new PlacedSubresourceFootprint(); + Anonymous.SubresourceIndex = subresourceIndex; + } +} diff --git a/src/Vortice.Win32/Graphics/Dxgi/FormatHelper.cs b/src/Vortice.Win32/Graphics/Dxgi/FormatHelper.cs new file mode 100644 index 0000000..f390d6c --- /dev/null +++ b/src/Vortice.Win32/Graphics/Dxgi/FormatHelper.cs @@ -0,0 +1,560 @@ +// Copyright © Amer Koleci and Contributors. +// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. + +namespace Win32.Graphics.Dxgi.Common; + +/// +/// Helper to use with . +/// +public static class FormatHelper +{ + public const Format Xbox_R10G10B10_7E3_A2_Float = (Format)116; + public const Format Xbox_R10G10B10_6E4_A2_Float = (Format)117; + public const Format Xbox_D16_UNorm_S8_UInt = (Format)118; + public const Format Xbox_R16_UNorm_X8_Typeless = (Format)119; + public const Format Xbox_X16_Typeless_G8_UInt = (Format)120; + public const Format Xbox_R10G10B10_SNorm_A2_UNorm = (Format)189; + public const Format Xbox_R4G4_UNorm = (Format)190; + + /// + /// Return the BPP for a given . + /// + /// The DXGI format. + /// BPP of + public static int GetBitsPerPixel(this Format format) + { + switch (format) + { + case Format.R32G32B32A32Typeless: + case Format.R32G32B32A32Float: + case Format.R32G32B32A32Uint: + case Format.R32G32B32A32Sint: + return 128; + + case Format.R32G32B32Typeless: + case Format.R32G32B32Float: + case Format.R32G32B32Uint: + case Format.R32G32B32Sint: + return 96; + + case Format.R16G16B16A16Typeless: + case Format.R16G16B16A16Float: + case Format.R16G16B16A16Unorm: + case Format.R16G16B16A16Uint: + case Format.R16G16B16A16Snorm: + case Format.R16G16B16A16Sint: + case Format.R32G32Typeless: + case Format.R32G32Float: + case Format.R32G32Uint: + case Format.R32G32Sint: + case Format.R32G8X24Typeless: + case Format.D32FloatS8X24Uint: + case Format.R32FloatX8X24Typeless: + case Format.X32TypelessG8X24Uint: + case Format.Y416: + case Format.Y210: + case Format.Y216: + return 64; + + case Format.R10G10B10A2Typeless: + case Format.R10G10B10A2Unorm: + case Format.R10G10B10A2Uint: + case Format.R11G11B10Float: + case Format.R8G8B8A8Typeless: + case Format.R8G8B8A8Unorm: + case Format.R8G8B8A8UnormSrgb: + case Format.R8G8B8A8Snorm: + case Format.R8G8B8A8Uint: + case Format.R8G8B8A8Sint: + case Format.R16G16Typeless: + case Format.R16G16Float: + case Format.R16G16Unorm: + case Format.R16G16Snorm: + case Format.R16G16Uint: + case Format.R16G16Sint: + case Format.R32Typeless: + case Format.D32Float: + case Format.R32Float: + case Format.R32Uint: + case Format.R32Sint: + case Format.R24G8Typeless: + case Format.D24UnormS8Uint: + case Format.R24UnormX8Typeless: + case Format.X24TypelessG8Uint: + case Format.R9G9B9E5SharedExp: + case Format.R8G8B8G8Unorm: + case Format.G8R8G8B8Unorm: + case Format.B8G8R8A8Unorm: + case Format.B8G8R8X8Unorm: + case Format.R10G10B10XRBiasA2Unorm: + case Format.B8G8R8A8Typeless: + case Format.B8G8R8A8UnormSrgb: + case Format.B8G8R8X8Typeless: + case Format.B8G8R8X8UnormSrgb: + case Format.AYUV: + case Format.Y410: + case Format.YUY2: + case Xbox_R10G10B10_7E3_A2_Float: + case Xbox_R10G10B10_6E4_A2_Float: + case Xbox_R10G10B10_SNorm_A2_UNorm: + return 32; + + case Format.P010: + case Format.P016: + case Xbox_D16_UNorm_S8_UInt: + case Xbox_R16_UNorm_X8_Typeless: + case Xbox_X16_Typeless_G8_UInt: + case Format.V408: + return 24; + + case Format.R8G8Typeless: + case Format.R8G8Unorm: + case Format.R8G8Uint: + case Format.R8G8Snorm: + case Format.R8G8Sint: + case Format.R16Typeless: + case Format.R16Float: + case Format.D16Unorm: + case Format.R16Unorm: + case Format.R16Uint: + case Format.R16Snorm: + case Format.R16Sint: + case Format.B5G6R5Unorm: + case Format.B5G5R5A1Unorm: + case Format.A8P8: + case Format.B4G4R4A4Unorm: + case Format.P208: + case Format.V208: + return 16; + + case Format.NV12: + case Format.Opaque420: + case Format.NV11: + return 12; + + case Format.R8Typeless: + case Format.R8Unorm: + case Format.R8Uint: + case Format.R8Snorm: + case Format.R8Sint: + case Format.A8Unorm: + case Format.BC2Typeless: + case Format.BC2Unorm: + case Format.BC2UnormSrgb: + case Format.BC3Typeless: + case Format.BC3Unorm: + case Format.BC3UnormSrgb: + case Format.BC5Typeless: + case Format.BC5Unorm: + case Format.BC5Snorm: + case Format.BC6HTypeless: + case Format.BC6HUF16: + case Format.BC6HSF16: + case Format.BC7Typeless: + case Format.BC7Unorm: + case Format.BC7UnormSrgb: + case Format.AI44: + case Format.IA44: + case Format.P8: + case Xbox_R4G4_UNorm: + return 8; + + case Format.R1Unorm: + return 1; + + case Format.BC1Typeless: + case Format.BC1Unorm: + case Format.BC1UnormSrgb: + case Format.BC4Typeless: + case Format.BC4Unorm: + case Format.BC4Snorm: + return 4; + + default: + return 0; + } + } + + /// + /// Returns true if the is valid. + /// + /// A format to validate + /// True if the is valid. + public static bool IsValid(this Format format) + { + return ((int)(format) >= 1 && (int)(format) <= 115); + } + + /// + /// Returns true if the is a compressed format. + /// + /// The format to check for compressed. + /// True if the is a compressed format + public static bool IsCompressed(this Format format) + { + switch (format) + { + case Format.BC1Typeless: + case Format.BC1Unorm: + case Format.BC1UnormSrgb: + case Format.BC2Typeless: + case Format.BC2Unorm: + case Format.BC2UnormSrgb: + case Format.BC3Typeless: + case Format.BC3Unorm: + case Format.BC3UnormSrgb: + case Format.BC4Typeless: + case Format.BC4Unorm: + case Format.BC4Snorm: + case Format.BC5Typeless: + case Format.BC5Unorm: + case Format.BC5Snorm: + case Format.BC6HTypeless: + case Format.BC6HUF16: + case Format.BC6HSF16: + case Format.BC7Typeless: + case Format.BC7Unorm: + case Format.BC7UnormSrgb: + return true; + + default: + return false; + } + } + + /// + /// Determines whether the specified is packed. + /// + /// The DXGI Format. + /// true if the specified is packed; otherwise, false. + public static bool IsPacked(this Format format) + { + switch (format) + { + case Format.R8G8B8G8Unorm: + case Format.G8R8G8B8Unorm: + case Format.YUY2: // 4:2:2 8-bit + case Format.Y210: // 4:2:2 10-bit + case Format.Y216: // 4:2:2 16-bit + return true; + + default: + return false; + } + } + + /// + /// Determines whether the specified is video. + /// + /// The . + /// true if the specified is video; otherwise, false. + public static bool IsVideo(this Format format) + { + switch (format) + { + case Format.AYUV: + case Format.Y410: + case Format.Y416: + case Format.NV12: + case Format.P010: + case Format.P016: + case Format.YUY2: + case Format.Y210: + case Format.Y216: + case Format.NV11: + // These video formats can be used with the 3D pipeline through special view mappings + + case Format.Opaque420: + case Format.AI44: + case Format.IA44: + case Format.P8: + case Format.A8P8: + // These are limited use video formats not usable in any way by the 3D pipeline + + case Format.P208: + case Format.V208: + case Format.V408: + // These video formats are for JPEG Hardware decode (DXGI 1.4) + return true; + + default: + return false; + } + } + + public static bool IsPlanar(this Format format) + { + switch (format) + { + case Format.NV12: // 4:2:0 8-bit + case Format.P010: // 4:2:0 10-bit + case Format.P016: // 4:2:0 16-bit + case Format.Opaque420:// 4:2:0 8-bit + case Format.NV11: // 4:1:1 8-bit + + case Format.P208: // 4:2:2 8-bit + case Format.V208: // 4:4:0 8-bit + case Format.V408: // 4:4:4 8-bit + // These are JPEG Hardware decode formats (DXGI 1.4) + case Xbox_D16_UNorm_S8_UInt: + case Xbox_R16_UNorm_X8_Typeless: + case Xbox_X16_Typeless_G8_UInt: + // These are Xbox One platform specific types + return true; + + default: + return false; + } + } + + public static bool IsPalettized(this Format format) + { + switch (format) + { + case Format.AI44: + case Format.IA44: + case Format.P8: + case Format.A8P8: + return true; + + default: + return false; + } + } + + public static bool IsDepthStencil(this Format format) + { + switch (format) + { + case Format.R32G8X24Typeless: + case Format.D32FloatS8X24Uint: + case Format.R32FloatX8X24Typeless: + case Format.X32TypelessG8X24Uint: + case Format.D32Float: + case Format.R24G8Typeless: + case Format.D24UnormS8Uint: + case Format.R24UnormX8Typeless: + case Format.X24TypelessG8Uint: + case Format.D16Unorm: + case Xbox_D16_UNorm_S8_UInt: + case Xbox_R16_UNorm_X8_Typeless: + case Xbox_X16_Typeless_G8_UInt: + return true; + + default: + return false; + } + } + + /// + /// Determines whether the specified is a SRGB format. + /// + /// The . + /// true if the specified is a SRGB format; otherwise, false. + public static bool IsSRGB(this Format format) + { + switch (format) + { + case Format.R8G8B8A8UnormSrgb: + case Format.BC1UnormSrgb: + case Format.BC2UnormSrgb: + case Format.BC3UnormSrgb: + case Format.B8G8R8A8UnormSrgb: + case Format.B8G8R8X8UnormSrgb: + case Format.BC7UnormSrgb: + return true; + + default: + return false; + } + } + + /// + /// Determines whether the specified is typeless. + /// + /// The . + /// + /// true if the specified is typeless; otherwise, false. + public static bool IsTypeless(this Format format, bool partialTypeless = true) + { + switch (format) + { + case Format.R32G32B32A32Typeless: + case Format.R32G32B32Typeless: + case Format.R16G16B16A16Typeless: + case Format.R32G32Typeless: + case Format.R32G8X24Typeless: + case Format.R10G10B10A2Typeless: + case Format.R8G8B8A8Typeless: + case Format.R16G16Typeless: + case Format.R32Typeless: + case Format.R24G8Typeless: + case Format.R8G8Typeless: + case Format.R16Typeless: + case Format.R8Typeless: + case Format.BC1Typeless: + case Format.BC2Typeless: + case Format.BC3Typeless: + case Format.BC4Typeless: + case Format.BC5Typeless: + case Format.B8G8R8A8Typeless: + case Format.B8G8R8X8Typeless: + case Format.BC6HTypeless: + case Format.BC7Typeless: + return true; + + case Format.R32FloatX8X24Typeless: + case Format.X32TypelessG8X24Uint: + case Format.R24UnormX8Typeless: + case Format.X24TypelessG8Uint: + case Xbox_R16_UNorm_X8_Typeless: + case Xbox_X16_Typeless_G8_UInt: + return partialTypeless; + + default: + return false; + } + } + + public static bool IsBGR(this Format format) + { + switch (format) + { + case Format.B5G6R5Unorm: + case Format.B5G5R5A1Unorm: + case Format.B8G8R8A8Unorm: + case Format.B8G8R8X8Unorm: + case Format.B8G8R8A8Typeless: + case Format.B8G8R8A8UnormSrgb: + case Format.B8G8R8X8Typeless: + case Format.B8G8R8X8UnormSrgb: + case Format.B4G4R4A4Unorm: + return true; + + default: + return false; + } + } + + public static void GetSurfaceInfo( + Format format, + int width, + int height, + out int rowPitch, + out int slicePitch, + out int rowCount) + { + bool bc = false; + bool packed = false; + bool planar = false; + int bpe = 0; + + switch (format) + { + case Format.BC1Typeless: + case Format.BC1Unorm: + case Format.BC1UnormSrgb: + case Format.BC4Typeless: + case Format.BC4Unorm: + case Format.BC4Snorm: + bc = true; + bpe = 8; + break; + + case Format.BC2Typeless: + case Format.BC2Unorm: + case Format.BC2UnormSrgb: + case Format.BC3Typeless: + case Format.BC3Unorm: + case Format.BC3UnormSrgb: + case Format.BC5Typeless: + case Format.BC5Unorm: + case Format.BC5Snorm: + case Format.BC6HTypeless: + case Format.BC6HUF16: + case Format.BC6HSF16: + case Format.BC7Typeless: + case Format.BC7Unorm: + case Format.BC7UnormSrgb: + bc = true; + bpe = 16; + break; + + case Format.R8G8B8G8Unorm: + case Format.G8R8G8B8Unorm: + case Format.YUY2: + packed = true; + bpe = 4; + break; + + case Format.Y210: + case Format.Y216: + packed = true; + bpe = 8; + break; + + case Format.NV12: + case Format.Opaque420: + case Format.P208: + planar = true; + bpe = 2; + break; + + case Format.P010: + case Format.P016: + planar = true; + bpe = 4; + break; + + default: + break; + } + + if (bc) + { + int numBlocksWide = 0; + if (width > 0) + { + numBlocksWide = Math.Max(1, (width + 3) / 4); + } + int numBlocksHigh = 0; + if (height > 0) + { + numBlocksHigh = Math.Max(1, (height + 3) / 4); + } + rowPitch = numBlocksWide * bpe; + rowCount = numBlocksHigh; + slicePitch = rowPitch * numBlocksHigh; + } + else if (packed) + { + rowPitch = ((width + 1) >> 1) * bpe; + rowCount = height; + slicePitch = rowPitch * height; + } + else if (format == Format.NV11) + { + rowPitch = ((width + 3) >> 2) * 4; + rowCount = height * 2; // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data + slicePitch = rowPitch * rowCount; + } + else if (planar) + { + rowPitch = ((width + 1) >> 1) * bpe; + slicePitch = (rowPitch * height) + ((rowPitch * height + 1) >> 1); + rowCount = (int)(height + ((height + 1u) >> 1)); + } + else + { + int bpp = GetBitsPerPixel(format); + rowPitch = (width * bpp + 7) / 8; // round up to nearest byte + rowCount = height; + slicePitch = rowPitch * height; + } + } + + public static void GetSurfaceInfo(Format format, int width, int height, out int rowPitch, out int slicePitch) + { + GetSurfaceInfo(format, width, height, out rowPitch, out slicePitch, out _); + } +} diff --git a/src/Vortice.Win32/Vortice.Win32.csproj b/src/Vortice.Win32/Vortice.Win32.csproj index e4c8496..36e7d8d 100644 --- a/src/Vortice.Win32/Vortice.Win32.csproj +++ b/src/Vortice.Win32/Vortice.Win32.csproj @@ -3,7 +3,7 @@ netstandard2.0;net6.0; Windows API low level bindings. - 1.5.4 + 1.5.5 true