feat(resource): refactor heap management & suballocation

Major overhaul of GPU resource/heap management:
- Replace resource pooling and upload buffer logic with transient heap/page-based suballocation in ResourceManager.
- Add support for suballocation and heap flags/types, with D3D12 helpers.
- Remove ICommandBuffer.UploadBuffer/UploadTexture; add UpdateSubResources and CopyBuffer, move upload logic to RenderingContext.
- Refactor D3D12ResourceAllocator/Database for suballocation, heap flags, and mapping.
- Standardize on Handle<GPUBuffer> usage.
- Update meshlet/mesh utilities for new allocation handles and memory pools.
- Refactor RenderGraph and docs to use "heap" terminology.
- Use cpuFrame/gpuFrame consistently for frame sync.
- Add s2h.hlsl, s2h_3d.hlsl, s2h_scatter.hlsl shader debug libs.
- Miscellaneous fixes, cleanup, and dependency updates.

BREAKING CHANGE: Resource pooling and upload APIs replaced with new heap/page-based suballocation system. Update all buffer/texture creation and upload code to use new ResourceManager and ICommandBuffer methods.
This commit is contained in:
2026-04-03 01:48:49 +09:00
parent d03eb659fa
commit 6321b36ef5
47 changed files with 2552 additions and 526 deletions

View File

@@ -4,14 +4,14 @@ using Ghost.Graphics.RHI;
using Misaki.HighPerformance.LowLevel;
using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections;
using Misaki.HighPerformance.LowLevel.Utilities;
using System.Diagnostics;
using System.Runtime.InteropServices;
using TerraFX.Interop.DirectX;
namespace Ghost.Graphics.D3D12;
// TODO: Thread safety
internal class D3D12ResourceDatabase : IResourceDatabase
internal unsafe class D3D12ResourceDatabase : IResourceDatabase
{
internal unsafe record struct ResourceRecord
{
@@ -109,7 +109,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
private int _writeLock;
private ulong _currentFrame;
private ulong _cpuFrame;
private bool _disposed;
public D3D12ResourceDatabase(D3D12DescriptorAllocator descriptorAllocator)
@@ -323,12 +323,12 @@ internal class D3D12ResourceDatabase : IResourceDatabase
{
Debug.Assert(!_disposed);
if (_resources.TryGetElementAt(handle.ID, handle.Generation, out var record))
if (!_resources.TryGetElementAt(handle.ID, handle.Generation, out var record))
{
return;
}
var entry = new ReleaseEntry(record, _currentFrame);
var entry = new ReleaseEntry(record, _cpuFrame);
_releaseQueue.Enqueue(entry);
_resources.Remove(handle.ID, handle.Generation);
@@ -399,20 +399,52 @@ internal class D3D12ResourceDatabase : IResourceDatabase
return Error.None;
}
public void BeginFrame(ulong currentFrame)
public Error Map(Handle<GPUResource> handle, uint subResource, ResourceRange? readRange, ResourceRange? writeRange, void* pData, nuint size)
{
Debug.Assert(!_disposed);
_currentFrame = currentFrame;
var r = GetResourceRecord(handle);
if (r.IsFailure)
{
return r.Error;
}
var resource = r.Value.ResourcePtr;
var rRange = readRange.HasValue ? new D3D12_RANGE { Begin = readRange.Value.Start, End = readRange.Value.End } : default;
var wRange = writeRange.HasValue ? new D3D12_RANGE { Begin = writeRange.Value.Start, End = writeRange.Value.End } : default;
void * mappedData = null;
resource.Get()->Map(subResource, readRange.HasValue ? &rRange : null, &mappedData);
MemoryUtility.MemCpy(mappedData, pData, size);
resource.Get()->Unmap(subResource, writeRange.HasValue ? &wRange : null);
return Error.None;
}
public void EndFrame(ulong completedFrame)
public ulong GetIntermediateResourceSize(Handle<GPUResource> resource, uint firstSubResource, uint numSubResources)
{
var r = GetResourceRecord(resource);
if (r.IsFailure)
{
return 0;
}
return GetRequiredIntermediateSize(r.Value.ResourcePtr.Get(), firstSubResource, numSubResources);
}
public void BeginFrame(ulong cpuFrame)
{
Debug.Assert(!_disposed);
_cpuFrame = cpuFrame;
}
public void EndFrame(ulong gpuFrame)
{
Debug.Assert(!_disposed);
while (_releaseQueue.Count > 0)
{
var toRelease = _releaseQueue.Peek();
if (toRelease.fenceValue > completedFrame)
if (toRelease.fenceValue > gpuFrame)
{
break;
}
@@ -431,6 +463,8 @@ internal class D3D12ResourceDatabase : IResourceDatabase
{
record.Release(_descriptorAllocator);
}
_resources.Clear();
}
public void Dispose()