Refactor namespaces and improve resource handling

- Updated namespaces from `Ghost.UnitTest` to `Ghost.Graphics.Test` across multiple files.
- Refactored `GraphicsTestWindow` to use a new `RenderSystem` configuration.
- Removed deprecated `Logger` and `SerializationTest` classes.
- Improved memory management in D3D12 components, including resource allocation and cleanup.
- Added `[SupportedOSPlatform]` attributes to specify Windows version compatibility.
- Updated `.editorconfig` settings and project references for consistency.
- Enabled `nativeDebugging` in `launchSettings.json`.
This commit is contained in:
2025-11-11 21:30:47 +09:00
parent fb003da26a
commit 6f786a0698
35 changed files with 334 additions and 401 deletions

View File

@@ -2,6 +2,6 @@
csharp_new_line_before_open_brace = all csharp_new_line_before_open_brace = all
csharp_preserve_single_line_statements = true csharp_preserve_single_line_statements = true
csharp_preserve_single_line_blocks = true csharp_preserve_single_line_blocks = true
dotnet_sort_system_directives_first = true dotnet_sort_system_directives_first = false
dotnet_separate_import_directive_groups = true dotnet_separate_import_directive_groups = false
max_line_length = 400 max_line_length = 400

View File

@@ -20,7 +20,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Misaki.HighPerformance" Version="1.0.0" /> <PackageReference Include="Misaki.HighPerformance" Version="1.0.0" />
<PackageReference Include="Misaki.HighPerformance.Jobs" Version="1.1.0" /> <PackageReference Include="Misaki.HighPerformance.Jobs" Version="1.1.0" />
<PackageReference Include="Misaki.HighPerformance.LowLevel" Version="1.0.0" /> <PackageReference Include="Misaki.HighPerformance.LowLevel" Version="1.1.2" />
<PackageReference Include="Misaki.HighPerformance.Mathematics" Version="1.2.6" /> <PackageReference Include="Misaki.HighPerformance.Mathematics" Version="1.2.6" />
<PackageReference Include="System.IO.Hashing" Version="9.0.10" /> <PackageReference Include="System.IO.Hashing" Version="9.0.10" />
<PackageReference Include="TerraFX.Interop.Windows" Version="10.0.26100.2" /> <PackageReference Include="TerraFX.Interop.Windows" Version="10.0.26100.2" />

View File

@@ -31,6 +31,11 @@ public readonly struct Handle<T>
return obj is Handle<T> id && Equals(id); return obj is Handle<T> id && Equals(id);
} }
public override string ToString()
{
return $"Handle<{typeof(T).Name}>({id}, {generation})";
}
public readonly bool Equals(Handle<T> other) public readonly bool Equals(Handle<T> other)
{ {
return id == other.id; return id == other.id;
@@ -77,6 +82,11 @@ public readonly struct Identifier<T>
return obj is Identifier<T> id && Equals(id); return obj is Identifier<T> id && Equals(id);
} }
public override string ToString()
{
return $"Identifier<{typeof(T).Name}>({value})";
}
public readonly bool Equals(Identifier<T> other) public readonly bool Equals(Identifier<T> other)
{ {
return value == other.value; return value == other.value;

View File

@@ -57,6 +57,25 @@ public readonly struct Result<T>
public static implicit operator Result<T>(Result result) => result.success ? Success(default!) : Fail(result.message); public static implicit operator Result<T>(Result result) => result.success ? Success(default!) : Fail(result.message);
} }
public readonly struct Result<T, S>
{
public readonly T value;
public readonly S status;
public Result(T value, S status)
{
this.value = value;
this.status = status;
}
public static Result<T, S> Create(T value, S status)
{
return new Result<T, S>(value, status);
}
public override string ToString() => $"Value: {value}, Status: {status}";
}
public static class ResultExtensions public static class ResultExtensions
{ {
public static void ThrowIfFailed(this Result result) public static void ThrowIfFailed(this Result result)

View File

@@ -6,9 +6,13 @@ using TerraFX.Interop.Windows;
namespace Ghost.Core.Utilities; namespace Ghost.Core.Utilities;
#if PLATEFORME_WIN64 internal static partial class Win32Utility
[SupportedOSPlatform("windows10.0.19041.0")] {
internal static unsafe class Win32Utility public const string OS_SUPPORTED_VERSION = "windows10.0.19041.0";
}
[SupportedOSPlatform(OS_SUPPORTED_VERSION)]
internal static unsafe partial class Win32Utility
{ {
[EditorBrowsable(EditorBrowsableState.Never)] [EditorBrowsable(EditorBrowsableState.Never)]
public readonly ref struct IID_PPV public readonly ref struct IID_PPV
@@ -70,14 +74,21 @@ internal static unsafe class Win32Utility
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void** PPV<T>(this ComPtr<T> comPtr) public static Guid* IID<T>(this T ptr)
where T : unmanaged, IUnknown.Interface
{
return Windows.__uuidof<T>();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void** PPV<T>(ref this ComPtr<T> comPtr)
where T : unmanaged, IUnknown.Interface where T : unmanaged, IUnknown.Interface
{ {
return (void**)comPtr.GetAddressOf(); return (void**)comPtr.GetAddressOf();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void** ReleaseAndGetVoidAddressOf<T>(this ComPtr<T> comPtr) public static void** ReleaseAndGetVoidAddressOf<T>(ref this ComPtr<T> comPtr)
where T : unmanaged, IUnknown.Interface where T : unmanaged, IUnknown.Interface
{ {
return (void**)comPtr.ReleaseAndGetAddressOf(); return (void**)comPtr.ReleaseAndGetAddressOf();
@@ -99,4 +110,3 @@ internal static unsafe class Win32Utility
return (flags & Unsafe.As<T, uint>(ref flag)) != 0; return (flags & Unsafe.As<T, uint>(ref flag)) != 0;
} }
} }
#endif

View File

@@ -84,7 +84,7 @@ public static partial class AssetDatabase
var metaFileResult = GetMetaFilePath(assetPath); var metaFileResult = GetMetaFilePath(assetPath);
if (!metaFileResult.success) if (!metaFileResult.success)
{ {
Logger.LogError(metaFileResult.message); Logger.LogError(metaFileResult.message ?? string.Empty);
return; return;
} }

View File

@@ -1,3 +1,4 @@
using Ghost.Core;
using Ghost.Editor.Core.AppState; using Ghost.Editor.Core.AppState;
using Ghost.Editor.Core.Inspector; using Ghost.Editor.Core.Inspector;
using Ghost.Editor.Core.Notifications; using Ghost.Editor.Core.Notifications;

View File

@@ -1,5 +1,5 @@
using Ghost.Core;
using Ghost.Engine.Models; using Ghost.Engine.Models;
using Ghost.Engine.Services;
namespace Ghost.Engine; namespace Ghost.Engine;
@@ -9,20 +9,20 @@ internal class EngineCore
{ {
ActivationHandler.Handle(args); ActivationHandler.Handle(args);
GraphicsPipeline.Initialize(); //GraphicsPipeline.Initialize();
GraphicsPipeline.Start(); //GraphicsPipeline.Start();
Logger.LogInfo("Engine started successfully."); Logger.LogInfo("Engine started successfully.");
} }
public void IncrementCPUFenceValue() public void IncrementCPUFenceValue()
{ {
GraphicsPipeline.SignalCPUReady(); //GraphicsPipeline.SignalCPUReady();
} }
public void ShutDown() public void ShutDown()
{ {
GraphicsPipeline.SignalCPUReady(); //GraphicsPipeline.SignalCPUReady();
GraphicsPipeline.Shutdown(); //GraphicsPipeline.Shutdown();
} }
} }

View File

@@ -21,10 +21,4 @@
<!--<ProjectReference Include="..\Ghost.Generator\Ghost.Generator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />--> <!--<ProjectReference Include="..\Ghost.Generator\Ghost.Generator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />-->
</ItemGroup> </ItemGroup>
<ItemGroup>
<Reference Include="Misaki.HighPerformance.Unsafe">
<HintPath>..\..\Class\Misaki.HighPerformance\Misaki.HighPerformance.LowLevel\bin\Release\net9.0\Misaki.HighPerformance.LowLevel.dll</HintPath>
</Reference>
</ItemGroup>
</Project> </Project>

View File

@@ -1,106 +0,0 @@
using Ghost.Engine.Models;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
namespace Ghost.Engine.Services;
internal enum LogChangeType
{
LogAdded,
LogRemoved,
LogsCleared
}
internal readonly struct LogChangeContext(LogChangeType type, int index)
{
public readonly LogChangeType changeType = type;
public readonly int index = index;
}
public static class Logger
{
private const int _MAX_LOGS = 4096;
private static readonly List<LogMessage> _logs = new();
internal static IReadOnlyList<LogMessage> Logs => _logs;
internal static event Action<LogChangeContext>? OnLogsUpdate;
internal static bool HasStackTrace
{
get; set;
}
private static StackTrace? CaptureStackTrace()
{
return HasStackTrace ? new StackTrace(1, true) : null;
}
private static void LogInternal(LogLevel level, object? message, StackTrace? stackTrace)
{
if (_logs.Count >= _MAX_LOGS)
{
_logs.RemoveAt(0);
OnLogsUpdate?.Invoke(new(LogChangeType.LogRemoved, 0));
}
var logMessage = new LogMessage(level, message?.ToString(), stackTrace?.ToString());
_logs.Add(logMessage);
OnLogsUpdate?.Invoke(new(LogChangeType.LogAdded, _logs.Count - 1));
}
private static void LogExceptionInternal(Exception ex)
{
if (_logs.Count >= _MAX_LOGS)
{
_logs.RemoveAt(0);
OnLogsUpdate?.Invoke(new(LogChangeType.LogRemoved, 0));
}
var logMessage = new LogMessage(LogLevel.Error, ex.Message, ex.StackTrace);
_logs.Add(logMessage);
OnLogsUpdate?.Invoke(new(LogChangeType.LogAdded, _logs.Count - 1));
}
public static void Log(LogLevel level, object? message)
{
LogInternal(level, message, CaptureStackTrace());
}
public static void LogInfo(object? message)
{
LogInternal(LogLevel.Info, message, CaptureStackTrace());
}
public static void LogWarning(object? message)
{
LogInternal(LogLevel.Warning, message, CaptureStackTrace());
}
public static void LogError(object? message)
{
LogInternal(LogLevel.Error, message, CaptureStackTrace());
}
public static void LogError(Exception ex)
{
LogExceptionInternal(ex);
}
public static void Assert([DoesNotReturnIf(false)] bool condition, object? message = null)
{
if (!condition)
{
LogInternal(LogLevel.Error, message ?? "Assertion failed", CaptureStackTrace());
}
}
internal static void Clear()
{
_logs.Clear();
OnLogsUpdate?.Invoke(new(LogChangeType.LogsCleared, -1));
}
}

View File

@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<UserControl <UserControl
x:Class="Ghost.UnitTest.Controls.DebugConsole" x:Class="Ghost.Graphics.Test.Controls.DebugConsole"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Ghost.UnitTest.Controls" xmlns:local="using:Ghost.Graphics.Test.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> mc:Ignorable="d">

View File

@@ -1,13 +1,15 @@
using Ghost.UnitTest.Models; using System.Collections.ObjectModel;
using Ghost.UnitTest.Services;
using Ghost.Graphics.Test.Models;
using Ghost.Graphics.Test.Services;
using Microsoft.UI; using Microsoft.UI;
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Data; using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Media; using Microsoft.UI.Xaml.Media;
using System.Collections.ObjectModel;
namespace Ghost.UnitTest.Controls; namespace Ghost.Graphics.Test.Controls;
public sealed partial class DebugConsole : UserControl public sealed partial class DebugConsole : UserControl
{ {

View File

@@ -3,7 +3,7 @@
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net9.0-windows10.0.22621.0</TargetFramework> <TargetFramework>net9.0-windows10.0.22621.0</TargetFramework>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion> <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<RootNamespace>Ghost.UnitTest</RootNamespace> <RootNamespace>Ghost.Graphics.Test</RootNamespace>
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>
<Platforms>x86;x64;ARM64</Platforms> <Platforms>x86;x64;ARM64</Platforms>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers> <RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
@@ -59,12 +59,6 @@
<ProjectReference Include="..\Ghost.Test.Core\Ghost.Test.Core.csproj" /> <ProjectReference Include="..\Ghost.Test.Core\Ghost.Test.Core.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Reference Include="Misaki.HighPerformance.Unsafe">
<HintPath>..\..\Class\Misaki.HighPerformance\Misaki.HighPerformance.LowLevel\bin\Release\net9.0\Misaki.HighPerformance.LowLevel.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup> <ItemGroup>
<Page Update="Windows\DebugOutputWindow.xaml"> <Page Update="Windows\DebugOutputWindow.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

View File

@@ -1,4 +1,4 @@
namespace Ghost.UnitTest.Models; namespace Ghost.Graphics.Test.Models;
public enum LogLevel public enum LogLevel
{ {

View File

@@ -1,10 +1,10 @@
{ {
"profiles": { "profiles": {
"Ghost.UnitTest (Package)": { "Ghost.Graphics.Test (Package)": {
"commandName": "MsixPackage", "commandName": "MsixPackage",
"nativeDebugging": false "nativeDebugging": true
}, },
"Ghost.UnitTest (Unpackaged)": { "Ghost.Graphics.Test (Unpackaged)": {
"commandName": "Project" "commandName": "Project"
} }
} }

View File

@@ -1,7 +1,8 @@
using Ghost.UnitTest.Models; using Ghost.Graphics.Test.Models;
using System.Diagnostics; using System.Diagnostics;
namespace Ghost.UnitTest.Services; namespace Ghost.Graphics.Test.Services;
internal class LoggingService internal class LoggingService
{ {

View File

@@ -1,50 +0,0 @@
using Ghost.Editor.Core.SceneGraph;
using Ghost.Entities;
using System.Text.Json;
namespace Ghost.UnitTest.Test;
internal class SerializationTest : ITest
{
private const string _TEST_FILE_PATH = "C:/Users/Misaki/Downloads/testScene.ghostscene";
public void Run()
{
var testWorld = World.Create();
var testScene = new WorldNode(testWorld, "Test Scene");
var entity1 = SceneGraphHelpers.CreateEntityNode(testScene, "entity 1");
var entity2 = SceneGraphHelpers.CreateEntityNode(testScene, "entity 2");
var entity3 = SceneGraphHelpers.CreateEntityNode(testScene, "entity 3");
var entity4 = SceneGraphHelpers.CreateEntityNode(testScene, "entity 4");
var entity5 = SceneGraphHelpers.CreateEntityNode(testScene, "entity 5");
testWorld.SystemStorage.AddSystem<TestSystem>();
SceneGraphHelpers.AttachChild(testScene, entity1, entity2);
SceneGraphHelpers.AttachChild(testScene, entity1, entity3);
SceneGraphHelpers.AttachChild(testScene, entity2, entity4);
testScene.AddChild(entity1);
testScene.AddChild(entity5);
var createStream = new FileStream(_TEST_FILE_PATH, FileMode.Create, FileAccess.Write, FileShare.None);
var options = new JsonSerializerOptions
{
WriteIndented = true,
IncludeFields = true,
IgnoreReadOnlyProperties = true,
};
JsonSerializer.Serialize(createStream, testScene, options);
createStream.Dispose();
testWorld.Dispose();
var readStream = new FileStream(_TEST_FILE_PATH, FileMode.Open, FileAccess.Read, FileShare.Read);
var deserializedScene = JsonSerializer.Deserialize<WorldNode>(readStream, options) ?? throw new Exception("Deserialization failed.");
deserializedScene.LoadAsync();
}
}

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<Application <Application
x:Class="Ghost.UnitTest.UnitTestApp" x:Class="Ghost.Graphics.Test.UnitTestApp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Ghost.UnitTest"> xmlns:local="using:Ghost.Graphics.Test">
<Application.Resources> <Application.Resources>
<ResourceDictionary> <ResourceDictionary>
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>

View File

@@ -1,11 +1,12 @@
using Ghost.UnitTest.Windows; 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;
// 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.
namespace Ghost.UnitTest; namespace Ghost.Graphics.Test;
/// <summary> /// <summary>
/// Provides application-specific behavior to supplement the default Application class. /// Provides application-specific behavior to supplement the default Application class.
/// </summary> /// </summary>
@@ -30,12 +31,11 @@ public partial class UnitTestApp : Application
{ {
Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.CreateDefaultUI(); Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.CreateDefaultUI();
_window = new DebugOutputWindow(); _window = new GraphicsTestWindow();
_window.Activate(); _window.Activate();
UITestMethodAttribute.DispatcherQueue = _window.DispatcherQueue; UITestMethodAttribute.DispatcherQueue = _window.DispatcherQueue;
Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.Run(Environment.CommandLine); Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.Run(Environment.CommandLine);
//TestRunner.Run<EntityTest>();
} }
} }

View File

@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<Window <Window
x:Class="Ghost.UnitTest.Windows.DebugOutputWindow" x:Class="Ghost.Graphics.Test.Windows.DebugOutputWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Ghost.UnitTest.Controls" xmlns:controls="using:Ghost.Graphics.Test.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Ghost.UnitTest.Windows" xmlns:local="using:Ghost.Graphics.Test.Windows"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="DebugOutputWindow" Title="DebugOutputWindow"
mc:Ignorable="d"> mc:Ignorable="d">

View File

@@ -1,6 +1,6 @@
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
namespace Ghost.UnitTest.Windows; namespace Ghost.Graphics.Test.Windows;
internal sealed partial class DebugOutputWindow : Window internal sealed partial class DebugOutputWindow : Window
{ {

View File

@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<Window <Window
x:Class="Ghost.UnitTest.Windows.GraphicsTestWindow" x:Class="Ghost.Graphics.Test.Windows.GraphicsTestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Ghost.UnitTest.Controls" xmlns:controls="using:Ghost.Graphics.Test.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Ghost.UnitTest.Windows" xmlns:local="using:Ghost.Graphics.Test.Windows"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="GraphicsTestWindow" Title="GraphicsTestWindow"
mc:Ignorable="d"> mc:Ignorable="d">

View File

@@ -4,11 +4,11 @@ using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Media; using Microsoft.UI.Xaml.Media;
using Misaki.HighPerformance.LowLevel.Buffer; using Misaki.HighPerformance.LowLevel.Buffer;
namespace Ghost.UnitTest.Windows; namespace Ghost.Graphics.Test.Windows;
public sealed partial class GraphicsTestWindow : Window public sealed partial class GraphicsTestWindow : Window
{ {
private RenderSystem? _renderSystem; private IRenderSystem? _renderSystem;
private IRenderer? _renderer; private IRenderer? _renderer;
private ISwapChain? _swapChain; private ISwapChain? _swapChain;
@@ -28,21 +28,27 @@ public sealed partial class GraphicsTestWindow : Window
AllocationManager.EnableDebugLayer(); AllocationManager.EnableDebugLayer();
#endif #endif
_renderSystem = new(GraphicsAPI.Direct3D12); _renderSystem = new RenderSystem(new()
_renderer = _renderSystem.CreateRenderer(); {
FrameBufferCount = 2,
GraphicsAPI = GraphicsAPI.Direct3D12
});
_renderer = _renderSystem.GraphicsEngine.CreateRenderer();
_swapChain = _renderSystem.GraphicsEngine.CreateSwapChain(new SwapChainDesc((uint)AppWindow.Size.Width, (uint)AppWindow.Size.Height, SwapChainTarget.FromCompositionSurface(Panel))); _swapChain = _renderSystem.GraphicsEngine.CreateSwapChain(new SwapChainDesc((uint)AppWindow.Size.Width, (uint)AppWindow.Size.Height, SwapChainTarget.FromCompositionSurface(Panel)));
_renderer.SetSwapChain(_swapChain); _renderer.SetSwapChain(_swapChain);
_renderSystem.Start();
CompositionTarget.Rendering += OnRendering; CompositionTarget.Rendering += OnRendering;
} }
private void SwapChainPanel_Unloaded(object sender, RoutedEventArgs e) private void SwapChainPanel_Unloaded(object sender, RoutedEventArgs e)
{ {
CompositionTarget.Rendering -= OnRendering; CompositionTarget.Rendering -= OnRendering;
_renderSystem?.Stop();
_swapChain?.Dispose();
_renderer?.Dispose(); _renderer?.Dispose();
_swapChain?.Dispose();
_renderSystem?.Dispose(); _renderSystem?.Dispose();
} }
@@ -50,18 +56,23 @@ public sealed partial class GraphicsTestWindow : Window
{ {
if (e.NewSize.Width > 8.0 && e.NewSize.Height > 8.0) if (e.NewSize.Width > 8.0 && e.NewSize.Height > 8.0)
{ {
_renderer?.RequestResize((uint)e.NewSize.Width, (uint)e.NewSize.Height); _renderer?.RequestResize(new((uint)e.NewSize.Width, (uint)e.NewSize.Height));
} }
} }
private void OnRendering(object? sender, object e) private void OnRendering(object? sender, object e)
{ {
//if (GraphicsPipeline.CPUFenceValue < GraphicsPipeline.GPUFenceValue + GraphicsPipeline._FRAME_COUNT) if (_renderSystem == null)
//{ {
// DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.High, () => return;
// { }
// GraphicsPipeline.SignalCPUReady();
// }); if (_renderSystem.CPUFenceValue < _renderSystem.GPUFenceValue + _renderSystem.Config.FrameBufferCount)
//} {
DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.High, () =>
{
_renderSystem.SignalCPUReady();
});
}
} }
} }

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> <assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="Ghost.UnitTest.app"/> <assemblyIdentity version="1.0.0.0" name="Ghost.Graphics.Test.app"/>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application> <application>

View File

@@ -2,14 +2,13 @@ global using static TerraFX.Interop.DirectX.D3D12;
global using static TerraFX.Interop.DirectX.DirectX; global using static TerraFX.Interop.DirectX.DirectX;
global using static TerraFX.Interop.DirectX.DXGI; 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 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.UnitTest")] [assembly: InternalsVisibleTo("Ghost.Graphics.Test")]
[assembly: SupportedOSPlatform("windows10.0.22621.0")]
[assembly: EngineAssembly] [assembly: EngineAssembly]

View File

@@ -1,19 +1,21 @@
using Ghost.Core; using Ghost.Core;
using Ghost.Core.Graphics;
using Ghost.Core.Utilities;
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.D3D12_Alias;
using static TerraFX.Aliases.D3D_Alias; using static TerraFX.Aliases.D3D_Alias;
using static TerraFX.Aliases.D3D12_Alias;
using static TerraFX.Aliases.DXGI_Alias; using static TerraFX.Aliases.DXGI_Alias;
using Ghost.Core.Graphics;
using Ghost.Graphics.Core;
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;
@@ -71,8 +73,6 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
_resourceAllocator = resourceAllocator; _resourceAllocator = resourceAllocator;
_descriptorAllocator = descriptorAllocator; _descriptorAllocator = descriptorAllocator;
// Command lists are created in recording state, so close it
_commandList.Get()->Close();
_isRecording = false; _isRecording = false;
_disposed = false; _disposed = false;
} }

View File

@@ -102,7 +102,7 @@ internal unsafe class D3D12GraphicsEngine : IGraphicsEngine
public ISwapChain CreateSwapChain(SwapChainDesc desc) public ISwapChain CreateSwapChain(SwapChainDesc desc)
{ {
ThrowIfDisposed(); ThrowIfDisposed();
return new D3D12SwapChain(_resourceDatabase, _device.DXGIFactory, ((D3D12CommandQueue)_device.ComputeQueue).NativeQueue, desc); return new D3D12SwapChain(_resourceDatabase, _device.DXGIFactory, ((D3D12CommandQueue)_device.GraphicsQueue).NativeQueue, desc);
} }
public void BeginFrame() public void BeginFrame()

View File

@@ -9,6 +9,7 @@ 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;
@@ -31,6 +32,7 @@ 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.
@@ -45,6 +47,7 @@ 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 _ROOT_PARAM_COUNT =

View File

@@ -1,6 +1,6 @@
using Ghost.Core.Utilities; using Ghost.Core.Utilities;
using Ghost.Graphics.D3D12.Utilities;
using Ghost.Graphics.RHI; using Ghost.Graphics.RHI;
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;
@@ -11,6 +11,7 @@ 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;
@@ -57,31 +58,34 @@ internal unsafe class D3D12RenderDevice : IRenderDevice
_dxgiFactory.Attach(pFactory); _dxgiFactory.Attach(pFactory);
ID3D12Device14* pDevice = default; ID3D12Device14* pDevice = default;
ComPtr<IDXGIAdapter1> adapter = default; IDXGIAdapter1* pAdapter = default;
for (uint adapterIndex = 0; for (uint adapterIndex = 0;
_dxgiFactory.Get()->EnumAdapterByGpuPreference(adapterIndex, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, adapter.IID(), adapter.ReleaseAndGetVoidAddressOf()).SUCCEEDED; _dxgiFactory.Get()->EnumAdapterByGpuPreference(adapterIndex, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, __uuidof<IDXGIAdapter1>(), (void**)&pAdapter).SUCCEEDED;
adapterIndex++) adapterIndex++)
{ {
DXGI_ADAPTER_DESC1 desc = default; DXGI_ADAPTER_DESC1 desc = default;
adapter.Get()->GetDesc1(&desc); pAdapter->GetDesc1(&desc);
// Don't select the Basic Render Driver adapter. // Don't select the Basic Render Driver adapter.
if (desc.Flags.HasFlag(DXGI_ADAPTER_FLAG_SOFTWARE)) if (desc.Flags.HasFlag(DXGI_ADAPTER_FLAG_SOFTWARE))
{ {
continue; goto NEXT_ITERATION;
} }
if (D3D12CreateDevice((IUnknown*)adapter.Get(), D3D_FEATURE_LEVEL_12_0, __uuidof(pDevice), (void**)&pDevice).SUCCEEDED) if (D3D12CreateDevice((IUnknown*)pAdapter, D3D_FEATURE_LEVEL_12_0, __uuidof(pDevice), (void**)&pDevice).SUCCEEDED)
{ {
_adapter = adapter.Move(); _adapter.Attach(pAdapter);
break; break;
} }
NEXT_ITERATION:
pAdapter->Release();
} }
if (pDevice == null) if (pDevice == null)
{ {
adapter.Dispose(); // Dispose the last adapter we tried. If the operation succeeded, we would have moved it. pAdapter->Release(); // Dispose the last adapter we tried. If the operation succeeded, we would have moved it.
throw new PlatformNotSupportedException("Cannot create ID3D12Device with feature level 12.0"); throw new PlatformNotSupportedException("Cannot create ID3D12Device with feature level 12.0");
} }

View File

@@ -3,12 +3,12 @@ using Ghost.Core.Graphics;
using Ghost.Core.Utilities; using Ghost.Core.Utilities;
using Ghost.Graphics.Core; using Ghost.Graphics.Core;
using Ghost.Graphics.RHI; using Ghost.Graphics.RHI;
using Misaki.HighPerformance.Mathematics;
using Misaki.HighPerformance.LowLevel.Collections; using Misaki.HighPerformance.LowLevel.Collections;
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;
using static TerraFX.Aliases.D3D12MA_Alias; using static TerraFX.Aliases.D3D12MA_Alias;
using static TerraFX.Aliases.DXGI_Alias; using static TerraFX.Aliases.DXGI_Alias;
@@ -16,6 +16,7 @@ using static TerraFX.Interop.DirectX.D3D12MemAlloc;
namespace Ghost.Graphics.D3D12; namespace Ghost.Graphics.D3D12;
[SupportedOSPlatform(Win32Utility.OS_SUPPORTED_VERSION)]
internal unsafe sealed 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.
@@ -591,6 +592,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 unsafe sealed partial class D3D12ResourceAllocator : IResourceAllocator, IDisposable
{ {
private readonly IFenceSynchronizer _fenceSynchronizer; private readonly IFenceSynchronizer _fenceSynchronizer;

View File

@@ -1,16 +1,19 @@
using Ghost.Core; using Ghost.Core;
using Ghost.Core.Utilities;
using Ghost.Graphics.Core;
using Ghost.Graphics.RHI; using Ghost.Graphics.RHI;
using Misaki.HighPerformance.Collections; using Misaki.HighPerformance.Collections;
using Misaki.HighPerformance.LowLevel.Buffer; 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;
using Ghost.Graphics.Core;
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
@@ -106,13 +109,13 @@ internal class D3D12ResourceDatabase : IResourceDatabase, IDisposable
public D3D12ResourceDatabase(D3D12DescriptorAllocator descriptorAllocator) public D3D12ResourceDatabase(D3D12DescriptorAllocator descriptorAllocator)
{ {
_resources = new(64, Allocator.Persistent); _resources = new(64, Allocator.Persistent, AllocationOption.Clear);
#if DEBUG || GHOST_EDITOR #if DEBUG || GHOST_EDITOR
_resourceName = new(64); _resourceName = new(64);
#endif #endif
_meshes = new(64, Allocator.Persistent); _meshes = new(64, Allocator.Persistent, AllocationOption.Clear);
_materials = new(16, Allocator.Persistent); _materials = new(16, Allocator.Persistent, AllocationOption.Clear);
_shaders = new(16); _shaders = new(16);
_shaderPasses = new(16); _shaderPasses = new(16);
@@ -168,7 +171,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase, IDisposable
public bool HasResource(Handle<GPUResource> handle) public bool HasResource(Handle<GPUResource> handle)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
return _resources.Contain(handle.id, handle.generation); return _resources.Contains(handle.id, handle.generation);
} }
public ref ResourceRecord GetResourceInfo(Handle<GPUResource> handle) public ref ResourceRecord GetResourceInfo(Handle<GPUResource> handle)
@@ -292,7 +295,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase, IDisposable
public bool HasMesh(Handle<Mesh> handle) public bool HasMesh(Handle<Mesh> handle)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
return _meshes.Contain(handle.id, handle.generation); return _meshes.Contains(handle.id, handle.generation);
} }
public ref Mesh GetMeshReference(Handle<Mesh> handle) public ref Mesh GetMeshReference(Handle<Mesh> handle)
@@ -333,7 +336,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase, IDisposable
public bool HasMaterial(Handle<Material> handle) public bool HasMaterial(Handle<Material> handle)
{ {
ObjectDisposedException.ThrowIf(_disposed, this); ObjectDisposedException.ThrowIf(_disposed, this);
return _materials.Contain(handle.id, handle.generation); return _materials.Contains(handle.id, handle.generation);
} }
public ref Material GetMaterialReference(Handle<Material> handle) public ref Material GetMaterialReference(Handle<Material> handle)

View File

@@ -5,6 +5,7 @@ using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections; using Misaki.HighPerformance.LowLevel.Collections;
using Misaki.HighPerformance.LowLevel.Utilities; using Misaki.HighPerformance.LowLevel.Utilities;
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;
@@ -119,6 +120,7 @@ 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)
@@ -196,27 +198,32 @@ internal static unsafe class D3D12ShaderCompiler
public static Result<CompileResult> Compile(ref readonly CompilerConfig config, Allocator allocator, IDxcBlob** ppReflectionBlob) public static Result<CompileResult> Compile(ref readonly CompilerConfig config, Allocator allocator, IDxcBlob** ppReflectionBlob)
{ {
// NOTE: Should we cache the compiler and utils instances for better performance? // NOTE: Should we cache the pCompiler and pUtils instances for better performance?
using ComPtr<IDxcCompiler3> compiler = default; IDxcCompiler3* pCompiler = default;
using ComPtr<IDxcUtils> utils = default; IDxcUtils* pUtils = default;
using ComPtr<IDxcIncludeHandler> includeHandler = default; IDxcIncludeHandler* pIncludeHandler = default;
// Create DXC compiler and utils try
{
// Create DXC pCompiler and pUtils
var dxccID = CLSID.CLSID_DxcCompiler; var dxccID = CLSID.CLSID_DxcCompiler;
var dxcuID = CLSID.CLSID_DxcUtils; var dxcuID = CLSID.CLSID_DxcUtils;
ThrowIfFailed(DxcCreateInstance(&dxccID, compiler.IID(), compiler.PPV())); ThrowIfFailed(DxcCreateInstance(&dxccID, pCompiler->IID(), (void**)&pCompiler));
ThrowIfFailed(DxcCreateInstance(&dxcuID, utils.IID(), utils.PPV())); ThrowIfFailed(DxcCreateInstance(&dxcuID, pUtils->IID(), (void**)&pUtils));
//includeHandler.Get()->LoadSource(); //pIncludeHandler.Get()->LoadSource();
utils.Get()->CreateDefaultIncludeHandler(includeHandler.GetAddressOf()); pUtils->CreateDefaultIncludeHandler(&pIncludeHandler);
// Create source blob // Create source blob
using ComPtr<IDxcBlobEncoding> sourceBlob = default; using ComPtr<IDxcBlobEncoding> sourceBlob = default;
if (utils.Get()->LoadFile(config.shaderPath.AsSpan().GetUnsafePtr(), null, sourceBlob.GetAddressOf()).FAILED) fixed (char* pPath = config.shaderPath)
{
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}");
} }
}
var argsArray = GetCompilerArguments(in config); var argsArray = GetCompilerArguments(in config);
var argPtrs = stackalloc char*[argsArray.Count]; var argPtrs = stackalloc char*[argsArray.Count];
@@ -225,10 +232,11 @@ internal static unsafe class D3D12ShaderCompiler
argPtrs[i] = (char*)Marshal.StringToHGlobalUni(argsArray[i]); argPtrs[i] = (char*)Marshal.StringToHGlobalUni(argsArray[i]);
} }
IDxcResult* pResult = default;
try try
{ {
// Compile shader // Compile shader
using ComPtr<IDxcResult> result = default;
var buffer = new DxcBuffer var buffer = new DxcBuffer
{ {
Ptr = sourceBlob.Get()->GetBufferPointer(), Ptr = sourceBlob.Get()->GetBufferPointer(),
@@ -236,16 +244,16 @@ internal static unsafe class D3D12ShaderCompiler
Encoding = DXC.DXC_CP_UTF8 Encoding = DXC.DXC_CP_UTF8
}; };
ThrowIfFailed(compiler.Get()->Compile(&buffer, argPtrs, (uint)argsArray.Count, includeHandler.Get(), result.IID(), result.PPV())); ThrowIfFailed(pCompiler->Compile(&buffer, argPtrs, (uint)argsArray.Count, pIncludeHandler, pResult->IID(), (void**)&pResult));
// Check compilation result // Check compilation pResult
HRESULT hrStatus; HRESULT hrStatus;
result.Get()->GetStatus(&hrStatus); pResult->GetStatus(&hrStatus);
if (hrStatus.FAILED) if (hrStatus.FAILED)
{ {
// Get error messages // Get error messages
using ComPtr<IDxcBlobEncoding> errorBlob = default; using ComPtr<IDxcBlobEncoding> errorBlob = default;
result.Get()->GetErrorBuffer(errorBlob.GetAddressOf()); pResult->GetErrorBuffer(errorBlob.GetAddressOf());
if (errorBlob.Get() != null) if (errorBlob.Get() != null)
{ {
@@ -260,12 +268,12 @@ internal static unsafe class D3D12ShaderCompiler
// Get compiled bytecode // Get compiled bytecode
using ComPtr<IDxcBlob> bytecodeBlob = default; using ComPtr<IDxcBlob> bytecodeBlob = default;
ThrowIfFailed(result.Get()->GetResult(bytecodeBlob.GetAddressOf())); ThrowIfFailed(pResult->GetResult(bytecodeBlob.GetAddressOf()));
// Get reflection data using DXC API // Get reflection data using DXC API
if (ppReflectionBlob != null) if (ppReflectionBlob != null)
{ {
ThrowIfFailed(result.Get()->GetOutput(DXC_OUT_KIND.DXC_OUT_REFLECTION, __uuidof<IDxcBlob>(), (void**)ppReflectionBlob, null)); ThrowIfFailed(pResult->GetOutput(DXC_OUT_KIND.DXC_OUT_REFLECTION, __uuidof<IDxcBlob>(), (void**)ppReflectionBlob, null));
} }
var bytecodeSize = bytecodeBlob.Get()->GetBufferSize(); var bytecodeSize = bytecodeBlob.Get()->GetBufferSize();
@@ -284,6 +292,15 @@ internal static unsafe class D3D12ShaderCompiler
{ {
Marshal.FreeHGlobal((nint)argPtrs[i]); Marshal.FreeHGlobal((nint)argPtrs[i]);
} }
pResult->Release();
}
}
finally
{
pCompiler->Release();
pUtils->Release();
pIncludeHandler->Release();
} }
} }
@@ -296,9 +313,13 @@ internal static unsafe class D3D12ShaderCompiler
return Result<ShaderReflectionData>.Fail("Reflection blob is null."); return Result<ShaderReflectionData>.Fail("Reflection blob is null.");
} }
// Create DXC utils to parse reflection data ComPtr<IDxcUtils> utils = default;
ComPtr<ID3D12ShaderReflection> reflection = default;
try
{
// Create DXC pUtils to parse reflection data
var dxcuID = CLSID.CLSID_DxcUtils; var dxcuID = CLSID.CLSID_DxcUtils;
using ComPtr<IDxcUtils> utils = default;
ThrowIfFailed(DxcCreateInstance(&dxcuID, utils.IID(), utils.PPV())); ThrowIfFailed(DxcCreateInstance(&dxcuID, utils.IID(), utils.PPV()));
// Create reflection interface from blob // Create reflection interface from blob
@@ -309,7 +330,6 @@ internal static unsafe class D3D12ShaderCompiler
Encoding = DXC.DXC_CP_ACP Encoding = DXC.DXC_CP_ACP
}; };
using ComPtr<ID3D12ShaderReflection> reflection = default;
ThrowIfFailed(utils.Get()->CreateReflection(&reflectionBuffer, reflection.IID(), reflection.PPV())); ThrowIfFailed(utils.Get()->CreateReflection(&reflectionBuffer, reflection.IID(), reflection.PPV()));
D3D12_SHADER_DESC shaderDesc; D3D12_SHADER_DESC shaderDesc;
@@ -389,5 +409,12 @@ internal static unsafe class D3D12ShaderCompiler
} }
return reflectionData; return reflectionData;
}
finally
{
utils.Dispose();
reflection.Dispose();
}
} }
} }

View File

@@ -71,18 +71,18 @@ internal unsafe class D3D12SwapChain : ISwapChain
Stereo = false, Stereo = false,
}; };
using ComPtr<IDXGISwapChain1> tempSwapChain = default; IDXGISwapChain1* pTempSwapChain = default;
switch (desc.target.type) switch (desc.target.type)
{ {
case SwapChainTargetType.Composition: case SwapChainTargetType.Composition:
pFactory->CreateSwapChainForComposition((IUnknown*)commandQueue, &swapChainDesc, null, tempSwapChain.GetAddressOf()); ThrowIfFailed(pFactory->CreateSwapChainForComposition((IUnknown*)commandQueue, &swapChainDesc, null, &pTempSwapChain));
// Set the composition surface // Set the composition surface
if (desc.target.compositionSurface != null) if (desc.target.compositionSurface != null)
{ {
using var swapChainPanelNative = ISwapChainPanelNative.FromSwapChainPanel(desc.target.compositionSurface); using var swapChainPanelNative = ISwapChainPanelNative.FromSwapChainPanel(desc.target.compositionSurface);
swapChainPanelNative.SetSwapChain((IntPtr)tempSwapChain.Get()); swapChainPanelNative.SetSwapChain((IntPtr)pTempSwapChain);
} }
break; break;
@@ -98,7 +98,7 @@ internal unsafe class D3D12SwapChain : ISwapChain
&swapChainDesc, &swapChainDesc,
&swapChainFullscreenDesc, &swapChainFullscreenDesc,
null, null,
tempSwapChain.GetAddressOf()); &pTempSwapChain);
break; break;
default: default:
@@ -106,7 +106,8 @@ internal unsafe class D3D12SwapChain : ISwapChain
} }
IDXGISwapChain4* pSwapChain = default; IDXGISwapChain4* pSwapChain = default;
tempSwapChain.Get()->QueryInterface(__uuidof(pSwapChain), (void**)&pSwapChain); pTempSwapChain->QueryInterface(__uuidof(pSwapChain), (void**)&pSwapChain);
pTempSwapChain->Release();
_swapChain.Attach(pSwapChain); _swapChain.Attach(pSwapChain);
} }

View File

@@ -288,7 +288,15 @@ internal unsafe struct D3D12DescriptorHeap : IDisposable
_heap.Attach(pHeap); _heap.Attach(pHeap);
_startCpuHandle = _heap.Get()->GetCPUDescriptorHandleForHeapStart(); _startCpuHandle = _heap.Get()->GetCPUDescriptorHandleForHeapStart();
if (!_allocatedDescriptors.IsCreated)
{
_allocatedDescriptors = new UnsafeArray<bool>(numDescriptors, Misaki.HighPerformance.LowLevel.Buffer.Allocator.Persistent);
}
else
{
_allocatedDescriptors.Resize(numDescriptors); _allocatedDescriptors.Resize(numDescriptors);
}
if (ShaderVisible) if (ShaderVisible)
{ {

View File

@@ -46,7 +46,7 @@ public interface IFenceSynchronizer
public void SignalCPUReady(); public void SignalCPUReady();
} }
public interface IRenderSystem : IFenceSynchronizer public interface IRenderSystem : IFenceSynchronizer, IDisposable
{ {
RenderingConfig Config RenderingConfig Config
{ {