Refactor render graph error handling and resource APIs

- RenderGraph.Compile/Execute now return Error for better failure detection; error handling is propagated throughout compiler and executor.
- Renamed ScheduleReleaseResource to ReleaseResource for clarity; updated all usages.
- ResourceManager now calls ReleaseResource directly on Mesh, Material, and Shader types.
- Camera exposes Actual/Virtual size properties and Render returns Error.
- RenderingContext now uses IResourceManager for mesh/resource ops.
- Replaced custom BinaryWriter with BufferWriter in RenderGraphHasher.
- Improved variable naming, interface signatures, and code formatting.
- Added Error extension for IsSuccess/IsFailure.
- Minor FMOD/native interop and test code cleanups.
- No breaking API changes except for new Error return values on some methods.
This commit is contained in:
2026-02-25 19:08:54 +09:00
parent 30090f84ab
commit 162b71f309
93 changed files with 537 additions and 593 deletions

View File

@@ -8,6 +8,7 @@ public class Camera
{
private readonly IRenderer _renderer;
// History buffers.
private Handle<Texture> _colorTexture;
private Handle<Texture> _depthTexture;
@@ -23,14 +24,17 @@ public class Camera
/// Gets the actual width of the camera's render target in pixels. If upscaler is used, this is the width before upscaling.
/// </summary>
public uint ActualWidth => _actualWidth;
/// <summary>
/// Gets the actual height of the camera's render target in pixels. If upscaler is used, this is the height before upscaling.
/// </summary>
public uint ActualHeight => _actualHeight;
/// <summary>
/// Gets the virtual width of the camera's render target in pixels. If upscaler is used, this is the width after upscaling.
/// </summary>
public uint VirtualWidth => _virtualWidth;
/// <summary>
/// Gets the virtual height of the camera's render target in pixels. If upscaler is used, this is the height after upscaling.
/// </summary>
@@ -64,8 +68,17 @@ public class Camera
RenderGraph.Reset();
var view = new ViewState(_virtualWidth, _virtualHeight, _actualWidth, _actualHeight);
RenderGraph.Compile(in view);
RenderGraph.Execute(context.CommandBuffer);
var e = RenderGraph.Compile(in view);
if (e != Error.None)
{
return e;
}
e = RenderGraph.Execute(context.CommandBuffer);
if (e != Error.None)
{
return e;
}
return Error.None;
}

View File

@@ -35,7 +35,7 @@ internal struct CBufferCache : IResourceReleasable
}
_cpuData.Dispose();
database.ScheduleReleaseResource(_gpuResource.AsResource());
database.ReleaseResource(_gpuResource.AsResource());
_gpuResource = Handle<GraphicsBuffer>.Invalid;
_size = 0;
@@ -144,7 +144,6 @@ public struct Material : IResourceReleasable
return _cBufferCache.CpuData.AsSpan(0, (int)_cBufferCache.Size);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe Error SetPropertyCache<T>(scoped ref readonly T data)
where T : unmanaged
{
@@ -166,7 +165,6 @@ public struct Material : IResourceReleasable
return Error.None;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Error SetRawPropertyCache(ReadOnlySpan<byte> data)
{
if (data.Length != _cBufferCache.Size)
@@ -200,7 +198,6 @@ public struct Material : IResourceReleasable
_isDirty = true;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Error SetKeyword(IResourceManager manager, int keywordId, bool enabled)
{
var r = manager.GetShaderReference(_shader);
@@ -222,7 +219,6 @@ public struct Material : IResourceReleasable
return Error.None;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly bool IsKeywordEnabled(IResourceManager manager, int keywordId)
{
var r = manager.GetShaderReference(_shader);
@@ -276,8 +272,7 @@ public struct Material : IResourceReleasable
cmd.ResourceBarrier(desc);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void IResourceReleasable.ReleaseResource(IResourceDatabase database)
public void ReleaseResource(IResourceDatabase database)
{
_cBufferCache.ReleaseResource(database);
_passPipelineOverride.Dispose();

View File

@@ -113,13 +113,13 @@ public struct Mesh : IResourceReleasable
_indices.Dispose();
}
readonly void IResourceReleasable.ReleaseResource(IResourceDatabase database)
public readonly void ReleaseResource(IResourceDatabase database)
{
ReleaseCpuResources();
database.ScheduleReleaseResource(VertexBuffer.AsResource());
database.ScheduleReleaseResource(IndexBuffer.AsResource());
database.ScheduleReleaseResource(ObjectDataBuffer.AsResource());
database.ReleaseResource(VertexBuffer.AsResource());
database.ReleaseResource(IndexBuffer.AsResource());
database.ReleaseResource(ObjectDataBuffer.AsResource());
}
}

View File

@@ -10,18 +10,21 @@ namespace Ghost.Graphics.Core;
public readonly unsafe ref struct RenderingContext
{
private readonly IGraphicsEngine _engine;
private readonly IResourceManager _resourceManager;
private readonly ICommandBuffer _directCmd;
public ICommandBuffer DirectCommandBuffer => _directCmd;
public IShaderCompiler ShaderCompiler => _engine.ShaderCompiler;
public IResourceManager ResourceManager => _resourceManager;
public IResourceAllocator ResourceAllocator => _engine.ResourceAllocator;
public IResourceDatabase ResourceDatabase => _engine.ResourceDatabase;
public IPipelineLibrary PipelineLibrary => _engine.PipelineLibrary;
internal RenderingContext(IGraphicsEngine engine, ICommandBuffer directCmd)
internal RenderingContext(IGraphicsEngine engine, IResourceManager resourceManager, ICommandBuffer directCmd)
{
_engine = engine;
_resourceManager = resourceManager;
_directCmd = directCmd;
}
@@ -82,8 +85,8 @@ public readonly unsafe ref struct RenderingContext
public Handle<Mesh> CreateMesh(UnsafeList<Vertex> vertices, UnsafeList<uint> indices, bool staticMesh)
{
var mesh = ResourceAllocator.CreateMesh(vertices, indices);
var r = ResourceDatabase.GetMeshReference(mesh);
var mesh = _resourceManager.CreateMesh(vertices, indices);
var r = _resourceManager.GetMeshReference(mesh);
if (r.IsFailure)
{
return mesh;
@@ -129,7 +132,7 @@ public readonly unsafe ref struct RenderingContext
/// <param name="markMeshStatic">Whether to mark the mesh as static. If it's true, the cpu buffer of the mesh will not be avaliable any more</param>
public void UploadMesh(Handle<Mesh> mesh, bool markMeshStatic)
{
var r = ResourceDatabase.GetMeshReference(mesh);
var r = _resourceManager.GetMeshReference(mesh);
if (r.IsFailure)
{
return;
@@ -156,7 +159,7 @@ public readonly unsafe ref struct RenderingContext
public void UpdateObjectData(Handle<Mesh> mesh, float4x4 localToWorld)
{
var r = ResourceDatabase.GetMeshReference(mesh);
var r = _resourceManager.GetMeshReference(mesh);
if (r.IsFailure)
{
return;
@@ -192,7 +195,7 @@ public readonly unsafe ref struct RenderingContext
where T : unmanaged
{
var desc = ResourceDatabase.GetResourceDescription(texture.AsResource()).GetValueOrThrow();
//var size = ResourceAllocator.GetSizeInfo(desc).Size;
//if ((ulong)(data.Length * sizeof(T)) != ResourceAllocator.GetSizeInfo(desc).Size)
//{

View File

@@ -3,6 +3,7 @@ using Ghost.Core.Graphics;
using Ghost.Graphics.RHI;
using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Ghost.Graphics.Core;
@@ -136,6 +137,7 @@ public partial struct Shader : IResourceReleasable
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal readonly int GetLocalKeywordIndex(int globalKeywordID)
{
if (_keywordIDToLocal.TryGetValue(globalKeywordID, out var localIndex))
@@ -146,6 +148,7 @@ public partial struct Shader : IResourceReleasable
return -1;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly int GetPassIndex(Identifier<ShaderPass> passID)
{
if (_passIDToLocal.TryGetValue(passID.Value, out var index))
@@ -156,6 +159,7 @@ public partial struct Shader : IResourceReleasable
return -1;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly int GetPassIndex(string passName)
{
if (_passIDToLocal.TryGetValue(GetPassID(passName), out var index))
@@ -166,11 +170,13 @@ public partial struct Shader : IResourceReleasable
return -1;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly ref ShaderPass GetPassReference(int index)
{
return ref _shaderPasses[index];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly Result<ShaderPass, Error> TryGetPass(Identifier<ShaderPass> passID, out int passIndex)
{
if (_passIDToLocal.TryGetValue(passID.Value, out var index))
@@ -183,7 +189,7 @@ public partial struct Shader : IResourceReleasable
return _shaderPasses[index];
}
void IResourceReleasable.ReleaseResource(IResourceDatabase database)
public void ReleaseResource(IResourceDatabase database)
{
_keywordIDToLocal.Dispose();
_shaderPasses.Dispose();