Fixed bugs in rendering.
This commit is contained in:
@@ -6,12 +6,7 @@ using TerraFX.Interop.Windows;
|
|||||||
|
|
||||||
namespace Ghost.Core.Utilities;
|
namespace Ghost.Core.Utilities;
|
||||||
|
|
||||||
internal static partial class Win32Utility
|
[SupportedOSPlatform("windows10.0.19041.0")]
|
||||||
{
|
|
||||||
public const string OS_SUPPORTED_VERSION = "windows10.0.19041.0";
|
|
||||||
}
|
|
||||||
|
|
||||||
[SupportedOSPlatform(OS_SUPPORTED_VERSION)]
|
|
||||||
internal static unsafe partial class Win32Utility
|
internal static unsafe partial class Win32Utility
|
||||||
{
|
{
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace Ghost.Entities.Query;
|
|||||||
|
|
||||||
public struct QueryFilter : IDisposable
|
public struct QueryFilter : IDisposable
|
||||||
{
|
{
|
||||||
private readonly Stack.Scope _scope;
|
//private readonly Stack.Scope _scope;
|
||||||
|
|
||||||
internal UnsafeList<TypeHandle> _all;
|
internal UnsafeList<TypeHandle> _all;
|
||||||
internal UnsafeList<TypeHandle> _any;
|
internal UnsafeList<TypeHandle> _any;
|
||||||
@@ -15,7 +15,7 @@ public struct QueryFilter : IDisposable
|
|||||||
|
|
||||||
public QueryFilter()
|
public QueryFilter()
|
||||||
{
|
{
|
||||||
_scope = AllocationManager.CreateStackScope();
|
//_scope = AllocationManager.CreateStackScope();
|
||||||
|
|
||||||
_all = new UnsafeList<TypeHandle>(4, Allocator.Stack);
|
_all = new UnsafeList<TypeHandle>(4, Allocator.Stack);
|
||||||
_any = new UnsafeList<TypeHandle>(4, Allocator.Stack);
|
_any = new UnsafeList<TypeHandle>(4, Allocator.Stack);
|
||||||
@@ -92,6 +92,6 @@ public struct QueryFilter : IDisposable
|
|||||||
|
|
||||||
public readonly void Dispose()
|
public readonly void Dispose()
|
||||||
{
|
{
|
||||||
_scope.Dispose();
|
//_scope.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ using Ghost.Graphics.Test.Windows;
|
|||||||
|
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer;
|
using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
// To learn more about WinUI, the WinUI project structure,
|
// To learn more about WinUI, the WinUI project structure,
|
||||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||||
@@ -23,12 +24,31 @@ public partial class UnitTestApp : Application
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void LoadDll()
|
||||||
|
{
|
||||||
|
var currentDir = AppContext.BaseDirectory;
|
||||||
|
var platform = OperatingSystem.IsWindows() ? "win" :
|
||||||
|
OperatingSystem.IsLinux() ? "linux" :
|
||||||
|
OperatingSystem.IsMacOS() ? "osx" : "unknown";
|
||||||
|
var arch = Environment.Is64BitProcess ? "x64" : "x86";
|
||||||
|
var nativeDllDir = Path.Combine(currentDir, "runtime", platform + "-" + arch, "native");
|
||||||
|
if (Directory.Exists(nativeDllDir))
|
||||||
|
{
|
||||||
|
foreach (var dll in Directory.EnumerateFiles(nativeDllDir, "*.dll"))
|
||||||
|
{
|
||||||
|
NativeLibrary.Load(dll);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when the application is launched.
|
/// Invoked when the application is launched.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="args">Details about the launch request and process.</param>
|
/// <param name="args">Details about the launch request and process.</param>
|
||||||
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
protected override void OnLaunched(LaunchActivatedEventArgs args)
|
||||||
{
|
{
|
||||||
|
LoadDll();
|
||||||
|
|
||||||
Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.CreateDefaultUI();
|
Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.CreateDefaultUI();
|
||||||
|
|
||||||
_window = new GraphicsTestWindow();
|
_window = new GraphicsTestWindow();
|
||||||
|
|||||||
@@ -4,11 +4,15 @@ global using static TerraFX.Interop.DirectX.DXGI;
|
|||||||
global using static TerraFX.Interop.Windows.Windows;
|
global using static TerraFX.Interop.Windows.Windows;
|
||||||
|
|
||||||
using Ghost.Core.Attributes;
|
using Ghost.Core.Attributes;
|
||||||
|
using Ghost.Core.Utilities;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
[assembly: InternalsVisibleTo("Ghost.Engine")]
|
[assembly: InternalsVisibleTo("Ghost.Engine")]
|
||||||
[assembly: InternalsVisibleTo("Ghost.Editor")]
|
[assembly: InternalsVisibleTo("Ghost.Editor")]
|
||||||
[assembly: InternalsVisibleTo("Ghost.Editor.Core")]
|
[assembly: InternalsVisibleTo("Ghost.Editor.Core")]
|
||||||
[assembly: InternalsVisibleTo("Ghost.Graphics.Test")]
|
[assembly: InternalsVisibleTo("Ghost.Graphics.Test")]
|
||||||
|
[assembly: SupportedOSPlatform("windows10.0.19041.0")]
|
||||||
|
|
||||||
|
|
||||||
[assembly: EngineAssembly]
|
[assembly: EngineAssembly]
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
using Ghost.Core;
|
using Ghost.Core;
|
||||||
using Ghost.Core.Graphics;
|
using Ghost.Core.Graphics;
|
||||||
using Ghost.Core.Utilities;
|
|
||||||
using Ghost.Graphics.Core;
|
using Ghost.Graphics.Core;
|
||||||
using Ghost.Graphics.D3D12.Utilities;
|
using Ghost.Graphics.D3D12.Utilities;
|
||||||
using Ghost.Graphics.RHI;
|
using Ghost.Graphics.RHI;
|
||||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
using Misaki.HighPerformance.LowLevel.Utilities;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.Versioning;
|
|
||||||
using TerraFX.Interop.DirectX;
|
using TerraFX.Interop.DirectX;
|
||||||
using TerraFX.Interop.Windows;
|
using TerraFX.Interop.Windows;
|
||||||
using static TerraFX.Aliases.D3D_Alias;
|
using static TerraFX.Aliases.D3D_Alias;
|
||||||
@@ -15,7 +13,6 @@ using static TerraFX.Aliases.DXGI_Alias;
|
|||||||
|
|
||||||
namespace Ghost.Graphics.D3D12;
|
namespace Ghost.Graphics.D3D12;
|
||||||
|
|
||||||
[SupportedOSPlatform(Win32Utility.OS_SUPPORTED_VERSION)]
|
|
||||||
internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||||
{
|
{
|
||||||
private ComPtr<ID3D12CommandAllocator> _allocator;
|
private ComPtr<ID3D12CommandAllocator> _allocator;
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ internal unsafe class D3D12GraphicsEngine : IGraphicsEngine
|
|||||||
CommandBufferType.Copy);
|
CommandBufferType.Copy);
|
||||||
|
|
||||||
_renderers = ImmutableArray<IRenderer>.Empty;
|
_renderers = ImmutableArray<IRenderer>.Empty;
|
||||||
|
|
||||||
|
_pipelineLibrary.InitializeLibrary(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
~D3D12GraphicsEngine()
|
~D3D12GraphicsEngine()
|
||||||
@@ -59,10 +61,7 @@ internal unsafe class D3D12GraphicsEngine : IGraphicsEngine
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void ThrowIfDisposed()
|
private void ThrowIfDisposed()
|
||||||
{
|
{
|
||||||
if (_disposed)
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
{
|
|
||||||
throw new ObjectDisposedException(nameof(D3D12GraphicsEngine));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IRenderer CreateRenderer()
|
public IRenderer CreateRenderer()
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ using Misaki.HighPerformance.LowLevel.Utilities;
|
|||||||
using Misaki.HighPerformance.Utilities;
|
using Misaki.HighPerformance.Utilities;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
|
||||||
using TerraFX.Interop.DirectX;
|
using TerraFX.Interop.DirectX;
|
||||||
using TerraFX.Interop.Windows;
|
using TerraFX.Interop.Windows;
|
||||||
|
|
||||||
@@ -32,7 +31,6 @@ internal struct D3D12GraphicsCompiledResult : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SupportedOSPlatform(Win32Utility.OS_SUPPORTED_VERSION)]
|
|
||||||
internal struct D3D12PipelineState : IDisposable
|
internal struct D3D12PipelineState : IDisposable
|
||||||
{
|
{
|
||||||
// NOTE: This is just a temporary cache for compiled shader code. We will implement a proper disk cache later.
|
// NOTE: This is just a temporary cache for compiled shader code. We will implement a proper disk cache later.
|
||||||
@@ -47,10 +45,9 @@ internal struct D3D12PipelineState : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SupportedOSPlatform(Win32Utility.OS_SUPPORTED_VERSION)]
|
|
||||||
internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
||||||
{
|
{
|
||||||
private const int _ROOT_PARAM_COUNT =
|
private const int rootParamCount =
|
||||||
#if USE_TRADITIONAL_BINDLESS
|
#if USE_TRADITIONAL_BINDLESS
|
||||||
6
|
6
|
||||||
#else
|
#else
|
||||||
@@ -83,7 +80,7 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
|||||||
_defaultRootSignature = default;
|
_defaultRootSignature = default;
|
||||||
|
|
||||||
// NOTE: Since we are targeting SM 6.6, we can use ResourceDescriptorHeap and SamplerDescriptorHeap directly without needing to set up viewGroup tables.
|
// NOTE: Since we are targeting SM 6.6, we can use ResourceDescriptorHeap and SamplerDescriptorHeap directly without needing to set up viewGroup tables.
|
||||||
var rootParameters = stackalloc D3D12_ROOT_PARAMETER1[_ROOT_PARAM_COUNT];
|
var rootParameters = stackalloc D3D12_ROOT_PARAMETER1[rootParamCount];
|
||||||
rootParameters[0] = new D3D12_ROOT_PARAMETER1
|
rootParameters[0] = new D3D12_ROOT_PARAMETER1
|
||||||
{
|
{
|
||||||
ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV,
|
ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV,
|
||||||
@@ -146,7 +143,7 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
|||||||
|
|
||||||
var rootSignatureDesc = new D3D12_ROOT_SIGNATURE_DESC1
|
var rootSignatureDesc = new D3D12_ROOT_SIGNATURE_DESC1
|
||||||
{
|
{
|
||||||
NumParameters = _ROOT_PARAM_COUNT,
|
NumParameters = rootParamCount,
|
||||||
pParameters = rootParameters,
|
pParameters = rootParameters,
|
||||||
NumStaticSamplers = 0,
|
NumStaticSamplers = 0,
|
||||||
pStaticSamplers = null,
|
pStaticSamplers = null,
|
||||||
@@ -180,7 +177,7 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
|||||||
_defaultRootSignature.Attach(pRootSignature);
|
_defaultRootSignature.Attach(pRootSignature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadLibraryFromDisk(string? filePath)
|
public void InitializeLibrary(string? filePath)
|
||||||
{
|
{
|
||||||
ID3D12PipelineLibrary1* pLibrary = default;
|
ID3D12PipelineLibrary1* pLibrary = default;
|
||||||
|
|
||||||
@@ -219,9 +216,9 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
|||||||
|
|
||||||
private static void ValidateReflectionData(ShaderReflectionData reflectionData)
|
private static void ValidateReflectionData(ShaderReflectionData reflectionData)
|
||||||
{
|
{
|
||||||
if (reflectionData.ConstantBuffers.Count != _ROOT_PARAM_COUNT)
|
if (reflectionData.ConstantBuffers.Count != rootParamCount)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Shader reflection data has {reflectionData.ConstantBuffers.Count} constant buffers, expected {_ROOT_PARAM_COUNT}");
|
throw new InvalidOperationException($"Shader reflection data has {reflectionData.ConstantBuffers.Count} constant buffers, expected {rootParamCount}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reflectionData.OtherResources.Count != 0)
|
if (reflectionData.OtherResources.Count != 0)
|
||||||
@@ -240,13 +237,16 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// TODO: This does not include generated code. This will cause a root signature mismatch.
|
||||||
var result = D3D12ShaderCompiler.Compile(ref config, Allocator.Persistent, &reflectionBlob).GetValueOrThrow();
|
var result = D3D12ShaderCompiler.Compile(ref config, Allocator.Persistent, &reflectionBlob).GetValueOrThrow();
|
||||||
|
|
||||||
|
#if false
|
||||||
if (reflectionBlob != null)
|
if (reflectionBlob != null)
|
||||||
{
|
{
|
||||||
var reflection = D3D12ShaderCompiler.PerformDXCReflection(reflectionBlob).GetValueOrThrow();
|
var reflection = D3D12ShaderCompiler.PerformDXCReflection(reflectionBlob).GetValueOrThrow();
|
||||||
ValidateReflectionData(reflection);
|
ValidateReflectionData(reflection);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -415,15 +415,16 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
|||||||
existing.compileResult = compiled;
|
existing.compileResult = compiled;
|
||||||
existing.psoDesc = desc;
|
existing.psoDesc = desc;
|
||||||
|
|
||||||
|
var meshStream = new CD3DX12_PIPELINE_MESH_STATE_STREAM(in desc);
|
||||||
var streamDesc = new D3D12_PIPELINE_STATE_STREAM_DESC
|
var streamDesc = new D3D12_PIPELINE_STATE_STREAM_DESC
|
||||||
{
|
{
|
||||||
pPipelineStateSubobjectStream = &desc,
|
pPipelineStateSubobjectStream = &meshStream,
|
||||||
SizeInBytes = (nuint)sizeof(D3DX12_MESH_SHADER_PIPELINE_STATE_DESC)
|
SizeInBytes = (nuint)sizeof(CD3DX12_PIPELINE_MESH_STATE_STREAM)
|
||||||
};
|
};
|
||||||
|
|
||||||
ID3D12PipelineState* pPipelineState = default;
|
ID3D12PipelineState* pPipelineState = default;
|
||||||
|
|
||||||
char* pKeyStr = stackalloc char[GraphicsPipelineKey.KEY_STRING_LENGTH];
|
var pKeyStr = stackalloc char[GraphicsPipelineKey.KEY_STRING_LENGTH];
|
||||||
var keySpan = new Span<char>(pKeyStr, GraphicsPipelineKey.KEY_STRING_LENGTH);
|
var keySpan = new Span<char>(pKeyStr, GraphicsPipelineKey.KEY_STRING_LENGTH);
|
||||||
key.GetString(keySpan).ThrowIfFailed();
|
key.GetString(keySpan).ThrowIfFailed();
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ namespace Ghost.Graphics.D3D12;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// D3D12 implementation of the render device interface
|
/// D3D12 implementation of the render device interface
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SupportedOSPlatform(Win32Utility.OS_SUPPORTED_VERSION)]
|
|
||||||
internal unsafe class D3D12RenderDevice : IRenderDevice
|
internal unsafe class D3D12RenderDevice : IRenderDevice
|
||||||
{
|
{
|
||||||
private ComPtr<IDXGIFactory7> _dxgiFactory;
|
private ComPtr<IDXGIFactory7> _dxgiFactory;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using Ghost.Graphics.RHI;
|
|||||||
using Misaki.HighPerformance.LowLevel.Collections;
|
using Misaki.HighPerformance.LowLevel.Collections;
|
||||||
using Misaki.HighPerformance.Mathematics;
|
using Misaki.HighPerformance.Mathematics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.Versioning;
|
|
||||||
using TerraFX.Interop.DirectX;
|
using TerraFX.Interop.DirectX;
|
||||||
using TerraFX.Interop.Windows;
|
using TerraFX.Interop.Windows;
|
||||||
using static TerraFX.Aliases.D3D12_Alias;
|
using static TerraFX.Aliases.D3D12_Alias;
|
||||||
@@ -16,8 +15,7 @@ using static TerraFX.Interop.DirectX.D3D12MemAlloc;
|
|||||||
|
|
||||||
namespace Ghost.Graphics.D3D12;
|
namespace Ghost.Graphics.D3D12;
|
||||||
|
|
||||||
[SupportedOSPlatform(Win32Utility.OS_SUPPORTED_VERSION)]
|
internal sealed unsafe partial class D3D12ResourceAllocator
|
||||||
internal unsafe sealed partial class D3D12ResourceAllocator
|
|
||||||
{
|
{
|
||||||
// NOTE: _MAX_BYTES may not be accurate, we need to verify it with feature level checks.
|
// NOTE: _MAX_BYTES may not be accurate, we need to verify it with feature level checks.
|
||||||
private const uint _MAX_BYTES = D3D12_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_A_TERM * 1024u * 1024u;
|
private const uint _MAX_BYTES = D3D12_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_A_TERM * 1024u * 1024u;
|
||||||
@@ -593,7 +591,7 @@ internal unsafe sealed partial class D3D12ResourceAllocator
|
|||||||
// TODO: Thread safety for resource allocator
|
// TODO: Thread safety for resource allocator
|
||||||
// A common solution is to use ticket. Each allocation request create a ticket and put it into a thread-safe queue. A dedicated thread process the queue and fulfill the requests.
|
// A common solution is to use ticket. Each allocation request create a ticket and put it into a thread-safe queue. A dedicated thread process the queue and fulfill the requests.
|
||||||
|
|
||||||
internal unsafe sealed partial class D3D12ResourceAllocator : IResourceAllocator, IDisposable
|
internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator, IDisposable
|
||||||
{
|
{
|
||||||
private readonly IFenceSynchronizer _fenceSynchronizer;
|
private readonly IFenceSynchronizer _fenceSynchronizer;
|
||||||
private readonly D3D12RenderDevice _device;
|
private readonly D3D12RenderDevice _device;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Ghost.Core;
|
using Ghost.Core;
|
||||||
using Ghost.Core.Utilities;
|
|
||||||
using Ghost.Graphics.Core;
|
using Ghost.Graphics.Core;
|
||||||
using Ghost.Graphics.RHI;
|
using Ghost.Graphics.RHI;
|
||||||
using Misaki.HighPerformance.Collections;
|
using Misaki.HighPerformance.Collections;
|
||||||
@@ -7,13 +6,11 @@ using Misaki.HighPerformance.LowLevel.Buffer;
|
|||||||
using Misaki.HighPerformance.LowLevel.Collections;
|
using Misaki.HighPerformance.LowLevel.Collections;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
|
||||||
using TerraFX.Interop.DirectX;
|
using TerraFX.Interop.DirectX;
|
||||||
using TerraFX.Interop.Windows;
|
using TerraFX.Interop.Windows;
|
||||||
|
|
||||||
namespace Ghost.Graphics.D3D12;
|
namespace Ghost.Graphics.D3D12;
|
||||||
|
|
||||||
[SupportedOSPlatform(Win32Utility.OS_SUPPORTED_VERSION)]
|
|
||||||
internal class D3D12ResourceDatabase : IResourceDatabase, IDisposable
|
internal class D3D12ResourceDatabase : IResourceDatabase, IDisposable
|
||||||
{
|
{
|
||||||
internal unsafe struct ResourceRecord
|
internal unsafe struct ResourceRecord
|
||||||
@@ -100,8 +97,8 @@ internal class D3D12ResourceDatabase : IResourceDatabase, IDisposable
|
|||||||
private readonly Dictionary<Handle<GPUResource>, string> _resourceName;
|
private readonly Dictionary<Handle<GPUResource>, string> _resourceName;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private readonly UnsafeSlotMap<Mesh> _meshes;
|
private UnsafeSlotMap<Mesh> _meshes;
|
||||||
private readonly UnsafeSlotMap<Material> _materials;
|
private UnsafeSlotMap<Material> _materials;
|
||||||
private readonly DynamicArray<Shader?> _shaders; // NOTE: We use a simple list since shader is not frequently added/removed. This can save 4 bytes for each ecs component.
|
private readonly DynamicArray<Shader?> _shaders; // NOTE: We use a simple list since shader is not frequently added/removed. This can save 4 bytes for each ecs component.
|
||||||
private readonly Dictionary<ShaderPassKey, ShaderPass> _shaderPasses; // NOTE: The reason we use Dictionary here is that ShaderPassKey is a presistence identifier across multiple application sessions.
|
private readonly Dictionary<ShaderPassKey, ShaderPass> _shaderPasses; // NOTE: The reason we use Dictionary here is that ShaderPassKey is a presistence identifier across multiple application sessions.
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Ghost.Core.Utilities;
|
|||||||
using Ghost.Graphics.RHI;
|
using Ghost.Graphics.RHI;
|
||||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
using Misaki.HighPerformance.LowLevel.Collections;
|
using Misaki.HighPerformance.LowLevel.Collections;
|
||||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
using TerraFX.Interop.DirectX;
|
using TerraFX.Interop.DirectX;
|
||||||
@@ -11,7 +10,7 @@ using TerraFX.Interop.Windows;
|
|||||||
|
|
||||||
namespace Ghost.Graphics.D3D12;
|
namespace Ghost.Graphics.D3D12;
|
||||||
|
|
||||||
internal unsafe struct CompileResult : IDisposable
|
internal struct CompileResult : IDisposable
|
||||||
{
|
{
|
||||||
public UnsafeArray<byte> bytecode;
|
public UnsafeArray<byte> bytecode;
|
||||||
|
|
||||||
@@ -120,7 +119,6 @@ internal readonly struct ShaderReflectionData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SupportedOSPlatform(Win32Utility.OS_SUPPORTED_VERSION)]
|
|
||||||
internal static unsafe class D3D12ShaderCompiler
|
internal static unsafe class D3D12ShaderCompiler
|
||||||
{
|
{
|
||||||
private static string GetProfileString(ShaderStage stage, CompilerTier version)
|
private static string GetProfileString(ShaderStage stage, CompilerTier version)
|
||||||
@@ -209,8 +207,8 @@ internal static unsafe class D3D12ShaderCompiler
|
|||||||
var dxccID = CLSID.CLSID_DxcCompiler;
|
var dxccID = CLSID.CLSID_DxcCompiler;
|
||||||
var dxcuID = CLSID.CLSID_DxcUtils;
|
var dxcuID = CLSID.CLSID_DxcUtils;
|
||||||
|
|
||||||
ThrowIfFailed(DxcCreateInstance(&dxccID, pCompiler->IID(), (void**)&pCompiler));
|
ThrowIfFailed(DxcCreateInstance(&dxccID, __uuidof(pCompiler), (void**)&pCompiler));
|
||||||
ThrowIfFailed(DxcCreateInstance(&dxcuID, pUtils->IID(), (void**)&pUtils));
|
ThrowIfFailed(DxcCreateInstance(&dxcuID, __uuidof(pUtils), (void**)&pUtils));
|
||||||
|
|
||||||
//pIncludeHandler.Get()->LoadSource();
|
//pIncludeHandler.Get()->LoadSource();
|
||||||
pUtils->CreateDefaultIncludeHandler(&pIncludeHandler);
|
pUtils->CreateDefaultIncludeHandler(&pIncludeHandler);
|
||||||
@@ -218,7 +216,7 @@ internal static unsafe class D3D12ShaderCompiler
|
|||||||
// Create source blob
|
// Create source blob
|
||||||
using ComPtr<IDxcBlobEncoding> sourceBlob = default;
|
using ComPtr<IDxcBlobEncoding> sourceBlob = default;
|
||||||
fixed (char* pPath = config.shaderPath)
|
fixed (char* pPath = config.shaderPath)
|
||||||
{
|
{
|
||||||
if (pUtils->LoadFile(pPath, null, sourceBlob.GetAddressOf()).FAILED)
|
if (pUtils->LoadFile(pPath, null, sourceBlob.GetAddressOf()).FAILED)
|
||||||
{
|
{
|
||||||
return Result.Fail($"Failed to load shader file: {config.shaderPath}");
|
return Result.Fail($"Failed to load shader file: {config.shaderPath}");
|
||||||
@@ -244,7 +242,7 @@ internal static unsafe class D3D12ShaderCompiler
|
|||||||
Encoding = DXC.DXC_CP_UTF8
|
Encoding = DXC.DXC_CP_UTF8
|
||||||
};
|
};
|
||||||
|
|
||||||
ThrowIfFailed(pCompiler->Compile(&buffer, argPtrs, (uint)argsArray.Count, pIncludeHandler, pResult->IID(), (void**)&pResult));
|
ThrowIfFailed(pCompiler->Compile(&buffer, argPtrs, (uint)argsArray.Count, pIncludeHandler, __uuidof(pResult), (void**)&pResult));
|
||||||
|
|
||||||
// Check compilation pResult
|
// Check compilation pResult
|
||||||
HRESULT hrStatus;
|
HRESULT hrStatus;
|
||||||
@@ -257,7 +255,7 @@ internal static unsafe class D3D12ShaderCompiler
|
|||||||
|
|
||||||
if (errorBlob.Get() != null)
|
if (errorBlob.Get() != null)
|
||||||
{
|
{
|
||||||
var errorMessage = Marshal.PtrToStringUni((IntPtr)errorBlob.Get()->GetBufferPointer());
|
var errorMessage = Marshal.PtrToStringUTF8((IntPtr)errorBlob.Get()->GetBufferPointer());
|
||||||
return Result.Fail($"DXC shader compilation failed:\n{errorMessage}");
|
return Result.Fail($"DXC shader compilation failed:\n{errorMessage}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using Ghost.Graphics.RHI;
|
|||||||
using TerraFX.Interop.DirectX;
|
using TerraFX.Interop.DirectX;
|
||||||
|
|
||||||
using static TerraFX.Aliases.D3D12_Alias;
|
using static TerraFX.Aliases.D3D12_Alias;
|
||||||
|
using static TerraFX.Aliases.DXGI_Alias;
|
||||||
|
|
||||||
namespace Ghost.Graphics.D3D12.Utilities;
|
namespace Ghost.Graphics.D3D12.Utilities;
|
||||||
|
|
||||||
@@ -31,12 +32,13 @@ internal unsafe static class D3D12Utility
|
|||||||
{
|
{
|
||||||
return format switch
|
return format switch
|
||||||
{
|
{
|
||||||
TextureFormat.R8G8B8A8_UNorm => DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM,
|
TextureFormat.Unknown => DXGI_FORMAT_UNKNOWN,
|
||||||
TextureFormat.B8G8R8A8_UNorm => DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM,
|
TextureFormat.R8G8B8A8_UNorm => DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||||
TextureFormat.R16G16B16A16_Float => DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_FLOAT,
|
TextureFormat.B8G8R8A8_UNorm => DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||||
TextureFormat.R32G32B32A32_Float => DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_FLOAT,
|
TextureFormat.R16G16B16A16_Float => DXGI_FORMAT_R16G16B16A16_FLOAT,
|
||||||
TextureFormat.D24_UNorm_S8_UInt => DXGI_FORMAT.DXGI_FORMAT_D24_UNORM_S8_UINT,
|
TextureFormat.R32G32B32A32_Float => DXGI_FORMAT_R32G32B32A32_FLOAT,
|
||||||
TextureFormat.D32_Float => DXGI_FORMAT.DXGI_FORMAT_D32_FLOAT,
|
TextureFormat.D24_UNorm_S8_UInt => DXGI_FORMAT_D24_UNORM_S8_UINT,
|
||||||
|
TextureFormat.D32_Float => DXGI_FORMAT_D32_FLOAT,
|
||||||
_ => throw new NotSupportedException($"Texture format {format} is not supported."),
|
_ => throw new NotSupportedException($"Texture format {format} is not supported."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -45,12 +47,12 @@ internal unsafe static class D3D12Utility
|
|||||||
{
|
{
|
||||||
return format switch
|
return format switch
|
||||||
{
|
{
|
||||||
DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM => TextureFormat.R8G8B8A8_UNorm,
|
DXGI_FORMAT_R8G8B8A8_UNORM => TextureFormat.R8G8B8A8_UNorm,
|
||||||
DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM => TextureFormat.B8G8R8A8_UNorm,
|
DXGI_FORMAT_B8G8R8A8_UNORM => TextureFormat.B8G8R8A8_UNorm,
|
||||||
DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_FLOAT => TextureFormat.R16G16B16A16_Float,
|
DXGI_FORMAT_R16G16B16A16_FLOAT => TextureFormat.R16G16B16A16_Float,
|
||||||
DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_FLOAT => TextureFormat.R32G32B32A32_Float,
|
DXGI_FORMAT_R32G32B32A32_FLOAT => TextureFormat.R32G32B32A32_Float,
|
||||||
DXGI_FORMAT.DXGI_FORMAT_D24_UNORM_S8_UINT => TextureFormat.D24_UNorm_S8_UInt,
|
DXGI_FORMAT_D24_UNORM_S8_UINT => TextureFormat.D24_UNorm_S8_UInt,
|
||||||
DXGI_FORMAT.DXGI_FORMAT_D32_FLOAT => TextureFormat.D32_Float,
|
DXGI_FORMAT_D32_FLOAT => TextureFormat.D32_Float,
|
||||||
_ => TextureFormat.Unknown,
|
_ => TextureFormat.Unknown,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -59,16 +61,16 @@ internal unsafe static class D3D12Utility
|
|||||||
{
|
{
|
||||||
return state switch
|
return state switch
|
||||||
{
|
{
|
||||||
ResourceState.Common or ResourceState.Present => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COMMON,
|
ResourceState.Common or ResourceState.Present => D3D12_RESOURCE_STATE_COMMON,
|
||||||
ResourceState.VertexAndConstantBuffer => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
|
ResourceState.VertexAndConstantBuffer => D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER,
|
||||||
ResourceState.IndexBuffer => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_INDEX_BUFFER,
|
ResourceState.IndexBuffer => D3D12_RESOURCE_STATE_INDEX_BUFFER,
|
||||||
ResourceState.RenderTarget => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_RENDER_TARGET,
|
ResourceState.RenderTarget => D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||||
ResourceState.UnorderedAccess => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
|
ResourceState.UnorderedAccess => D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
|
||||||
ResourceState.DepthWrite => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_DEPTH_WRITE,
|
ResourceState.DepthWrite => D3D12_RESOURCE_STATE_DEPTH_WRITE,
|
||||||
ResourceState.DepthRead => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_DEPTH_READ,
|
ResourceState.DepthRead => D3D12_RESOURCE_STATE_DEPTH_READ,
|
||||||
ResourceState.PixelShaderResource => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
ResourceState.PixelShaderResource => D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||||
ResourceState.CopyDest => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COPY_DEST,
|
ResourceState.CopyDest => D3D12_RESOURCE_STATE_COPY_DEST,
|
||||||
ResourceState.CopySource => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COPY_SOURCE,
|
ResourceState.CopySource => D3D12_RESOURCE_STATE_COPY_SOURCE,
|
||||||
_ => throw new ArgumentException($"Unknown resource state: {state}")
|
_ => throw new ArgumentException($"Unknown resource state: {state}")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,20 @@
|
|||||||
<IsAotCompatible>True</IsAotCompatible>
|
<IsAotCompatible>True</IsAotCompatible>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="runtime\win-x64\native\dxcompiler.dll" />
|
||||||
|
<None Remove="runtime\win-x64\native\dxil.dll" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="runtime\win-x64\native\dxcompiler.dll">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="runtime\win-x64\native\dxil.dll">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Misaki.HighPerformance.Image" Version="1.0.0" />
|
<PackageReference Include="Misaki.HighPerformance.Image" Version="1.0.0" />
|
||||||
<PackageReference Include="TerraFX.Interop.D3D12MemoryAllocator" Version="2.0.1.5" />
|
<PackageReference Include="TerraFX.Interop.D3D12MemoryAllocator" Version="2.0.1.5" />
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public interface IPipelineLibrary
|
|||||||
/// Load pipeline library from disk.
|
/// Load pipeline library from disk.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="filePath">File path. If null, load default library.</param>
|
/// <param name="filePath">File path. If null, load default library.</param>
|
||||||
void LoadLibraryFromDisk(string? filePath);
|
void InitializeLibrary(string? filePath);
|
||||||
void SaveLibraryToDisk(string filePath);
|
void SaveLibraryToDisk(string filePath);
|
||||||
GraphicsPipelineKey CompilePassPSO(IPassDescriptor descriptor, ReadOnlySpan<TextureFormat> rtvs, TextureFormat dsv);
|
GraphicsPipelineKey CompilePassPSO(IPassDescriptor descriptor, ReadOnlySpan<TextureFormat> rtvs, TextureFormat dsv);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ internal unsafe class MeshRenderPass : IRenderPass
|
|||||||
|
|
||||||
public void Initialize(ref readonly RenderingContext ctx)
|
public void Initialize(ref readonly RenderingContext ctx)
|
||||||
{
|
{
|
||||||
var shaderDescriptor = SDLCompiler.CompileShader("F:\\csharp\\GhostEngine\\Ghost.Graphics\\RenderPasses\\ShaderCode.hlsl").GetValueOrThrow();
|
var shaderDescriptor = SDLCompiler.CompileShader("F:\\csharp\\GhostEngine\\Ghost.Graphics\\test.gshader").GetValueOrThrow();
|
||||||
|
|
||||||
var key = ctx.PipelineLibrary.CompilePassPSO(shaderDescriptor.passes[0], [TextureFormat.B8G8R8A8_UNorm], TextureFormat.Unknown);
|
var key = ctx.PipelineLibrary.CompilePassPSO(shaderDescriptor.passes[0], [TextureFormat.B8G8R8A8_UNorm], TextureFormat.Unknown);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
cbuffer ConstantBuffer : register(b0)
|
cbuffer ConstantBuffer : register(b0)
|
||||||
{
|
{
|
||||||
float4 _Color;
|
float4 _Color;
|
||||||
uint _TextureIndex1;
|
uint _TextureIndex1;
|
||||||
@@ -9,9 +9,6 @@
|
|||||||
uint _IndexBufferIndex;
|
uint _IndexBufferIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
// SM 6.6 approach - direct access to global descriptor heap
|
|
||||||
SamplerState _MainSampler : register(s0);
|
|
||||||
|
|
||||||
struct Vertex
|
struct Vertex
|
||||||
{
|
{
|
||||||
float4 position;
|
float4 position;
|
||||||
@@ -54,6 +51,8 @@ void MSMain(
|
|||||||
v.color = asfloat(vertexBuffer.Load4(vertexOffset + 48));
|
v.color = asfloat(vertexBuffer.Load4(vertexOffset + 48));
|
||||||
v.uv = asfloat(vertexBuffer.Load4(vertexOffset + 64));
|
v.uv = asfloat(vertexBuffer.Load4(vertexOffset + 64));
|
||||||
|
|
||||||
|
SetMeshOutputCounts(3, 1);
|
||||||
|
|
||||||
// Write vertex output
|
// Write vertex output
|
||||||
outVerts[vertexId].position = v.position;
|
outVerts[vertexId].position = v.position;
|
||||||
outVerts[vertexId].color = v.color;
|
outVerts[vertexId].color = v.color;
|
||||||
@@ -62,28 +61,17 @@ void MSMain(
|
|||||||
// Thread 0 defines topology
|
// Thread 0 defines topology
|
||||||
if (vertexId == 0)
|
if (vertexId == 0)
|
||||||
{
|
{
|
||||||
SetMeshOutputCounts(3, 1);
|
|
||||||
outTris[0] = uint3(0, 1, 2);
|
outTris[0] = uint3(0, 1, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 PSMain(PixelInput input) : SV_TARGET
|
float4 PSMain(PixelInput input) : SV_TARGET
|
||||||
{
|
{
|
||||||
// SM 6.6 Modern Bindless Approach:
|
float4 color1 = SAMPLE_TEXTURE2D_BINDLESS(_TextureIndex1, 0, input.uv.xy);
|
||||||
// ResourceDescriptorHeap[index] directly accesses any texture in the heap
|
float4 color2 = SAMPLE_TEXTURE2D_BINDLESS(_TextureIndex2, 0, input.uv.xy);
|
||||||
Texture2D tex1 = ResourceDescriptorHeap[_TextureIndex1];
|
float4 color3 = SAMPLE_TEXTURE2D_BINDLESS(_TextureIndex3, 0, input.uv.xy);
|
||||||
Texture2D tex2 = ResourceDescriptorHeap[_TextureIndex2];
|
float4 color4 = SAMPLE_TEXTURE2D_BINDLESS(_TextureIndex4, 0, input.uv.xy);
|
||||||
Texture2D tex3 = ResourceDescriptorHeap[_TextureIndex3];
|
|
||||||
Texture2D tex4 = ResourceDescriptorHeap[_TextureIndex4];
|
|
||||||
|
|
||||||
// Sample the textures
|
|
||||||
float4 color1 = tex1.Sample(_MainSampler, input.uv.xy);
|
|
||||||
float4 color2 = tex2.Sample(_MainSampler, input.uv.xy);
|
|
||||||
float4 color3 = tex3.Sample(_MainSampler, input.uv.xy);
|
|
||||||
float4 color4 = tex4.Sample(_MainSampler, input.uv.xy);
|
|
||||||
|
|
||||||
// Blend all textures together (simple average)
|
|
||||||
float4 blendedColor = (color1 + color2 + color3 + color4) * 0.25f;
|
float4 blendedColor = (color1 + color2 + color3 + color4) * 0.25f;
|
||||||
|
|
||||||
return blendedColor * _Color;
|
return blendedColor * _Color;
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
Ghost.Graphics/runtime/win-x64/native/dxcompiler.dll
Normal file
BIN
Ghost.Graphics/runtime/win-x64/native/dxcompiler.dll
Normal file
Binary file not shown.
BIN
Ghost.Graphics/runtime/win-x64/native/dxil.dll
Normal file
BIN
Ghost.Graphics/runtime/win-x64/native/dxil.dll
Normal file
Binary file not shown.
Reference in New Issue
Block a user