diff --git a/Ghost.Core/Utilities/Win32Utility.cs b/Ghost.Core/Utilities/Win32Utility.cs index 2fc3d65..be1c49a 100644 --- a/Ghost.Core/Utilities/Win32Utility.cs +++ b/Ghost.Core/Utilities/Win32Utility.cs @@ -6,12 +6,7 @@ using TerraFX.Interop.Windows; namespace Ghost.Core.Utilities; -internal static partial class Win32Utility -{ - public const string OS_SUPPORTED_VERSION = "windows10.0.19041.0"; -} - -[SupportedOSPlatform(OS_SUPPORTED_VERSION)] +[SupportedOSPlatform("windows10.0.19041.0")] internal static unsafe partial class Win32Utility { [EditorBrowsable(EditorBrowsableState.Never)] diff --git a/Ghost.Entities/Query/QueryFilter.cs b/Ghost.Entities/Query/QueryFilter.cs index 8893e9d..bb2e6eb 100644 --- a/Ghost.Entities/Query/QueryFilter.cs +++ b/Ghost.Entities/Query/QueryFilter.cs @@ -6,7 +6,7 @@ namespace Ghost.Entities.Query; public struct QueryFilter : IDisposable { - private readonly Stack.Scope _scope; + //private readonly Stack.Scope _scope; internal UnsafeList _all; internal UnsafeList _any; @@ -15,7 +15,7 @@ public struct QueryFilter : IDisposable public QueryFilter() { - _scope = AllocationManager.CreateStackScope(); + //_scope = AllocationManager.CreateStackScope(); _all = new UnsafeList(4, Allocator.Stack); _any = new UnsafeList(4, Allocator.Stack); @@ -92,6 +92,6 @@ public struct QueryFilter : IDisposable public readonly void Dispose() { - _scope.Dispose(); + //_scope.Dispose(); } } \ No newline at end of file diff --git a/Ghost.Graphics.Test/UnitTestApp.xaml.cs b/Ghost.Graphics.Test/UnitTestApp.xaml.cs index ed0fb52..34e14ff 100644 --- a/Ghost.Graphics.Test/UnitTestApp.xaml.cs +++ b/Ghost.Graphics.Test/UnitTestApp.xaml.cs @@ -2,6 +2,7 @@ using Ghost.Graphics.Test.Windows; using Microsoft.UI.Xaml; using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer; +using System.Runtime.InteropServices; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. @@ -23,12 +24,31 @@ public partial class UnitTestApp : Application 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); + } + } + } + /// /// Invoked when the application is launched. /// /// Details about the launch request and process. protected override void OnLaunched(LaunchActivatedEventArgs args) { + LoadDll(); + Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.CreateDefaultUI(); _window = new GraphicsTestWindow(); diff --git a/Ghost.Graphics/AssemblyInfo.cs b/Ghost.Graphics/AssemblyInfo.cs index c66383e..1f1c0db 100644 --- a/Ghost.Graphics/AssemblyInfo.cs +++ b/Ghost.Graphics/AssemblyInfo.cs @@ -4,11 +4,15 @@ global using static TerraFX.Interop.DirectX.DXGI; global using static TerraFX.Interop.Windows.Windows; using Ghost.Core.Attributes; +using Ghost.Core.Utilities; using System.Runtime.CompilerServices; +using System.Runtime.Versioning; [assembly: InternalsVisibleTo("Ghost.Engine")] [assembly: InternalsVisibleTo("Ghost.Editor")] [assembly: InternalsVisibleTo("Ghost.Editor.Core")] [assembly: InternalsVisibleTo("Ghost.Graphics.Test")] +[assembly: SupportedOSPlatform("windows10.0.19041.0")] + [assembly: EngineAssembly] \ No newline at end of file diff --git a/Ghost.Graphics/D3D12/D3D12CommandBuffer.cs b/Ghost.Graphics/D3D12/D3D12CommandBuffer.cs index a8a3eb7..b10e01a 100644 --- a/Ghost.Graphics/D3D12/D3D12CommandBuffer.cs +++ b/Ghost.Graphics/D3D12/D3D12CommandBuffer.cs @@ -1,12 +1,10 @@ using Ghost.Core; using Ghost.Core.Graphics; -using Ghost.Core.Utilities; using Ghost.Graphics.Core; using Ghost.Graphics.D3D12.Utilities; using Ghost.Graphics.RHI; using Misaki.HighPerformance.LowLevel.Utilities; using System.Runtime.CompilerServices; -using System.Runtime.Versioning; using TerraFX.Interop.DirectX; using TerraFX.Interop.Windows; using static TerraFX.Aliases.D3D_Alias; @@ -15,7 +13,6 @@ using static TerraFX.Aliases.DXGI_Alias; namespace Ghost.Graphics.D3D12; -[SupportedOSPlatform(Win32Utility.OS_SUPPORTED_VERSION)] internal unsafe class D3D12CommandBuffer : ICommandBuffer { private ComPtr _allocator; diff --git a/Ghost.Graphics/D3D12/D3D12GraphicsEngine.cs b/Ghost.Graphics/D3D12/D3D12GraphicsEngine.cs index c8d3481..925c246 100644 --- a/Ghost.Graphics/D3D12/D3D12GraphicsEngine.cs +++ b/Ghost.Graphics/D3D12/D3D12GraphicsEngine.cs @@ -49,6 +49,8 @@ internal unsafe class D3D12GraphicsEngine : IGraphicsEngine CommandBufferType.Copy); _renderers = ImmutableArray.Empty; + + _pipelineLibrary.InitializeLibrary(null); } ~D3D12GraphicsEngine() @@ -59,10 +61,7 @@ internal unsafe class D3D12GraphicsEngine : IGraphicsEngine [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ThrowIfDisposed() { - if (_disposed) - { - throw new ObjectDisposedException(nameof(D3D12GraphicsEngine)); - } + ObjectDisposedException.ThrowIf(_disposed, this); } public IRenderer CreateRenderer() diff --git a/Ghost.Graphics/D3D12/D3D12PipelineLibrary.cs b/Ghost.Graphics/D3D12/D3D12PipelineLibrary.cs index b639745..3c4b0f1 100644 --- a/Ghost.Graphics/D3D12/D3D12PipelineLibrary.cs +++ b/Ghost.Graphics/D3D12/D3D12PipelineLibrary.cs @@ -9,7 +9,6 @@ using Misaki.HighPerformance.LowLevel.Utilities; using Misaki.HighPerformance.Utilities; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Runtime.Versioning; using TerraFX.Interop.DirectX; using TerraFX.Interop.Windows; @@ -32,7 +31,6 @@ internal struct D3D12GraphicsCompiledResult : IDisposable } } -[SupportedOSPlatform(Win32Utility.OS_SUPPORTED_VERSION)] internal struct D3D12PipelineState : IDisposable { // 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 { - private const int _ROOT_PARAM_COUNT = + private const int rootParamCount = #if USE_TRADITIONAL_BINDLESS 6 #else @@ -83,7 +80,7 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable _defaultRootSignature = default; // 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 { ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV, @@ -146,7 +143,7 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable var rootSignatureDesc = new D3D12_ROOT_SIGNATURE_DESC1 { - NumParameters = _ROOT_PARAM_COUNT, + NumParameters = rootParamCount, pParameters = rootParameters, NumStaticSamplers = 0, pStaticSamplers = null, @@ -180,7 +177,7 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable _defaultRootSignature.Attach(pRootSignature); } - public void LoadLibraryFromDisk(string? filePath) + public void InitializeLibrary(string? filePath) { ID3D12PipelineLibrary1* pLibrary = default; @@ -219,9 +216,9 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable 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) @@ -240,13 +237,16 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable 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(); +#if false if (reflectionBlob != null) { var reflection = D3D12ShaderCompiler.PerformDXCReflection(reflectionBlob).GetValueOrThrow(); ValidateReflectionData(reflection); } +#endif return result; } @@ -415,15 +415,16 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable existing.compileResult = compiled; existing.psoDesc = desc; + var meshStream = new CD3DX12_PIPELINE_MESH_STATE_STREAM(in desc); var streamDesc = new D3D12_PIPELINE_STATE_STREAM_DESC { - pPipelineStateSubobjectStream = &desc, - SizeInBytes = (nuint)sizeof(D3DX12_MESH_SHADER_PIPELINE_STATE_DESC) + pPipelineStateSubobjectStream = &meshStream, + SizeInBytes = (nuint)sizeof(CD3DX12_PIPELINE_MESH_STATE_STREAM) }; ID3D12PipelineState* pPipelineState = default; - char* pKeyStr = stackalloc char[GraphicsPipelineKey.KEY_STRING_LENGTH]; + var pKeyStr = stackalloc char[GraphicsPipelineKey.KEY_STRING_LENGTH]; var keySpan = new Span(pKeyStr, GraphicsPipelineKey.KEY_STRING_LENGTH); key.GetString(keySpan).ThrowIfFailed(); diff --git a/Ghost.Graphics/D3D12/D3D12RenderDevice.cs b/Ghost.Graphics/D3D12/D3D12RenderDevice.cs index 6260de4..ad02610 100644 --- a/Ghost.Graphics/D3D12/D3D12RenderDevice.cs +++ b/Ghost.Graphics/D3D12/D3D12RenderDevice.cs @@ -11,7 +11,6 @@ namespace Ghost.Graphics.D3D12; /// /// D3D12 implementation of the render device interface /// -[SupportedOSPlatform(Win32Utility.OS_SUPPORTED_VERSION)] internal unsafe class D3D12RenderDevice : IRenderDevice { private ComPtr _dxgiFactory; diff --git a/Ghost.Graphics/D3D12/D3D12ResourceAllocator.cs b/Ghost.Graphics/D3D12/D3D12ResourceAllocator.cs index f158e91..ef61d1d 100644 --- a/Ghost.Graphics/D3D12/D3D12ResourceAllocator.cs +++ b/Ghost.Graphics/D3D12/D3D12ResourceAllocator.cs @@ -6,7 +6,6 @@ using Ghost.Graphics.RHI; using Misaki.HighPerformance.LowLevel.Collections; using Misaki.HighPerformance.Mathematics; using System.Runtime.CompilerServices; -using System.Runtime.Versioning; using TerraFX.Interop.DirectX; using TerraFX.Interop.Windows; using static TerraFX.Aliases.D3D12_Alias; @@ -16,8 +15,7 @@ using static TerraFX.Interop.DirectX.D3D12MemAlloc; namespace Ghost.Graphics.D3D12; -[SupportedOSPlatform(Win32Utility.OS_SUPPORTED_VERSION)] -internal unsafe sealed partial class D3D12ResourceAllocator +internal sealed unsafe partial class D3D12ResourceAllocator { // 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; @@ -593,7 +591,7 @@ internal unsafe sealed partial class D3D12ResourceAllocator // 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. -internal unsafe sealed partial class D3D12ResourceAllocator : IResourceAllocator, IDisposable +internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator, IDisposable { private readonly IFenceSynchronizer _fenceSynchronizer; private readonly D3D12RenderDevice _device; diff --git a/Ghost.Graphics/D3D12/D3D12ResourceDatabase.cs b/Ghost.Graphics/D3D12/D3D12ResourceDatabase.cs index 03394f0..de3f33d 100644 --- a/Ghost.Graphics/D3D12/D3D12ResourceDatabase.cs +++ b/Ghost.Graphics/D3D12/D3D12ResourceDatabase.cs @@ -1,5 +1,4 @@ using Ghost.Core; -using Ghost.Core.Utilities; using Ghost.Graphics.Core; using Ghost.Graphics.RHI; using Misaki.HighPerformance.Collections; @@ -7,13 +6,11 @@ using Misaki.HighPerformance.LowLevel.Buffer; using Misaki.HighPerformance.LowLevel.Collections; using System.Diagnostics; using System.Runtime.InteropServices; -using System.Runtime.Versioning; using TerraFX.Interop.DirectX; using TerraFX.Interop.Windows; namespace Ghost.Graphics.D3D12; -[SupportedOSPlatform(Win32Utility.OS_SUPPORTED_VERSION)] internal class D3D12ResourceDatabase : IResourceDatabase, IDisposable { internal unsafe struct ResourceRecord @@ -100,8 +97,8 @@ internal class D3D12ResourceDatabase : IResourceDatabase, IDisposable private readonly Dictionary, string> _resourceName; #endif - private readonly UnsafeSlotMap _meshes; - private readonly UnsafeSlotMap _materials; + private UnsafeSlotMap _meshes; + private UnsafeSlotMap _materials; private readonly DynamicArray _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 _shaderPasses; // NOTE: The reason we use Dictionary here is that ShaderPassKey is a presistence identifier across multiple application sessions. diff --git a/Ghost.Graphics/D3D12/D3D12ShaderCompiler.cs b/Ghost.Graphics/D3D12/D3D12ShaderCompiler.cs index 9bd69ba..0497951 100644 --- a/Ghost.Graphics/D3D12/D3D12ShaderCompiler.cs +++ b/Ghost.Graphics/D3D12/D3D12ShaderCompiler.cs @@ -3,7 +3,6 @@ using Ghost.Core.Utilities; using Ghost.Graphics.RHI; using Misaki.HighPerformance.LowLevel.Buffer; using Misaki.HighPerformance.LowLevel.Collections; -using Misaki.HighPerformance.LowLevel.Utilities; using System.Runtime.InteropServices; using System.Runtime.Versioning; using TerraFX.Interop.DirectX; @@ -11,7 +10,7 @@ using TerraFX.Interop.Windows; namespace Ghost.Graphics.D3D12; -internal unsafe struct CompileResult : IDisposable +internal struct CompileResult : IDisposable { public UnsafeArray bytecode; @@ -120,7 +119,6 @@ internal readonly struct ShaderReflectionData } } -[SupportedOSPlatform(Win32Utility.OS_SUPPORTED_VERSION)] internal static unsafe class D3D12ShaderCompiler { private static string GetProfileString(ShaderStage stage, CompilerTier version) @@ -209,8 +207,8 @@ internal static unsafe class D3D12ShaderCompiler var dxccID = CLSID.CLSID_DxcCompiler; var dxcuID = CLSID.CLSID_DxcUtils; - ThrowIfFailed(DxcCreateInstance(&dxccID, pCompiler->IID(), (void**)&pCompiler)); - ThrowIfFailed(DxcCreateInstance(&dxcuID, pUtils->IID(), (void**)&pUtils)); + ThrowIfFailed(DxcCreateInstance(&dxccID, __uuidof(pCompiler), (void**)&pCompiler)); + ThrowIfFailed(DxcCreateInstance(&dxcuID, __uuidof(pUtils), (void**)&pUtils)); //pIncludeHandler.Get()->LoadSource(); pUtils->CreateDefaultIncludeHandler(&pIncludeHandler); @@ -218,7 +216,7 @@ internal static unsafe class D3D12ShaderCompiler // Create source blob using ComPtr sourceBlob = default; fixed (char* pPath = config.shaderPath) - { + { if (pUtils->LoadFile(pPath, null, sourceBlob.GetAddressOf()).FAILED) { return Result.Fail($"Failed to load shader file: {config.shaderPath}"); @@ -244,7 +242,7 @@ internal static unsafe class D3D12ShaderCompiler 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 HRESULT hrStatus; @@ -257,7 +255,7 @@ internal static unsafe class D3D12ShaderCompiler 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}"); } else diff --git a/Ghost.Graphics/D3D12/Utilities/D3D12Utility.cs b/Ghost.Graphics/D3D12/Utilities/D3D12Utility.cs index 6b0395c..21ff439 100644 --- a/Ghost.Graphics/D3D12/Utilities/D3D12Utility.cs +++ b/Ghost.Graphics/D3D12/Utilities/D3D12Utility.cs @@ -2,6 +2,7 @@ using Ghost.Graphics.RHI; using TerraFX.Interop.DirectX; using static TerraFX.Aliases.D3D12_Alias; +using static TerraFX.Aliases.DXGI_Alias; namespace Ghost.Graphics.D3D12.Utilities; @@ -31,12 +32,13 @@ internal unsafe static class D3D12Utility { return format switch { - TextureFormat.R8G8B8A8_UNorm => DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM, - TextureFormat.B8G8R8A8_UNorm => DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM, - TextureFormat.R16G16B16A16_Float => DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_FLOAT, - TextureFormat.R32G32B32A32_Float => DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_FLOAT, - TextureFormat.D24_UNorm_S8_UInt => DXGI_FORMAT.DXGI_FORMAT_D24_UNORM_S8_UINT, - TextureFormat.D32_Float => DXGI_FORMAT.DXGI_FORMAT_D32_FLOAT, + TextureFormat.Unknown => DXGI_FORMAT_UNKNOWN, + TextureFormat.R8G8B8A8_UNorm => DXGI_FORMAT_R8G8B8A8_UNORM, + TextureFormat.B8G8R8A8_UNorm => DXGI_FORMAT_B8G8R8A8_UNORM, + TextureFormat.R16G16B16A16_Float => DXGI_FORMAT_R16G16B16A16_FLOAT, + TextureFormat.R32G32B32A32_Float => DXGI_FORMAT_R32G32B32A32_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."), }; } @@ -45,12 +47,12 @@ internal unsafe static class D3D12Utility { return format switch { - DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM => TextureFormat.R8G8B8A8_UNorm, - DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM => TextureFormat.B8G8R8A8_UNorm, - DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_FLOAT => TextureFormat.R16G16B16A16_Float, - DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_FLOAT => TextureFormat.R32G32B32A32_Float, - DXGI_FORMAT.DXGI_FORMAT_D24_UNORM_S8_UINT => TextureFormat.D24_UNorm_S8_UInt, - DXGI_FORMAT.DXGI_FORMAT_D32_FLOAT => TextureFormat.D32_Float, + DXGI_FORMAT_R8G8B8A8_UNORM => TextureFormat.R8G8B8A8_UNorm, + DXGI_FORMAT_B8G8R8A8_UNORM => TextureFormat.B8G8R8A8_UNorm, + DXGI_FORMAT_R16G16B16A16_FLOAT => TextureFormat.R16G16B16A16_Float, + DXGI_FORMAT_R32G32B32A32_FLOAT => TextureFormat.R32G32B32A32_Float, + DXGI_FORMAT_D24_UNORM_S8_UINT => TextureFormat.D24_UNorm_S8_UInt, + DXGI_FORMAT_D32_FLOAT => TextureFormat.D32_Float, _ => TextureFormat.Unknown, }; } @@ -59,16 +61,16 @@ internal unsafe static class D3D12Utility { return state switch { - ResourceState.Common or ResourceState.Present => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COMMON, - ResourceState.VertexAndConstantBuffer => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, - ResourceState.IndexBuffer => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_INDEX_BUFFER, - ResourceState.RenderTarget => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_RENDER_TARGET, - ResourceState.UnorderedAccess => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_UNORDERED_ACCESS, - ResourceState.DepthWrite => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_DEPTH_WRITE, - ResourceState.DepthRead => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_DEPTH_READ, - ResourceState.PixelShaderResource => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, - ResourceState.CopyDest => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COPY_DEST, - ResourceState.CopySource => D3D12_RESOURCE_STATES.D3D12_RESOURCE_STATE_COPY_SOURCE, + ResourceState.Common or ResourceState.Present => D3D12_RESOURCE_STATE_COMMON, + ResourceState.VertexAndConstantBuffer => D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, + ResourceState.IndexBuffer => D3D12_RESOURCE_STATE_INDEX_BUFFER, + ResourceState.RenderTarget => D3D12_RESOURCE_STATE_RENDER_TARGET, + ResourceState.UnorderedAccess => D3D12_RESOURCE_STATE_UNORDERED_ACCESS, + ResourceState.DepthWrite => D3D12_RESOURCE_STATE_DEPTH_WRITE, + ResourceState.DepthRead => D3D12_RESOURCE_STATE_DEPTH_READ, + ResourceState.PixelShaderResource => D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, + ResourceState.CopyDest => D3D12_RESOURCE_STATE_COPY_DEST, + ResourceState.CopySource => D3D12_RESOURCE_STATE_COPY_SOURCE, _ => throw new ArgumentException($"Unknown resource state: {state}") }; } diff --git a/Ghost.Graphics/Ghost.Graphics.csproj b/Ghost.Graphics/Ghost.Graphics.csproj index 34ca1c2..c716068 100644 --- a/Ghost.Graphics/Ghost.Graphics.csproj +++ b/Ghost.Graphics/Ghost.Graphics.csproj @@ -16,6 +16,20 @@ True + + + + + + + + PreserveNewest + + + PreserveNewest + + + diff --git a/Ghost.Graphics/RHI/IPipelineLibrary.cs b/Ghost.Graphics/RHI/IPipelineLibrary.cs index 2f5c0ed..240e0bb 100644 --- a/Ghost.Graphics/RHI/IPipelineLibrary.cs +++ b/Ghost.Graphics/RHI/IPipelineLibrary.cs @@ -19,7 +19,7 @@ public interface IPipelineLibrary /// Load pipeline library from disk. /// /// File path. If null, load default library. - void LoadLibraryFromDisk(string? filePath); + void InitializeLibrary(string? filePath); void SaveLibraryToDisk(string filePath); GraphicsPipelineKey CompilePassPSO(IPassDescriptor descriptor, ReadOnlySpan rtvs, TextureFormat dsv); } diff --git a/Ghost.Graphics/RenderPasses/MeshRenderPass.cs b/Ghost.Graphics/RenderPasses/MeshRenderPass.cs index fbe27c9..7a6ce37 100644 --- a/Ghost.Graphics/RenderPasses/MeshRenderPass.cs +++ b/Ghost.Graphics/RenderPasses/MeshRenderPass.cs @@ -28,7 +28,7 @@ internal unsafe class MeshRenderPass : IRenderPass 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); diff --git a/Ghost.Graphics/RenderPasses/ShaderCode.hlsl b/Ghost.Graphics/RenderPasses/ShaderCode.hlsl index f9f291b..c9ca04e 100644 --- a/Ghost.Graphics/RenderPasses/ShaderCode.hlsl +++ b/Ghost.Graphics/RenderPasses/ShaderCode.hlsl @@ -1,4 +1,4 @@ -cbuffer ConstantBuffer : register(b0) +cbuffer ConstantBuffer : register(b0) { float4 _Color; uint _TextureIndex1; @@ -9,9 +9,6 @@ uint _IndexBufferIndex; }; -// SM 6.6 approach - direct access to global descriptor heap -SamplerState _MainSampler : register(s0); - struct Vertex { float4 position; @@ -54,6 +51,8 @@ void MSMain( v.color = asfloat(vertexBuffer.Load4(vertexOffset + 48)); v.uv = asfloat(vertexBuffer.Load4(vertexOffset + 64)); + SetMeshOutputCounts(3, 1); + // Write vertex output outVerts[vertexId].position = v.position; outVerts[vertexId].color = v.color; @@ -62,28 +61,17 @@ void MSMain( // Thread 0 defines topology if (vertexId == 0) { - SetMeshOutputCounts(3, 1); outTris[0] = uint3(0, 1, 2); } } float4 PSMain(PixelInput input) : SV_TARGET { - // SM 6.6 Modern Bindless Approach: - // ResourceDescriptorHeap[index] directly accesses any texture in the heap - Texture2D tex1 = ResourceDescriptorHeap[_TextureIndex1]; - Texture2D tex2 = ResourceDescriptorHeap[_TextureIndex2]; - 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 color1 = SAMPLE_TEXTURE2D_BINDLESS(_TextureIndex1, 0, input.uv.xy); + float4 color2 = SAMPLE_TEXTURE2D_BINDLESS(_TextureIndex2, 0, input.uv.xy); + float4 color3 = SAMPLE_TEXTURE2D_BINDLESS(_TextureIndex3, 0, input.uv.xy); + float4 color4 = SAMPLE_TEXTURE2D_BINDLESS(_TextureIndex4, 0, input.uv.xy); + float4 blendedColor = (color1 + color2 + color3 + color4) * 0.25f; - return blendedColor * _Color; } diff --git a/Ghost.Graphics/runtime/win-x64/native/dxcompiler.dll b/Ghost.Graphics/runtime/win-x64/native/dxcompiler.dll new file mode 100644 index 0000000..a52c4ab Binary files /dev/null and b/Ghost.Graphics/runtime/win-x64/native/dxcompiler.dll differ diff --git a/Ghost.Graphics/runtime/win-x64/native/dxil.dll b/Ghost.Graphics/runtime/win-x64/native/dxil.dll new file mode 100644 index 0000000..c3d1ebf Binary files /dev/null and b/Ghost.Graphics/runtime/win-x64/native/dxil.dll differ