From 84856597d928a261217f5c7fdc7b5db8f0355b63 Mon Sep 17 00:00:00 2001 From: David Hall Date: Tue, 14 Jan 2025 09:06:21 -0700 Subject: [PATCH] Added D3D12 struct ctors to directly set pointers --- PInvoke/Direct3D12/D3D12.Struct.cs | 152 +++++++++++++++++++++++++++-- 1 file changed, 144 insertions(+), 8 deletions(-) diff --git a/PInvoke/Direct3D12/D3D12.Struct.cs b/PInvoke/Direct3D12/D3D12.Struct.cs index 3170e53f1..e6577082b 100644 --- a/PInvoke/Direct3D12/D3D12.Struct.cs +++ b/PInvoke/Direct3D12/D3D12.Struct.cs @@ -1,5 +1,6 @@ using System.Buffers; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Security.Cryptography; @@ -194,7 +195,7 @@ public D3D12_BARRIER_GROUP(D3D12_TEXTURE_BARRIER[] pBarriers, out SafeAllocatedM { Type = D3D12_BARRIER_TYPE.D3D12_BARRIER_TYPE_TEXTURE; NumBarriers = (uint?)pBarriers?.Length ?? 0; - pGlobalBarriers = memoryHandle = SafeCoTaskMemHandle.CreateFromList(pBarriers ?? []); + pTextureBarriers = memoryHandle = SafeCoTaskMemHandle.CreateFromList(pBarriers ?? []); } /// Initializes a new instance of the struct. @@ -204,7 +205,37 @@ public D3D12_BARRIER_GROUP(D3D12_BUFFER_BARRIER[] pBarriers, out SafeAllocatedMe { Type = D3D12_BARRIER_TYPE.D3D12_BARRIER_TYPE_BUFFER; NumBarriers = (uint?)pBarriers?.Length ?? 0; - pGlobalBarriers = memoryHandle = SafeCoTaskMemHandle.CreateFromList(pBarriers ?? []); + pBufferBarriers = memoryHandle = SafeCoTaskMemHandle.CreateFromList(pBarriers ?? []); + } + + /// Initializes a new instance of the struct. + /// The number of barriers. + /// The barriers. + public D3D12_BARRIER_GROUP(SizeT numBarriers, ManagedArrayPointer pBarriers) + { + Type = D3D12_BARRIER_TYPE.D3D12_BARRIER_TYPE_GLOBAL; + NumBarriers = numBarriers; + pGlobalBarriers = pBarriers; + } + + /// Initializes a new instance of the struct. + /// The number of barriers. + /// The barriers. + public D3D12_BARRIER_GROUP(SizeT numBarriers, ManagedArrayPointer pBarriers) + { + Type = D3D12_BARRIER_TYPE.D3D12_BARRIER_TYPE_TEXTURE; + NumBarriers = numBarriers; + pTextureBarriers = pBarriers; + } + + /// Initializes a new instance of the struct. + /// The number of barriers. + /// The barriers. + public D3D12_BARRIER_GROUP(SizeT numBarriers, ManagedArrayPointer pBarriers) + { + Type = D3D12_BARRIER_TYPE.D3D12_BARRIER_TYPE_BUFFER; + NumBarriers = numBarriers; + pBufferBarriers = pBarriers; } } @@ -339,7 +370,21 @@ public struct D3D12_BLEND_DESC /// to the eight render targets that can be bound to the output-merger stage at one time. /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] - public D3D12_RENDER_TARGET_BLEND_DESC[] RenderTarget; + public D3D12_RENDER_TARGET_BLEND_DESC[] _RenderTarget; + + /// + /// Sets the array of D3D12_RENDER_TARGET_BLEND_DESC structures that describe the blend states for render targets; these + /// correspond to the eight render targets that can be bound to the output-merger stage at one time. This method ensures that + /// the structure's value always has a length of 8. + /// + /// The array of D3D12_RENDER_TARGET_BLEND_DESC structures. + [MemberNotNull(nameof(_RenderTarget))] + public void SetRenderTarget(params D3D12_RENDER_TARGET_BLEND_DESC[] value) + { + _RenderTarget = new D3D12_RENDER_TARGET_BLEND_DESC[8]; + if (value is null || value.Length == 0) return; + Array.ConstrainedCopy(value, 0, _RenderTarget, 0, Math.Min(value.Length, 8)); + } /// Initializes a new instance of the struct with standard (not default) values. public D3D12_BLEND_DESC() @@ -358,9 +403,7 @@ public D3D12_BLEND_DESC() LogicOp = D3D12_LOGIC_OP.D3D12_LOGIC_OP_NOOP, RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE.D3D12_COLOR_WRITE_ENABLE_ALL }; - RenderTarget = new D3D12_RENDER_TARGET_BLEND_DESC[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; - for (int i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - RenderTarget[i] = def; + SetRenderTarget(def); } } @@ -3828,6 +3871,24 @@ public struct D3D12_GRAPHICS_PIPELINE_STATE_DESC /// A D3D12_PIPELINE_STATE_FLAGS enumeration constant such as for "tool debug". public D3D12_PIPELINE_STATE_FLAGS Flags; + + /// + /// Sets the number of render targets and the render target formats ensuring that the array is correctly sized. + /// + /// The render targets. + [MemberNotNull(nameof(RTVFormats))] + public void SetRTVFormats(params DXGI_FORMAT[] value) + { + RTVFormats = new DXGI_FORMAT[8]; + if (value is null || value.Length == 0) + { + NumRenderTargets = 0; + } + else + { + Array.ConstrainedCopy(value, 0, RTVFormats, 0, (int)(NumRenderTargets = (uint)Math.Min(value.Length, RTVFormats.Length))); + } + } } /// Describes a heap. @@ -4397,6 +4458,15 @@ public D3D12_INPUT_LAYOUT_DESC(D3D12_INPUT_ELEMENT_DESC[] elements, out SafeAllo NumElements = (uint)(elements?.Length ?? 0); pInputElementDescs = memoryHandle = NumElements > 0 ? SafeCoTaskMemHandle.CreateFromList(elements!) : SafeCoTaskMemHandle.Null; } + + /// Initializes a new instance of the struct. + /// The number of elements. + /// The elements. + public D3D12_INPUT_LAYOUT_DESC(SizeT numElements, ManagedArrayPointer elements) + { + NumElements = numElements; + pInputElementDescs = elements; + } } /// Defines a local root signature state subobject that will be used with associated shaders. @@ -6937,6 +7007,13 @@ public struct D3D12_ROOT_DESCRIPTOR_TABLE /// An initialized D3D12_ROOT_DESCRIPTOR_TABLE. public static D3D12_ROOT_DESCRIPTOR_TABLE Init(D3D12_DESCRIPTOR_RANGE[] ranges, out SafeAllocatedMemoryHandle h) => new() { NumDescriptorRanges = (uint)ranges.Length, pDescriptorRanges = h = SafeCoTaskMemHandle.CreateFromList(ranges) }; + + /// Creates a new instance of a D3D12_ROOT_DESCRIPTOR_TABLE. + /// The number of descriptor ranges in the table layout. + /// The descriptor ranges. + /// An initialized D3D12_ROOT_DESCRIPTOR_TABLE. + public static D3D12_ROOT_DESCRIPTOR_TABLE Init(SizeT numRanges, ArrayPointer ranges) => + new() { NumDescriptorRanges = numRanges, pDescriptorRanges = ranges }; } /// @@ -6972,6 +7049,13 @@ public struct D3D12_ROOT_DESCRIPTOR_TABLE1 /// An initialized D3D12_ROOT_DESCRIPTOR_TABLE1. public static D3D12_ROOT_DESCRIPTOR_TABLE1 Init(D3D12_DESCRIPTOR_RANGE1[] ranges, out SafeAllocatedMemoryHandle h) => new() { NumDescriptorRanges = (uint)ranges.Length, pDescriptorRanges = h = SafeCoTaskMemHandle.CreateFromList(ranges) }; + + /// Creates a new instance of a D3D12_ROOT_DESCRIPTOR_TABLE1. + /// The number of descriptor ranges in the table layout. + /// The descriptor ranges. + /// An initialized D3D12_ROOT_DESCRIPTOR_TABLE1. + public static D3D12_ROOT_DESCRIPTOR_TABLE1 Init(SizeT numRanges, ArrayPointer ranges) => + new() { NumDescriptorRanges = numRanges, pDescriptorRanges = ranges }; } /// Describes descriptors inline in the root signature version 1.1 that appear in shaders. @@ -7075,6 +7159,19 @@ public static D3D12_ROOT_PARAMETER InitAsDescriptorTable([In] D3D12_DESCRIPTOR_R u = new() { DescriptorTable = D3D12_ROOT_DESCRIPTOR_TABLE.Init(pDescriptorRanges, out h) } }; + /// Initializes with a descriptor table. + /// The number of descriptor ranges in the table layout. + /// The descriptor ranges. + /// Specifies the shaders that can access the contents of the root signature slot. + /// An initialized . + public static D3D12_ROOT_PARAMETER InitAsDescriptorTable(SizeT numRanges, [In] ArrayPointer pDescriptorRanges, + [Optional] D3D12_SHADER_VISIBILITY visibility) => new() + { + ParameterType = D3D12_ROOT_PARAMETER_TYPE.D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, + ShaderVisibility = visibility, + u = new() { DescriptorTable = D3D12_ROOT_DESCRIPTOR_TABLE.Init(numRanges, pDescriptorRanges) } + }; + /// Initializes with constants. /// /// The number of constants that occupy a single shader slot (these constants appear like a single constant buffer). All constants @@ -7200,6 +7297,19 @@ public static D3D12_ROOT_PARAMETER1 InitAsDescriptorTable([In] D3D12_DESCRIPTOR_ u = new() { DescriptorTable = D3D12_ROOT_DESCRIPTOR_TABLE1.Init(pDescriptorRanges, out h) } }; + /// Initializes with a descriptor table. + /// The number of descriptor ranges in the table layout. + /// The descriptor ranges. + /// Specifies the shaders that can access the contents of the root signature slot. + /// An initialized . + public static D3D12_ROOT_PARAMETER1 InitAsDescriptorTable(SizeT numRanges, [In] ArrayPointer pDescriptorRanges, + [Optional] D3D12_SHADER_VISIBILITY visibility) => new() + { + ParameterType = D3D12_ROOT_PARAMETER_TYPE.D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, + ShaderVisibility = visibility, + u = new() { DescriptorTable = D3D12_ROOT_DESCRIPTOR_TABLE1.Init(numRanges, pDescriptorRanges) } + }; + /// Initializes with constants. /// /// The number of constants that occupy a single shader slot (these constants appear like a single constant buffer). All constants @@ -7625,8 +7735,7 @@ public struct D3D12_SAMPLER_DESC /// RGBA border color to use if D3D12_TEXTURE_ADDRESS_MODE_BORDER is specified for AddressU, AddressV, or /// AddressW. Range must be between 0.0 and 1.0 inclusive. /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] - public float[] BorderColor; + public D3DCOLORVALUE BorderColor; /// /// Lower end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap level and any level higher @@ -7659,6 +7768,21 @@ public struct D3D12_SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER /// The opaque driver versioning data. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] DriverOpaqueVersioningData; + + /// Initializes a new instance of the struct. + /// The opaque identifier of the driver. + /// The opaque driver versioning data. + /// nameof(driverOpaqueVersioningData), Array length must be 16 or less. + public D3D12_SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER(Guid driverOpaqueGUID, byte[] driverOpaqueVersioningData) + { + DriverOpaqueGUID = driverOpaqueGUID; + DriverOpaqueVersioningData = new byte[16]; + if (driverOpaqueVersioningData.Length > 16) + throw new ArgumentOutOfRangeException(nameof(driverOpaqueVersioningData), "Array length must be 16 or less."); + if (driverOpaqueVersioningData is null || driverOpaqueVersioningData.Length == 0) + return; + Array.ConstrainedCopy(driverOpaqueVersioningData, 0, DriverOpaqueVersioningData, 0, driverOpaqueVersioningData.Length); + } } /// Defines the header for a serialized raytracing acceleration structure. @@ -9560,6 +9684,18 @@ public struct D3D12_VIEW_INSTANCING_DESC /// Configures view instancing with additional options. public D3D12_VIEW_INSTANCING_FLAGS Flags; + /// Initializes a new instance of the struct. + /// The number of views to be used, up to D3D12_MAX_VIEW_INSTANCE_COUNT. + /// The view instance locations. + /// Configures view instancing with additional options. + public D3D12_VIEW_INSTANCING_DESC([Optional] SizeT cViewInstance, [In, Optional] ArrayPointer pViewInstanceLocations, + [Optional] D3D12_VIEW_INSTANCING_FLAGS flags) + { + ViewInstanceCount = cViewInstance; + this.pViewInstanceLocations = pViewInstanceLocations; + Flags = flags; + } + /// Initializes a new instance of the struct. /// The view instance locations. /// Configures view instancing with additional options.