feat(wrapper): span-based interop, resource API refactor

Refactored native wrappers to use ReadOnlySpan<T> for pointer parameters, improving .NET safety and interop. Enhanced wrapper generator with $TYPE and prefix/suffix-based parameter remapping. Added platform-specific native library loading for meshoptimizer, nvtt, and ufbx. Updated D3D12GraphicsEngineFactory for native DLL resolution and removed redundant logic from UnitTestApp. Changed RenderGraphBuilder's resource extraction API to use QueryTextureExtraction/QueryBufferExtraction with explicit handles and flags. Removed IRenderer and D3D12Renderer, moving RenderContext to RenderPipeline. Improved mesh loading, resource management, and updated test shader conventions. Updated project references, build settings, and added launchSettings.json for tooling.

BREAKING CHANGE: Native wrapper APIs now use ReadOnlySpan<T> instead of pointers. RenderGraphBuilder resource extraction API has changed. IRenderer and D3D12Renderer have been removed.
This commit is contained in:
2026-04-01 14:50:20 +09:00
parent 0b6e5b8501
commit a00cb27529
41 changed files with 491 additions and 482 deletions

View File

@@ -3,6 +3,4 @@ global using static TerraFX.Interop.DirectX.DirectX;
global using static TerraFX.Interop.DirectX.DXGI;
global using static TerraFX.Interop.Windows.Windows;
using System.Runtime.Versioning;
[assembly: SupportedOSPlatform("windows10.0.19041.0")]
[assembly: System.Runtime.Versioning.SupportedOSPlatform("windows10.0.19041.0")]

View File

@@ -7,11 +7,38 @@ using Ghost.Graphics.Core;
using Ghost.Graphics.RHI;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Loader;
namespace Ghost.Graphics.D3D12;
public static class D3D12GraphicsEngineFactory
{
static D3D12GraphicsEngineFactory()
{
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, "runtimes", platform + "-" + arch, "native");
AssemblyLoadContext.Default.ResolvingUnmanagedDll += (assembly, libraryName) =>
{
if (libraryName == "dxcompiler")
{
NativeLibrary.TryLoad(Path.Combine(nativeDllDir, "dxil.dll"), out _);
if (NativeLibrary.TryLoad(Path.Combine(nativeDllDir, "dxcompiler.dll"), out var dxcHandle))
{
return dxcHandle;
}
}
return IntPtr.Zero;
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IGraphicsEngine Create(GraphicsEngineDesc desc)
{

View File

@@ -1,124 +0,0 @@
using Ghost.Core;
using Ghost.Graphics.RHI;
namespace Ghost.Graphics.D3D12;
/// <summary>
/// D3D12 implementation of the renderer interface using RHI abstractions
/// </summary>
internal class D3D12Renderer : IRenderer
{
private readonly D3D12GraphicsEngine _graphicsEngine;
private readonly ICommandBuffer _commandBuffer;
private bool _disposed;
public IRenderOutput? RenderOutput
{
get; set;
}
public Func<RenderContext, Error>? RenderFunc
{
get; set;
}
public D3D12Renderer(D3D12GraphicsEngine graphicsEngine)
{
_graphicsEngine = graphicsEngine;
_commandBuffer = _graphicsEngine.CreateCommandBuffer(CommandBufferType.Graphics);
}
~D3D12Renderer()
{
Dispose();
}
public Result Render(ICommandAllocator commandAllocator)
{
if (RenderFunc is null)
{
return Result.Success(); // No render function set, skip rendering.
}
if (RenderOutput is null)
{
return Result.Failure("Render target strategy is not set.");
}
var target = RenderOutput.GetRenderTarget();
if (target.IsInvalid)
{
return Result.Failure("Render target is invalid.");
}
_commandBuffer.Begin(commandAllocator);
RenderOutput.BeginRender(_commandBuffer);
var ctx = new RenderContext();
var error = RenderFunc.Invoke(ctx);
if (error != Error.None)
{
_commandBuffer.End();
return Result.Failure(error);
}
RenderOutput.EndRender(_commandBuffer);
var r = _commandBuffer.End();
if (r.IsFailure)
{
return r;
}
_graphicsEngine.Device.GraphicsQueue.Submit(_commandBuffer);
RenderOutput.Present();
return Result.Success();
}
//// TODO: A proper render graph integration.
//private Error RenderScene(Handle<Texture> target, ViewportDesc viewport, ScissorRectDesc rect)
//{
// // NOTE: Testing only.
// var ctx = new RenderingContext(_graphicsEngine, _commandBuffer);
// if (_frameIndex == 0)
// {
// _pass.Initialize(ref ctx);
// }
// //_commandBuffer.BeginRenderPass(rtDesc, depthDesc, false);
// _commandBuffer.SetViewport(viewport);
// _commandBuffer.SetScissorRect(rect);
// _renderGraph.Reset();
// var backBuffer = _renderGraph.ImportTexture(target, "Back Buffer");
// _pass.Build(_renderGraph, backBuffer);
// // Create view state from viewport
// var viewState = new ViewState((uint)viewport.Width, (uint)viewport.Height);
// // Compile with view state
// _renderGraph.Compile(in viewState);
// _renderGraph.Execute(_commandBuffer);
// //_commandBuffer.EndRenderPass();
// _frameIndex++;
// return Error.None;
//}
public void Dispose()
{
if (_disposed)
{
return;
}
_commandBuffer.Dispose();
_disposed = true;
GC.SuppressFinalize(this);
}
}

View File

@@ -487,7 +487,7 @@ internal static unsafe class D3D12Utility
public static D3D12_RASTERIZER_DESC D3D12_RASTERIZER_DESC_CREATE(
D3D12_FILL_MODE fillMode,
D3D12_CULL_MODE cullMode,
bool frontCounterClockwise = false,
bool frontCounterClockwise = true,
int depthBias = D3D12_DEFAULT_DEPTH_BIAS,
float depthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP,
float slopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS,