Refactor error handling: use Error enum, update APIs

Replaces ErrorStatus with Error across all systems for consistency.
Renames ResourceBarrierData fields to camelCase.
Adds BindlessAccess enum and updates GetBindlessIndex API.
Updates method signatures, result types, and error checks.
Modernizes HLSL mesh shader syntax and fixes naming.
Improves code style and updates comments for clarity.
This commit is contained in:
2026-01-25 16:34:28 +09:00
parent e11a9ebb52
commit 364fbf9208
28 changed files with 282 additions and 252 deletions

View File

@@ -115,9 +115,9 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#if DEBUG
[System.Diagnostics.CodeAnalysis.DoesNotReturn]
private static void RecordError(string cmdName, ErrorStatus status)
private static void RecordError(string cmdName, Error status)
#else
private void RecordError(string cmdName, ErrorStatus status)
private void RecordError(string cmdName, Error status)
#endif
{
#if DEBUG
@@ -168,7 +168,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
_isRecording = false;
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return Result.Failure($"Command buffer ended with errors at {_lastError.CommandIndex}, command '{_lastError.CommandName}': {_lastError.Status}");
}
@@ -182,7 +182,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -198,7 +198,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -351,7 +351,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -365,12 +365,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
var handle = renderTargets[i];
if (!handle.IsValid)
{
RecordError(nameof(SetRenderTargets), ErrorStatus.InvalidArgument);
RecordError(nameof(SetRenderTargets), Error.InvalidArgument);
continue;
}
var recordResult = _resourceDatabase.GetResourceRecord(handle.AsResource());
if (recordResult.Error != ErrorStatus.None)
if (recordResult.Error != Error.None)
{
RecordError(nameof(SetRenderTargets), recordResult.Error);
continue;
@@ -386,7 +386,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
if (pDsvHandle != null)
{
var recordResult = _resourceDatabase.GetResourceRecord(depthTarget.AsResource());
if (recordResult.Error != ErrorStatus.None)
if (recordResult.Error != Error.None)
{
RecordError(nameof(SetRenderTargets), recordResult.Error);
return;
@@ -404,7 +404,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -412,7 +412,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
IncrementCommandCount();
var recordResult = _resourceDatabase.GetResourceRecord(renderTarget.AsResource());
if (recordResult.Error != ErrorStatus.None)
if (recordResult.Error != Error.None)
{
RecordError(nameof(ClearRenderTargetView), recordResult.Error);
return;
@@ -436,7 +436,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -444,7 +444,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
IncrementCommandCount();
var recordResult = _resourceDatabase.GetResourceRecord(depthStencil.AsResource());
if (recordResult.Error != ErrorStatus.None)
if (recordResult.Error != Error.None)
{
RecordError(nameof(ClearDepthStencilView), recordResult.Error);
return;
@@ -467,7 +467,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -480,12 +480,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
var rtDesc = rtDescs[i];
if (rtDesc.Texture.IsInvalid)
{
RecordError(nameof(BeginRenderPass), ErrorStatus.InvalidArgument);
RecordError(nameof(BeginRenderPass), Error.InvalidArgument);
continue;
}
var recordResult = _resourceDatabase.GetResourceRecord(rtDesc.Texture.AsResource());
if (recordResult.Error != ErrorStatus.None)
if (recordResult.Error != Error.None)
{
RecordError(nameof(BeginRenderPass), recordResult.Error);
continue;
@@ -539,7 +539,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
if (pDsvDesc != null)
{
var recordResult = _resourceDatabase.GetResourceRecord(depthDesc.Texture.AsResource());
if (recordResult.Error != ErrorStatus.None)
if (recordResult.Error != Error.None)
{
RecordError(nameof(BeginRenderPass), recordResult.Error);
return;
@@ -628,7 +628,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -643,7 +643,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -659,7 +659,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -667,7 +667,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
IncrementCommandCount();
var psor = _pipelineLibrary.GetGraphicsPSO(pipelineKey);
if (psor.Error != ErrorStatus.None)
if (psor.Error != Error.None)
{
RecordError(nameof(SetPipelineState), psor.Error);
return;
@@ -682,7 +682,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -698,7 +698,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -706,7 +706,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
IncrementCommandCount();
var recordResult = _resourceDatabase.GetResourceRecord(buffer.AsResource());
if (recordResult.Error != ErrorStatus.None)
if (recordResult.Error != Error.None)
{
RecordError(nameof(BeginRenderPass), recordResult.Error);
return;
@@ -728,7 +728,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -751,7 +751,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -774,7 +774,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -792,7 +792,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -807,7 +807,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -822,7 +822,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -837,7 +837,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -870,7 +870,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -890,7 +890,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -919,7 +919,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -960,7 +960,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
ThrowIfDisposed();
ThrowIfNotRecording();
#if !DEBUG
if (_lastError.Status != ErrorStatus.None)
if (_lastError.Status != Error.None)
{
return;
}
@@ -971,7 +971,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
var pSrcResource = _resourceDatabase.GetResource(src.AsResource());
if (pSrcResource == null || pDestResource == null)
{
RecordError(nameof(CopyBuffer), ErrorStatus.InvalidArgument);
RecordError(nameof(CopyBuffer), Error.InvalidArgument);
return;
}

View File

@@ -331,14 +331,14 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary
return _pipelineCache.ContainsKey(key);
}
public Result<SharedPtr<ID3D12PipelineState>, ErrorStatus> GetGraphicsPSO(Key128<GraphicsPipeline> key)
public Result<SharedPtr<ID3D12PipelineState>, Error> GetGraphicsPSO(Key128<GraphicsPipeline> key)
{
if (_pipelineCache.TryGetValue(key, out var cacheEntry))
{
return cacheEntry.pso.Share();
}
return ErrorStatus.NotFound;
return Error.NotFound;
}
public void Dispose()

View File

@@ -68,7 +68,7 @@ internal class D3D12Renderer : IRenderer
// HACK: This is hard coded for testing purposes only.
var error = RenderScene(target, RenderOutput.Viewport, RenderOutput.Scissor);
if (error != ErrorStatus.None)
if (error != Error.None)
{
_commandBuffer.End();
return Result.Failure(error);
@@ -88,7 +88,7 @@ internal class D3D12Renderer : IRenderer
}
// TODO: A proper render graph integration.
private ErrorStatus RenderScene(Handle<Texture> target, ViewportDesc viewport, RectDesc rect)
private Error RenderScene(Handle<Texture> target, ViewportDesc viewport, RectDesc rect)
{
// NOTE: Testing only.
var ctx = new RenderingContext(_graphicsEngine, _commandBuffer);
@@ -116,7 +116,7 @@ internal class D3D12Renderer : IRenderer
//_commandBuffer.EndRenderPass();
_frameIndex++;
return ErrorStatus.None;
return Error.None;
}
public void Dispose()

View File

@@ -605,9 +605,9 @@ internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator
var barrierData = new ResourceBarrierData
{
Access = BarrierAccess.NoAccess,
Layout = BarrierLayout.Common,
Sync = BarrierSync.None
access = BarrierAccess.NoAccess,
layout = BarrierLayout.Common,
sync = BarrierSync.None
};
return TrackAllocation(alloc, barrierData, ResourceViewGroup.Invalid, default, name, false);
@@ -693,9 +693,9 @@ internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator
var barrierData = new ResourceBarrierData
{
Access = BarrierAccess.NoAccess,
Layout = BarrierLayout.Common,
Sync = BarrierSync.None
access = BarrierAccess.NoAccess,
layout = BarrierLayout.Common,
sync = BarrierSync.None
};
Handle<GPUResource> resource;
@@ -715,7 +715,7 @@ internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator
{
ObjectDisposedException.ThrowIf(_disposed, this);
var textureDesc = desc.ToTextureDescripton();
var textureDesc = desc.ToTextureDescription();
return CreateTexture(in textureDesc, name, options);
}
@@ -803,9 +803,9 @@ internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator
var barrierData = new ResourceBarrierData
{
Access = BarrierAccess.NoAccess,
Layout = BarrierLayout.Undefined,
Sync = BarrierSync.None
access = BarrierAccess.NoAccess,
layout = BarrierLayout.Undefined,
sync = BarrierSync.None
};
Handle<GPUResource> resource;
@@ -927,7 +927,7 @@ internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator
ObjectDisposedException.ThrowIf(_disposed, this);
var material = new Material();
if (material.SetShader(shader, this, _resourceDatabase) != ErrorStatus.None)
if (material.SetShader(shader, this, _resourceDatabase) != Error.None)
{
return Handle<Material>.Invalid;
}

View File

@@ -6,11 +6,14 @@ using Misaki.HighPerformance.Collections;
using Misaki.HighPerformance.LowLevel;
using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using TerraFX.Interop.DirectX;
namespace Ghost.Graphics.D3D12;
// TODO: Thread safety
internal class D3D12ResourceDatabase : IResourceDatabase
{
internal unsafe record struct ResourceRecord
@@ -38,9 +41,6 @@ internal class D3D12ResourceDatabase : IResourceDatabase
public ResourceViewGroup viewGroup;
public ResourceUnion resource;
//public BarrierLayout layout;
//public BarrierAccess access;
//public BarrierSync sync;
public ResourceBarrierData barrierData;
public uint cpuFenceValue;
@@ -71,7 +71,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
this.desc = resource->GetDesc().ToResourceDesc();
}
public uint Release(D3D12DescriptorAllocator descriptorAllocator)
public readonly uint Release(D3D12DescriptorAllocator descriptorAllocator)
{
var refCount = 0u;
if (Allocated)
@@ -87,10 +87,6 @@ internal class D3D12ResourceDatabase : IResourceDatabase
}
descriptorAllocator.Release(viewGroup);
resource = default;
viewGroup = default;
return refCount;
}
}
@@ -138,6 +134,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
public unsafe Handle<GPUResource> ImportExternalResource(ID3D12Resource* pResource, ResourceBarrierData initialBarrierData, ResourceViewGroup viewGroup, string? name = null)
{
ObjectDisposedException.ThrowIf(_disposed, this);
if (pResource == null)
{
#if DEBUG
@@ -196,17 +193,17 @@ internal class D3D12ResourceDatabase : IResourceDatabase
return _resources.Contains(handle.ID, handle.Generation);
}
public RefResult<ResourceRecord, ErrorStatus> GetResourceRecord(Handle<GPUResource> handle)
public RefResult<ResourceRecord, Error> GetResourceRecord(Handle<GPUResource> handle)
{
ObjectDisposedException.ThrowIf(_disposed, this);
ref var info = ref _resources.GetElementReferenceAt(handle.ID, handle.Generation, out var exist);
if (!exist)
{
return ErrorStatus.NotFound;
return Error.NotFound;
}
return RefResult<ResourceRecord, ErrorStatus>.Success(ref info);
return RefResult<ResourceRecord, Error>.Success(ref info);
}
public SharedPtr<ID3D12Resource> GetResource(Handle<GPUResource> handle)
@@ -220,7 +217,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
return r.Value.ResourcePtr;
}
public Result<ResourceBarrierData, ErrorStatus> GetResourceBarrierData(Handle<GPUResource> handle)
public Result<ResourceBarrierData, Error> GetResourceBarrierData(Handle<GPUResource> handle)
{
var r = GetResourceRecord(handle);
if (r.IsFailure)
@@ -231,7 +228,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
return r.Value.barrierData;
}
public ErrorStatus SetResourceBarrierData(Handle<GPUResource> handle, ResourceBarrierData data)
public Error SetResourceBarrierData(Handle<GPUResource> handle, ResourceBarrierData data)
{
var r = GetResourceRecord(handle);
if (r.IsFailure)
@@ -240,10 +237,10 @@ internal class D3D12ResourceDatabase : IResourceDatabase
}
r.Value.barrierData = data;
return ErrorStatus.None;
return Error.None;
}
public Result<ResourceDesc, ErrorStatus> GetResourceDescription(Handle<GPUResource> handle)
public Result<ResourceDesc, Error> GetResourceDescription(Handle<GPUResource> handle)
{
var r = GetResourceRecord(handle);
if (r.IsFailure)
@@ -254,7 +251,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
return r.Value.desc;
}
public uint GetBindlessIndex(Handle<GPUResource> handle)
public uint GetBindlessIndex(Handle<GPUResource> handle, BindlessAccess access = BindlessAccess.ShaderResource)
{
var r = GetResourceRecord(handle);
if (r.IsFailure || !r.Value.Allocated)
@@ -262,7 +259,13 @@ internal class D3D12ResourceDatabase : IResourceDatabase
return ~0u;
}
return (uint)r.Value.viewGroup.srv.Value;
return access switch
{
BindlessAccess.ShaderResource => (uint)r.Value.viewGroup.srv.Value,
BindlessAccess.ConstantBuffer => (uint)r.Value.viewGroup.cbv.Value,
BindlessAccess.UnorderedAccess => (uint)r.Value.viewGroup.uav.Value,
_ => ~0u,
};
}
public string? GetResourceName(Handle<GPUResource> handle)
@@ -345,15 +348,15 @@ internal class D3D12ResourceDatabase : IResourceDatabase
return _meshes.Contains(handle.ID, handle.Generation);
}
public RefResult<Mesh, ErrorStatus> GetMeshReference(Handle<Mesh> handle)
public RefResult<Mesh, Error> GetMeshReference(Handle<Mesh> handle)
{
ref var mesh = ref _meshes.GetElementReferenceAt(handle.ID, handle.Generation, out var exist);
if (!exist)
{
return ErrorStatus.NotFound;
return Error.NotFound;
}
return RefResult<Mesh, ErrorStatus>.Success(ref mesh);
return RefResult<Mesh, Error>.Success(ref mesh);
}
public void ReleaseMesh(Handle<Mesh> handle)
@@ -384,15 +387,15 @@ internal class D3D12ResourceDatabase : IResourceDatabase
return _materials.Contains(handle.ID, handle.Generation);
}
public RefResult<Material, ErrorStatus> GetMaterialReference(Handle<Material> handle)
public RefResult<Material, Error> GetMaterialReference(Handle<Material> handle)
{
ref var material = ref _materials.GetElementReferenceAt(handle.ID, handle.Generation, out var exist);
if (!exist)
{
return ErrorStatus.NotFound;
return Error.NotFound;
}
return RefResult<Material, ErrorStatus>.Success(ref material);
return RefResult<Material, Error>.Success(ref material);
}
public void ReleaseMaterial(Handle<Material> handle)
@@ -424,14 +427,14 @@ internal class D3D12ResourceDatabase : IResourceDatabase
return id.Value >= 0 && id.Value < _shaders.Count;
}
public RefResult<Shader, ErrorStatus> GetShaderReference(Identifier<Shader> id)
public RefResult<Shader, Error> GetShaderReference(Identifier<Shader> id)
{
if (!HasShader(id))
{
return ErrorStatus.NotFound;
return Error.NotFound;
}
return RefResult<Shader, ErrorStatus>.Success(ref _shaders[id.Value]);
return RefResult<Shader, Error>.Success(ref _shaders[id.Value]);
}
public void ReleaseShader(Identifier<Shader> id)
@@ -449,6 +452,8 @@ internal class D3D12ResourceDatabase : IResourceDatabase
public void Dispose()
{
[DoesNotReturn]
[Conditional("DEBUG")]
static void ThrowMemoryLeakException(string resourceType, int count)
{
throw new MemoryLeakException($"ResourceAllocator is being disposed with {count} {resourceType} still registered. Ensure all resources are released before disposing.");

View File

@@ -159,9 +159,9 @@ internal unsafe class D3D12SwapChain : ISwapChain
var barrierData = new ResourceBarrierData
{
Access = BarrierAccess.NoAccess,
Layout = BarrierLayout.Present,
Sync = BarrierSync.None,
access = BarrierAccess.NoAccess,
layout = BarrierLayout.Present,
sync = BarrierSync.None,
};
var handle = _resourceDatabase.ImportExternalResource(pBackBuffer, barrierData, view);