Add new interfaces and refactor rendering logic

Added a new `ConstPtr<T>` struct for type-safe pointers.
Added a new `ICommandBuffer` interface for resource copying.
Added a new `IRenderPass` interface to define render passes.
Added a new `IResource` interface for GPU resources.
Added a new `IResourceAllocator` interface for resource management.
Added a new `ISwapChainPanelNative` struct for native interactions.
Added a new `D3D12Utility` class for Direct3D 12 utilities.
Added a new package reference for `Vortice.Win32.Graphics.D3D12MemoryAllocator`.

Changed project file to allow unsafe code blocks.
Changed `Result` struct methods to improve clarity.
Changed error handling in `ProjectService` and `AssetDatabase` to use `Result.Failure()`.
Changed `launchSettings.json` to enable native debugging.
Changed rendering logic in `ScenePage.xaml.cs` to use `IRenderer`.
Changed `IGraphicsDevice` interface to include renderer properties.
Changed `IRenderView` to `IRenderer` and updated its methods.
Changed `Mesh` class to use the new `IResource` interface for buffers.
Changed `GraphicsAPI` enum to include a `None` value.
Changed various aspects of the `GraphicsPipeline` class for new architecture.

Removed the old `DX12RenderView` class and replaced it with `DX12Renderer`.
Removed unnecessary code in the `ResourceView` class.
This commit is contained in:
2025-06-30 13:50:06 +09:00
parent 8fd1222780
commit 300ae7251b
27 changed files with 765 additions and 486 deletions

View File

@@ -2,5 +2,6 @@
public enum GraphicsAPI
{
None,
DX12
}

View File

@@ -1,4 +1,4 @@
using Ghost.Graphics.DX12.Utilities;
using Ghost.Graphics.Contracts;
using Misaki.HighPerformance.Unsafe.Collections;
using Misaki.HighPerformance.Unsafe.Helpers;
using System.Numerics;
@@ -16,8 +16,8 @@ public sealed class Mesh(int initialVertexCapacity = 256, int initialIndexCapaci
private BoundingBox _bounds;
private ID3D12Resource? _vertexBuffer;
private ID3D12Resource? _indexBuffer;
private IResource? _vertexBuffer;
private IResource? _indexBuffer;
private VertexBufferView _vertexBufferView;
private IndexBufferView _indexBufferView;
@@ -35,7 +35,7 @@ public sealed class Mesh(int initialVertexCapacity = 256, int initialIndexCapaci
/// <summary>
/// Adds a vertex to the mesh with the specified attributes.
/// </summary>
/// <param name="vertex">The data to add</param>
/// <param name="vertex">The vertex data to add</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AddVertex(Vertex vertex)
{
@@ -198,11 +198,11 @@ public sealed class Mesh(int initialVertexCapacity = 256, int initialIndexCapaci
}
/// <summary>
/// Uploads the mesh data to GPU resources immediately.
/// Uploads the mesh data to GPU resources.
/// </summary>
/// <param name="device">The Direct3D 12 device.</param>
/// <param name="commandList">The Direct3D 12 command list to record the upload commands.</param>
public unsafe void UploadMeshData(ID3D12Device device, ID3D12GraphicsCommandList commandList)
public unsafe void UploadMeshData(ICommandBuffer cmb)
{
if (VertexCount == 0 || IndexCount == 0)
{
@@ -214,49 +214,33 @@ public sealed class Mesh(int initialVertexCapacity = 256, int initialIndexCapaci
var vertexBufferSize = (uint)(VertexCount * sizeof(Vertex));
var indexBufferSize = (uint)(IndexCount * sizeof(int));
_vertexBuffer = D3D12ResourceUtils.CreateCPUDestinationBuffer(device, vertexBufferSize);
_indexBuffer = D3D12ResourceUtils.CreateCPUDestinationBuffer(device, indexBufferSize);
_vertexBuffer = GraphicsPipeline.ResourceAllocator.CreateCopyDestinationBuffer(vertexBufferSize);
_indexBuffer = GraphicsPipeline.ResourceAllocator.CreateCopyDestinationBuffer(indexBufferSize);
using var vertexUploadBuffer = D3D12ResourceUtils.CreateUploadBuffer(device, vertexBufferSize);
using var indexUploadBuffer = D3D12ResourceUtils.CreateUploadBuffer(device, indexBufferSize);
using var vertexUploadBuffer = GraphicsPipeline.ResourceAllocator.CreateUploadBuffer(vertexBufferSize);
using var indexUploadBuffer = GraphicsPipeline.ResourceAllocator.CreateUploadBuffer(indexBufferSize);
void* vertexData;
vertexUploadBuffer.Map(0, null, &vertexData);
Unsafe.CopyBlock(vertexData, _vertices.GetUnsafePtr(), vertexBufferSize);
vertexUploadBuffer.Unmap(0);
vertexUploadBuffer.SetData(_vertices.AsSpan());
indexUploadBuffer.SetData(_indices.AsSpan());
void* indexData;
indexUploadBuffer.Map(0, null, &indexData);
Unsafe.CopyBlock(indexData, _indices.GetUnsafePtr(), indexBufferSize);
indexUploadBuffer.Unmap(0);
commandList.CopyBufferRegion(_vertexBuffer, 0, vertexUploadBuffer, 0, vertexBufferSize);
commandList.CopyBufferRegion(_indexBuffer, 0, indexUploadBuffer, 0, indexBufferSize);
cmb.CopyResource(_vertexBuffer, 0, vertexUploadBuffer, 0, vertexBufferSize);
cmb.CopyResource(_indexBuffer, 0, indexUploadBuffer, 0, indexBufferSize);
_vertexBufferView = new VertexBufferView
{
BufferLocation = _vertexBuffer.GPUVirtualAddress,
BufferLocation = _vertexBuffer.GPUAddress,
SizeInBytes = vertexBufferSize,
StrideInBytes = (uint)sizeof(Vertex)
};
_indexBufferView = new IndexBufferView
{
BufferLocation = _indexBuffer.GPUVirtualAddress,
BufferLocation = _indexBuffer.GPUAddress,
SizeInBytes = indexBufferSize,
Format = Format.R32_UInt
Format = Format.R32_SInt
};
}
private void DisposeGpuResources()
{
_vertexBuffer?.Release();
_vertexBuffer = null;
_indexBuffer?.Release();
_indexBuffer = null;
}
/// <summary>
/// Clears all vertex and index data and releases associated GPU resources.
/// </summar>
@@ -267,6 +251,15 @@ public sealed class Mesh(int initialVertexCapacity = 256, int initialIndexCapaci
DisposeGpuResources();
}
private void DisposeGpuResources()
{
_vertexBuffer?.Dispose();
_vertexBuffer = null;
_indexBuffer?.Dispose();
_indexBuffer = null;
}
public void Dispose()
{
_vertices.Dispose();

View File

@@ -1,25 +0,0 @@
namespace Ghost.Graphics.Data;
internal abstract unsafe class ResourceView
{
public GraphicsResource Resource
{
get;
}
internal void* CpuDescriptorHandle
{
get;
}
protected ResourceView(GraphicsResource resource, void* descriptor)
{
Resource = resource;
CpuDescriptorHandle = descriptor;
}
protected ResourceView(GraphicsResource resource, IntPtr descriptor) :
this(resource, (void*)descriptor)
{
}
}

View File

@@ -1,4 +1,6 @@
namespace Ghost.Graphics.Data;
using Ghost.Graphics.Contracts;
namespace Ghost.Graphics.Data;
internal readonly struct SwapChainPresenter
{
@@ -13,7 +15,7 @@ internal readonly struct SwapChainPresenter
get;
}
public readonly Vortice.WinUI.ISwapChainPanelNative? SwapChainPanelNative
public readonly ISwapChainPanelNative SwapChainPanelNative
{
get;
}
@@ -33,7 +35,7 @@ internal readonly struct SwapChainPresenter
get;
}
public SwapChainPresenter(Vortice.WinUI.ISwapChainPanelNative swapChainPanelNative, uint width, uint height)
public SwapChainPresenter(ISwapChainPanelNative swapChainPanelNative, uint width, uint height)
{
Type = TargetType.Composition;
SwapChainPanelNative = swapChainPanelNative;
@@ -45,7 +47,6 @@ internal readonly struct SwapChainPresenter
public SwapChainPresenter(IntPtr hwnd, uint width, uint height)
{
Type = TargetType.Hwnd;
SwapChainPanelNative = null;
Hwnd = hwnd;
Width = width;
Height = height;