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,30 @@
namespace AcDream.App.Rendering;
/// <summary>
/// Capacity policy for render-thread-owned streaming GPU buffers. Dynamic
/// buffers keep one backing allocation and update its active prefix; they do
/// not orphan a new driver allocation on every draw call.
/// </summary>
internal static class DynamicBufferCapacity
{
internal const int DefaultAlignment = 4096;
public static int Grow(int currentBytes, int requiredBytes, int alignment = DefaultAlignment)
{
if (currentBytes < 0)
throw new ArgumentOutOfRangeException(nameof(currentBytes));
if (requiredBytes < 0)
throw new ArgumentOutOfRangeException(nameof(requiredBytes));
if (alignment <= 0)
throw new ArgumentOutOfRangeException(nameof(alignment));
if (requiredBytes <= currentBytes)
return currentBytes;
long doubled = currentBytes == 0 ? alignment : (long)currentBytes * 2L;
long target = Math.Max(requiredBytes, doubled);
long aligned = ((target + alignment - 1L) / alignment) * alignment;
if (aligned > int.MaxValue)
throw new OverflowException("Dynamic GPU buffer capacity exceeds Int32.MaxValue.");
return (int)aligned;
}
}