forked from Misaki/GhostEngine
Refactor and enhance graphics and audio systems
Updated target frameworks to .NET 10.0 across multiple projects for compatibility with the latest features. Refactored namespaces and introduced new classes for shader descriptors, FMOD integration, and DirectX 12 utilities using TerraFX. Replaced `Win32` bindings with TerraFX equivalents for DirectX 12. Added a C# wrapper for FMOD Studio API, including DSP and error handling. Enhanced entity queries, component storage, and query filters for better performance and type safety. Introduced new test projects and updated the solution structure. Added `meshoptimizer` bindings and integrated `meshoptimizer_native.dll`. Improved code readability, maintainability, and performance.
This commit is contained in:
@@ -1,32 +1,34 @@
|
||||
using Misaki.HighPerformance.LowLevel.Collections;
|
||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
||||
using System.Diagnostics;
|
||||
using System.Numerics;
|
||||
using Win32;
|
||||
using Win32.Graphics.Direct3D12;
|
||||
using DescriptorIndex = System.Int32;
|
||||
using TerraFX.Interop.DirectX;
|
||||
using TerraFX.Interop.Windows;
|
||||
|
||||
using static TerraFX.Aliases.D3D12_Alias;
|
||||
|
||||
namespace Ghost.Graphics.D3D12.Utilities;
|
||||
|
||||
internal unsafe struct D3D12DescriptorHeap : IDisposable
|
||||
{
|
||||
private const DescriptorIndex _INVALID_DESCRIPTOR_INDEX = -1;
|
||||
private const int _INVALID_DESCRIPTOR_INDEX = -1;
|
||||
|
||||
private readonly D3D12RenderDevice _device;
|
||||
|
||||
private ComPtr<ID3D12DescriptorHeap> _heap;
|
||||
private ComPtr<ID3D12DescriptorHeap> _shaderVisibleHeap;
|
||||
private CpuDescriptorHandle _startCpuHandle;
|
||||
private CpuDescriptorHandle _startCpuHandleShaderVisible;
|
||||
private GpuDescriptorHandle _startGpuHandleShaderVisible;
|
||||
private DescriptorIndex _searchStart;
|
||||
private D3D12_CPU_DESCRIPTOR_HANDLE _startCpuHandle;
|
||||
private D3D12_CPU_DESCRIPTOR_HANDLE _startCpuHandleShaderVisible;
|
||||
private D3D12_GPU_DESCRIPTOR_HANDLE _startGpuHandleShaderVisible;
|
||||
private int _searchStart;
|
||||
private UnsafeArray<bool> _allocatedDescriptors;
|
||||
|
||||
private readonly DescriptorIndex _dynamicHeapStart;
|
||||
private DescriptorIndex _currentDynamicOffset;
|
||||
private readonly int _dynamicHeapStart;
|
||||
private int _currentDynamicOffset;
|
||||
|
||||
private readonly Lock _lock = new();
|
||||
|
||||
public DescriptorHeapType HeapType
|
||||
public D3D12_DESCRIPTOR_HEAP_TYPE HeapType
|
||||
{
|
||||
get;
|
||||
}
|
||||
@@ -54,7 +56,7 @@ internal unsafe struct D3D12DescriptorHeap : IDisposable
|
||||
public readonly ID3D12DescriptorHeap* Heap => _heap.Get();
|
||||
public readonly ID3D12DescriptorHeap* ShaderVisibleHeap => _shaderVisibleHeap.Get();
|
||||
|
||||
public D3D12DescriptorHeap(string name, D3D12RenderDevice device, DescriptorHeapType type, int numDescriptors, int dynamicHeapStart)
|
||||
public D3D12DescriptorHeap(string name, D3D12RenderDevice device, D3D12_DESCRIPTOR_HEAP_TYPE type, int numDescriptors, int dynamicHeapStart)
|
||||
{
|
||||
numDescriptors = Math.Max(64, numDescriptors);
|
||||
|
||||
@@ -62,7 +64,7 @@ internal unsafe struct D3D12DescriptorHeap : IDisposable
|
||||
|
||||
HeapType = type;
|
||||
NumDescriptors = numDescriptors;
|
||||
ShaderVisible = type == DescriptorHeapType.CbvSrvUav || type == DescriptorHeapType.Sampler;
|
||||
ShaderVisible = type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV || type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER;
|
||||
Stride = device.NativeDevice->GetDescriptorHandleIncrementSize(type);
|
||||
|
||||
_dynamicHeapStart = Math.Clamp(dynamicHeapStart, 0, numDescriptors);
|
||||
@@ -71,16 +73,16 @@ internal unsafe struct D3D12DescriptorHeap : IDisposable
|
||||
var success = AllocateResources(numDescriptors);
|
||||
Debug.Assert(success);
|
||||
|
||||
_heap.Get()->SetName(name);
|
||||
_heap.Get()->SetName(name.AsSpan().GetUnsafePtr());
|
||||
if (ShaderVisible)
|
||||
{
|
||||
_shaderVisibleHeap.Get()->SetName($"{name} Shader Visible");
|
||||
_shaderVisibleHeap.Get()->SetName($"{name} Shader Visible".AsSpan().GetUnsafePtr());
|
||||
}
|
||||
}
|
||||
|
||||
public DescriptorIndex AllocateDescriptor() => AllocateDescriptors(1);
|
||||
public int AllocateDescriptor() => AllocateDescriptors(1);
|
||||
|
||||
public DescriptorIndex AllocateDescriptors(int count)
|
||||
public int AllocateDescriptors(int count)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
@@ -125,9 +127,9 @@ internal unsafe struct D3D12DescriptorHeap : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
public DescriptorIndex AllocateDescriptorDynamic() => AllocateDescriptorsDynamic(1);
|
||||
public int AllocateDescriptorDynamic() => AllocateDescriptorsDynamic(1);
|
||||
|
||||
public DescriptorIndex AllocateDescriptorsDynamic(int count)
|
||||
public int AllocateDescriptorsDynamic(int count)
|
||||
{
|
||||
if (count <= 0)
|
||||
{
|
||||
@@ -157,9 +159,9 @@ internal unsafe struct D3D12DescriptorHeap : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
public void ReleaseDescriptor(DescriptorIndex index) => ReleaseDescriptors(index, 1);
|
||||
public void ReleaseDescriptor(int index) => ReleaseDescriptors(index, 1);
|
||||
|
||||
public void ReleaseDescriptors(DescriptorIndex baseIndex, int count = 1)
|
||||
public void ReleaseDescriptors(int baseIndex, int count = 1)
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
@@ -203,7 +205,7 @@ internal unsafe struct D3D12DescriptorHeap : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
public readonly CpuDescriptorHandle GetCpuHandle(DescriptorIndex index)
|
||||
public readonly D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandle(int index)
|
||||
{
|
||||
if (index < 0 || index >= NumDescriptors)
|
||||
{
|
||||
@@ -213,7 +215,7 @@ internal unsafe struct D3D12DescriptorHeap : IDisposable
|
||||
return _startCpuHandle.Offset(index, Stride);
|
||||
}
|
||||
|
||||
public readonly CpuDescriptorHandle GetCpuHandleShaderVisible(DescriptorIndex index)
|
||||
public readonly D3D12_CPU_DESCRIPTOR_HANDLE GetCpuHandleShaderVisible(int index)
|
||||
{
|
||||
if (index < 0 || index >= NumDescriptors)
|
||||
{
|
||||
@@ -228,7 +230,7 @@ internal unsafe struct D3D12DescriptorHeap : IDisposable
|
||||
return _startCpuHandleShaderVisible.Offset(index, Stride);
|
||||
}
|
||||
|
||||
public readonly GpuDescriptorHandle GetGpuHandle(DescriptorIndex index)
|
||||
public readonly D3D12_GPU_DESCRIPTOR_HANDLE GetGpuHandle(int index)
|
||||
{
|
||||
if (index < 0 || index >= NumDescriptors)
|
||||
{
|
||||
@@ -243,7 +245,7 @@ internal unsafe struct D3D12DescriptorHeap : IDisposable
|
||||
return _startGpuHandleShaderVisible.Offset(index, Stride);
|
||||
}
|
||||
|
||||
public DescriptorIndex CopyToPersistentHeap(DescriptorIndex index, int count = 1)
|
||||
public int CopyToPersistentHeap(int index, int count = 1)
|
||||
{
|
||||
if (index < _dynamicHeapStart)
|
||||
{
|
||||
@@ -256,7 +258,7 @@ internal unsafe struct D3D12DescriptorHeap : IDisposable
|
||||
return newLocation;
|
||||
}
|
||||
|
||||
public readonly void CopyToShaderVisibleHeap(DescriptorIndex index, int count = 1)
|
||||
public readonly void CopyToShaderVisibleHeap(int index, int count = 1)
|
||||
{
|
||||
_device.NativeDevice->CopyDescriptorsSimple((uint)count, GetCpuHandleShaderVisible(index), GetCpuHandle(index), HeapType);
|
||||
}
|
||||
@@ -267,18 +269,18 @@ internal unsafe struct D3D12DescriptorHeap : IDisposable
|
||||
_heap.Dispose();
|
||||
_shaderVisibleHeap.Dispose();
|
||||
|
||||
DescriptorHeapDescription heapDesc = new()
|
||||
D3D12_DESCRIPTOR_HEAP_DESC heapDesc = new()
|
||||
{
|
||||
Type = HeapType,
|
||||
NumDescriptors = (uint)numDescriptors,
|
||||
Flags = DescriptorHeapFlags.None,
|
||||
Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE,
|
||||
NodeMask = 0
|
||||
};
|
||||
|
||||
fixed (void* heapPtr = &_heap)
|
||||
{
|
||||
var hr = _device.NativeDevice->CreateDescriptorHeap(&heapDesc, __uuidof<ID3D12DescriptorHeap>(), (void**)heapPtr);
|
||||
if (hr.Failure)
|
||||
if (hr.FAILED)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -289,12 +291,12 @@ internal unsafe struct D3D12DescriptorHeap : IDisposable
|
||||
|
||||
if (ShaderVisible)
|
||||
{
|
||||
heapDesc.Flags = DescriptorHeapFlags.ShaderVisible;
|
||||
heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
|
||||
|
||||
fixed (void* heapPtr = &_shaderVisibleHeap)
|
||||
{
|
||||
var hr = _device.NativeDevice->CreateDescriptorHeap(&heapDesc, __uuidof<ID3D12DescriptorHeap>(), (void**)heapPtr);
|
||||
if (hr.Failure)
|
||||
if (hr.FAILED)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Ghost.Graphics.Data;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Win32.Graphics.Direct3D12;
|
||||
using Win32.Graphics.Dxgi.Common;
|
||||
using TerraFX.Interop.DirectX;
|
||||
|
||||
namespace Ghost.Graphics.D3D12.Utilities;
|
||||
|
||||
@@ -9,19 +8,19 @@ internal unsafe static class D3D12PipelineResource
|
||||
{
|
||||
public const int BACK_BUFFER_COUNT = 2;
|
||||
|
||||
private readonly static InputElementDescription[] s_inputElementDescs = [
|
||||
new InputElementDescription{ SemanticName = Vertex.Semantic.position.GetUnsafePointer(), SemanticIndex = 0u, Format = Format.R32G32B32A32Float, InputSlot = 0u, AlignedByteOffset = 0u, InputSlotClass = InputClassification.PerVertexData, InstanceDataStepRate = 0 },
|
||||
new InputElementDescription{ SemanticName = Vertex.Semantic.normal.GetUnsafePointer(), SemanticIndex = 0u, Format = Format.R32G32B32A32Float, InputSlot = 0u, AlignedByteOffset = 16u, InputSlotClass = InputClassification.PerVertexData, InstanceDataStepRate = 0 },
|
||||
new InputElementDescription{ SemanticName = Vertex.Semantic.tangent.GetUnsafePointer(), SemanticIndex = 0u, Format = Format.R32G32B32A32Float, InputSlot = 0u, AlignedByteOffset = 32u, InputSlotClass = InputClassification.PerVertexData, InstanceDataStepRate = 0 },
|
||||
new InputElementDescription{ SemanticName = Vertex.Semantic.uv.GetUnsafePointer(), SemanticIndex = 0u, Format = Format.R32G32B32A32Float, InputSlot = 0u, AlignedByteOffset = 48u, InputSlotClass = InputClassification.PerVertexData, InstanceDataStepRate = 0 },
|
||||
new InputElementDescription{ SemanticName = Vertex.Semantic.color.GetUnsafePointer(), SemanticIndex = 0u, Format = Format.R32G32B32A32Float, InputSlot = 0u, AlignedByteOffset = 64u, InputSlotClass = InputClassification.PerVertexData, InstanceDataStepRate = 0 },
|
||||
private readonly static D3D12_INPUT_ELEMENT_DESC[] s_inputElementDescs = [
|
||||
new D3D12_INPUT_ELEMENT_DESC{ SemanticName = (sbyte*)Vertex.Semantic.position.GetUnsafePointer(), SemanticIndex = 0u, Format = Vertex.Semantic.ALIGNED_FORMAT, InputSlot = 0u, AlignedByteOffset = 0u, InputSlotClass = D3D12_INPUT_CLASSIFICATION.D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, InstanceDataStepRate = 0 },
|
||||
new D3D12_INPUT_ELEMENT_DESC{ SemanticName = (sbyte*)Vertex.Semantic.normal.GetUnsafePointer(), SemanticIndex = 0u, Format = Vertex.Semantic.ALIGNED_FORMAT, InputSlot = 0u, AlignedByteOffset = 16u, InputSlotClass = D3D12_INPUT_CLASSIFICATION.D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, InstanceDataStepRate = 0 },
|
||||
new D3D12_INPUT_ELEMENT_DESC{ SemanticName = (sbyte*)Vertex.Semantic.tangent.GetUnsafePointer(), SemanticIndex = 0u, Format = Vertex.Semantic.ALIGNED_FORMAT, InputSlot = 0u, AlignedByteOffset = 32u, InputSlotClass = D3D12_INPUT_CLASSIFICATION.D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, InstanceDataStepRate = 0 },
|
||||
new D3D12_INPUT_ELEMENT_DESC{ SemanticName = (sbyte*)Vertex.Semantic.uv.GetUnsafePointer(), SemanticIndex = 0u, Format = Vertex.Semantic.ALIGNED_FORMAT, InputSlot = 0u, AlignedByteOffset = 48u, InputSlotClass = D3D12_INPUT_CLASSIFICATION.D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, InstanceDataStepRate = 0 },
|
||||
new D3D12_INPUT_ELEMENT_DESC{ SemanticName = (sbyte*)Vertex.Semantic.color.GetUnsafePointer(), SemanticIndex = 0u, Format = Vertex.Semantic.ALIGNED_FORMAT, InputSlot = 0u, AlignedByteOffset = 64u, InputSlotClass = D3D12_INPUT_CLASSIFICATION.D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, InstanceDataStepRate = 0 },
|
||||
];
|
||||
|
||||
public const Format SWAP_CHAIN_BACK_BUFFER_FORMAT = Format.B8G8R8A8Unorm;
|
||||
public const DXGI_FORMAT SWAP_CHAIN_BACK_BUFFER_FORMAT = DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
|
||||
public static InputLayoutDescription InputLayoutDescription => new()
|
||||
public static D3D12_INPUT_LAYOUT_DESC InputLayoutDescription => new()
|
||||
{
|
||||
pInputElementDescs = (InputElementDescription*)Unsafe.AsPointer(ref s_inputElementDescs[0]),
|
||||
pInputElementDescs = (D3D12_INPUT_ELEMENT_DESC*)Unsafe.AsPointer(ref s_inputElementDescs[0]),
|
||||
NumElements = (uint)s_inputElementDescs.Length
|
||||
};
|
||||
}
|
||||
@@ -1,5 +1,163 @@
|
||||
namespace Ghost.Graphics.D3D12.Utilities;
|
||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
||||
using TerraFX.Interop.DirectX;
|
||||
|
||||
internal static class D3D12Utility
|
||||
using static TerraFX.Aliases.D3D12_Alias;
|
||||
|
||||
namespace Ghost.Graphics.D3D12.Utilities;
|
||||
|
||||
internal unsafe static class ID3D12Resource_Extensions
|
||||
{
|
||||
extension(ID3D12Resource resource)
|
||||
{
|
||||
public void SetName(ReadOnlySpan<char> name)
|
||||
{
|
||||
resource.SetName(name.GetUnsafePtr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static class D3D12_RASTERIZER_DESC_Extensions
|
||||
{
|
||||
extension(D3D12_RASTERIZER_DESC)
|
||||
{
|
||||
public static D3D12_RASTERIZER_DESC CULL_NONE => Create(D3D12_FILL_MODE_SOLID, D3D12_CULL_MODE_NONE);
|
||||
public static D3D12_RASTERIZER_DESC CULL_CLOCKWISE => Create(D3D12_FILL_MODE_SOLID, D3D12_CULL_MODE_FRONT);
|
||||
public static D3D12_RASTERIZER_DESC CULL_COUNTER_CLOCKWISE => Create(D3D12_FILL_MODE_SOLID, D3D12_CULL_MODE_BACK);
|
||||
public static D3D12_RASTERIZER_DESC WIREFRAME => Create(D3D12_FILL_MODE_WIREFRAME, D3D12_CULL_MODE_NONE);
|
||||
|
||||
public static D3D12_RASTERIZER_DESC Create(
|
||||
D3D12_FILL_MODE fillMode,
|
||||
D3D12_CULL_MODE cullMode,
|
||||
bool frontCounterClockwise = false,
|
||||
int depthBias = D3D12_DEFAULT_DEPTH_BIAS,
|
||||
float depthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP,
|
||||
float slopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS,
|
||||
bool depthClipEnable = true,
|
||||
bool multisampleEnable = true,
|
||||
bool antialiasedLineEnable = false,
|
||||
uint forcedSampleCount = 0,
|
||||
D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF)
|
||||
{
|
||||
return new D3D12_RASTERIZER_DESC
|
||||
{
|
||||
FillMode = fillMode,
|
||||
CullMode = cullMode,
|
||||
FrontCounterClockwise = frontCounterClockwise ? TRUE : FALSE,
|
||||
DepthBias = depthBias,
|
||||
DepthBiasClamp = depthBiasClamp,
|
||||
SlopeScaledDepthBias = slopeScaledDepthBias,
|
||||
DepthClipEnable = depthClipEnable ? TRUE : FALSE,
|
||||
MultisampleEnable = multisampleEnable ? TRUE : FALSE,
|
||||
AntialiasedLineEnable = antialiasedLineEnable ? TRUE : FALSE,
|
||||
ForcedSampleCount = forcedSampleCount,
|
||||
ConservativeRaster = conservativeRaster
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static class D3D12_BLEND_DESC_Extensions
|
||||
{
|
||||
extension(D3D12_BLEND_DESC)
|
||||
{
|
||||
public static D3D12_BLEND_DESC OPAQUE => Create(D3D12_BLEND_ONE, D3D12_BLEND_ZERO);
|
||||
public static D3D12_BLEND_DESC ALPHA_BLEND => Create(D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA);
|
||||
public static D3D12_BLEND_DESC ADDITIVE => Create(D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_ONE);
|
||||
public static D3D12_BLEND_DESC NON_PREMULTIPLIED => Create(D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA);
|
||||
|
||||
public static D3D12_BLEND_DESC Create(D3D12_BLEND srcBlend, D3D12_BLEND destBlend)
|
||||
{
|
||||
var blendDesc = new D3D12_BLEND_DESC
|
||||
{
|
||||
AlphaToCoverageEnable = false,
|
||||
IndependentBlendEnable = false
|
||||
};
|
||||
|
||||
for (var i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
|
||||
{
|
||||
blendDesc.RenderTarget[i].BlendEnable = srcBlend != D3D12_BLEND_ONE || destBlend != D3D12_BLEND_ZERO;
|
||||
blendDesc.RenderTarget[i].LogicOp = D3D12_LOGIC_OP_NOOP;
|
||||
blendDesc.RenderTarget[i].SrcBlend = srcBlend;
|
||||
blendDesc.RenderTarget[i].DestBlend = destBlend;
|
||||
blendDesc.RenderTarget[i].BlendOp = D3D12_BLEND_OP_ADD;
|
||||
blendDesc.RenderTarget[i].SrcBlendAlpha = srcBlend;
|
||||
blendDesc.RenderTarget[i].DestBlendAlpha = destBlend;
|
||||
blendDesc.RenderTarget[i].BlendOpAlpha = D3D12_BLEND_OP_ADD;
|
||||
blendDesc.RenderTarget[i].RenderTargetWriteMask = (byte)D3D12_COLOR_WRITE_ENABLE_ALL;
|
||||
}
|
||||
|
||||
return blendDesc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static class D3D12_DEPTH_STENCIL_DESC_Extensions
|
||||
{
|
||||
extension(D3D12_DEPTH_STENCIL_DESC)
|
||||
{
|
||||
public static D3D12_DEPTH_STENCIL_DESC NONE => Create(false, false, D3D12_COMPARISON_FUNC_LESS_EQUAL);
|
||||
public static D3D12_DEPTH_STENCIL_DESC READ => Create(true, false, D3D12_COMPARISON_FUNC_LESS_EQUAL);
|
||||
public static D3D12_DEPTH_STENCIL_DESC REVERSE_Z => Create(true, true, D3D12_COMPARISON_FUNC_GREATER_EQUAL);
|
||||
public static D3D12_DEPTH_STENCIL_DESC READ_REVERSE_Z => Create(true, false, D3D12_COMPARISON_FUNC_GREATER_EQUAL);
|
||||
|
||||
public static D3D12_DEPTH_STENCIL_DESC Create(bool depthEnable,
|
||||
bool depthWriteEnable,
|
||||
D3D12_COMPARISON_FUNC depthFunc,
|
||||
bool stencilEnable = false,
|
||||
byte stencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK,
|
||||
byte stencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK,
|
||||
D3D12_STENCIL_OP frontStencilFailOp = D3D12_STENCIL_OP_KEEP,
|
||||
D3D12_STENCIL_OP frontStencilDepthFailOp = D3D12_STENCIL_OP_KEEP,
|
||||
D3D12_STENCIL_OP frontStencilPassOp = D3D12_STENCIL_OP_KEEP,
|
||||
D3D12_COMPARISON_FUNC frontStencilFunc = D3D12_COMPARISON_FUNC_ALWAYS,
|
||||
D3D12_STENCIL_OP backStencilFailOp = D3D12_STENCIL_OP_KEEP,
|
||||
D3D12_STENCIL_OP backStencilDepthFailOp = D3D12_STENCIL_OP_KEEP,
|
||||
D3D12_STENCIL_OP backStencilPassOp = D3D12_STENCIL_OP_KEEP,
|
||||
D3D12_COMPARISON_FUNC backStencilFunc = D3D12_COMPARISON_FUNC_ALWAYS)
|
||||
{
|
||||
return new D3D12_DEPTH_STENCIL_DESC
|
||||
{
|
||||
DepthEnable = depthEnable,
|
||||
DepthWriteMask = depthWriteEnable ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO,
|
||||
DepthFunc = depthFunc,
|
||||
StencilEnable = stencilEnable,
|
||||
StencilReadMask = stencilReadMask,
|
||||
StencilWriteMask = stencilWriteMask,
|
||||
FrontFace = D3D12_DEPTH_STENCILOP_DESC.Create(frontStencilFailOp, frontStencilDepthFailOp, frontStencilPassOp, frontStencilFunc),
|
||||
BackFace = D3D12_DEPTH_STENCILOP_DESC.Create(backStencilFailOp, backStencilDepthFailOp, backStencilPassOp, backStencilFunc)
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
internal static class D3D12_DEPTH_STENCILOP_DESC_Extensions
|
||||
{
|
||||
extension(D3D12_DEPTH_STENCILOP_DESC)
|
||||
{
|
||||
public static D3D12_DEPTH_STENCILOP_DESC DEFAULT => Create(D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS);
|
||||
|
||||
public static D3D12_DEPTH_STENCILOP_DESC Create(D3D12_STENCIL_OP stencilFailOp, D3D12_STENCIL_OP stencilDepthFailOp, D3D12_STENCIL_OP stencilPassOp, D3D12_COMPARISON_FUNC stencilFunc)
|
||||
{
|
||||
return new D3D12_DEPTH_STENCILOP_DESC
|
||||
{
|
||||
StencilFailOp = stencilFailOp,
|
||||
StencilDepthFailOp = stencilDepthFailOp,
|
||||
StencilPassOp = stencilPassOp,
|
||||
StencilFunc = stencilFunc
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal unsafe static class D3D12MA_Allocation_Extensions
|
||||
{
|
||||
extension(ref readonly D3D12MA_Allocation allocation)
|
||||
{
|
||||
public bool IsNull => allocation.GetResource() == null
|
||||
&& allocation.GetHeap() == null
|
||||
&& allocation.GetSize() == 0;
|
||||
|
||||
public bool IsNotNull => !allocation.IsNull;
|
||||
}
|
||||
}
|
||||
13335
Ghost.Graphics/D3D12/Utilities/EnumAliases.cs
Normal file
13335
Ghost.Graphics/D3D12/Utilities/EnumAliases.cs
Normal file
File diff suppressed because it is too large
Load Diff
41
Ghost.Graphics/D3D12/Utilities/Win32Utility.cs
Normal file
41
Ghost.Graphics/D3D12/Utilities/Win32Utility.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using TerraFX.Interop.Windows;
|
||||
|
||||
namespace Ghost.Graphics.D3D12.Utilities;
|
||||
|
||||
internal unsafe static class Win32Utility
|
||||
{
|
||||
public static void ThrowIfFailed(this HRESULT hr)
|
||||
{
|
||||
if (hr.FAILED)
|
||||
{
|
||||
throw new InvalidOperationException($"Operation failed with HRESULT: 0x{hr.Value:X8}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void** GetVoidAddressOf<T>(this ComPtr<T> comPtr)
|
||||
where T : unmanaged, IUnknown.Interface
|
||||
{
|
||||
return (void**)comPtr.GetAddressOf();
|
||||
}
|
||||
|
||||
public static void** ReleaseAndGetVoidAddressOf<T>(this ComPtr<T> comPtr)
|
||||
where T : unmanaged, IUnknown.Interface
|
||||
{
|
||||
return (void**)comPtr.ReleaseAndGetAddressOf();
|
||||
}
|
||||
|
||||
public static ComPtr<T> Move<T>(this ComPtr<T> comPtr)
|
||||
where T : unmanaged, IUnknown.Interface
|
||||
{
|
||||
ComPtr<T> copy = default;
|
||||
Unsafe.AsRef(in comPtr).Swap(ref copy);
|
||||
return copy;
|
||||
}
|
||||
|
||||
public static bool HasFlag<T>(this uint flags, T flag)
|
||||
where T : Enum
|
||||
{
|
||||
return (flags & Unsafe.As<T, uint>(ref flag)) != 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user