fix(rendering): bound portal resource lifetime

Separate logical ownership, render publication, and GPU retirement across live entities, landblocks, particles, textures, mesh arenas, portal/UI teardown, and per-frame scratch storage. Add bounded DAT/texture caches, upload budgets, three-frame fence retirement, exact-incarnation appearance reconciliation, frame pacing, and extensive lifetime conformance coverage.\n\nThe seven-destination connected route now cuts peak working/private memory roughly in half, returns Caul to 125-153 FPS locally, and produces no WER or AMD reset.\n\nCo-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-18 21:35:16 +02:00
parent 3971997689
commit 749e8ceeb1
225 changed files with 29107 additions and 3914 deletions

View file

@ -0,0 +1,55 @@
namespace AcDream.App.Rendering.Wb;
/// <summary>
/// Owns the physical layer slots in one texture array. A released texture
/// remains rented until the GPU-retirement callback returns its layer, so
/// <see cref="AvailableCount"/> never advertises a CPU-unreferenced layer
/// that an in-flight draw may still sample.
/// </summary>
internal sealed class TextureAtlasSlotAllocator
{
private readonly bool[] _rented;
private readonly Stack<int> _returned = new();
private int _next;
public TextureAtlasSlotAllocator(int capacity)
{
ArgumentOutOfRangeException.ThrowIfLessThan(capacity, 1);
_rented = new bool[capacity];
}
public int AvailableCount => _returned.Count + (_rented.Length - _next);
public int Rent()
{
int slot;
if (_returned.Count != 0)
{
slot = _returned.Pop();
}
else
{
if (_next == _rented.Length)
throw new InvalidOperationException(
$"Texture atlas has no GPU-safe layer available ({_rented.Length} layers)."
);
slot = _next++;
}
if (_rented[slot])
throw new InvalidOperationException($"Texture atlas layer {slot} was rented twice.");
_rented[slot] = true;
return slot;
}
public void Return(int slot)
{
ArgumentOutOfRangeException.ThrowIfNegative(slot);
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(slot, _next);
if (!_rented[slot])
throw new InvalidOperationException($"Texture atlas layer {slot} was returned twice.");
_rented[slot] = false;
_returned.Push(slot);
}
}