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

@ -46,7 +46,7 @@ Copy this block when adding a new issue:
## #225 — Scene particles overpaint translucent world objects
**Status:** IN-PROGRESS — implementation complete; connected visual gate pending
**Status:** IN-PROGRESS — implementation/reviews and connected stress gate pass; final visual gate pending
**Severity:** MEDIUM
**Filed:** 2026-07-18
**Component:** rendering / world translucency / particles
@ -79,7 +79,7 @@ order inside one instanced draw, with only DAT blend-mode changes splitting a
run. The identical location recovered to about 153 FPS / 6.6 ms in the
connected Release client.
A second, genuinely cumulative portal regression remained: ACE retains
A second, genuinely cumulative portal regression was first isolated: ACE retains
`KnownObjects` across normal teleports, while acdream retained every old
`LiveEntityRecord` indefinitely. Each destination therefore left animation,
effect, and render owners active; after enough trips the render thread blocked
@ -93,6 +93,30 @@ duplicating vertices per material and growing forever. A connected five-region
round trip returned live/animation ownership to baseline, recreated C95B on
revisit, and held its normal 6080 FPS.
That shorter route did not close the process-lifetime problem. A subsequent
multi-recall run still climbed to about 3.0 GiB working set / 3.5 GiB private
memory and reproduced the 512 FPS collapse, with effect emitters, composite
textures, decoded DAT objects, texture atlases, and physical GL stores remaining
resident after their owners left. The final integration therefore makes the
whole chain owner-scoped and bounded: exact-incarnation appearance replacement,
retryable live/landblock/UI/portal teardown, emitter retirement indexes,
bounded DAT/decoded/standalone/composite caches, reclaimable mesh/atlas storage,
incremental arena migration, and three-frame GPU-fenced physical reuse. It also
reuses per-frame scratch storage without clearing a legitimate large working set.
No draw distance, texture resolution, particle range, or visual effect was
reduced.
The final connected route (Caul → Sawato → Rynthid → Aerlinthe → Sawato →
Holtburg → Caul, with 2530 second destination dwells and 60 seconds after the
return) passed without an exception, WER report, or AMD display-driver reset.
Peak working set fell from 2,954.5 MiB to 1,493.4 MiB and peak private memory
from 3,502.3 MiB to 1,969.5 MiB versus the failing build. Returned Caul settled
at 1,030.6 MiB working set / 1,638.2 MiB private / 831.6 MiB local GPU; the final
local-display dwell held 125153 FPS (141.8 average). Emitter/binding ownership
balanced at 1,715/1,715 and composite physical residency remained below its
128 MiB ceiling. The older 32 FPS comparison run was RDP-refresh-capped and is
used only for memory comparison. The lifestone/particle visual gate remains.
**Files:** `src/AcDream.App/Rendering/RetailAlphaQueue.cs`;
`src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs`;
`src/AcDream.App/Rendering/ParticleRenderer.cs`;
@ -100,11 +124,17 @@ revisit, and held its normal 6080 FPS.
`src/AcDream.App/Rendering/Shaders/particle.frag`;
`src/AcDream.App/Rendering/RetailPViewRenderer.cs`;
`src/AcDream.App/World/LiveEntityLivenessController.cs`;
`src/AcDream.App/Rendering/Wb/GlobalMeshBuffer.cs`.
`src/AcDream.App/Rendering/Wb/GlobalMeshBuffer.cs`;
`src/AcDream.App/Rendering/GpuFrameFlightController.cs`;
`src/AcDream.App/Rendering/CompositeTextureArrayCache.cs`;
`src/AcDream.App/Rendering/StandaloneBindlessTextureCache.cs`;
`src/AcDream.Content/BoundedDatObjectCache.cs`;
`src/AcDream.Content/DecodedTextureCache.cs`.
**Research:**
`docs/research/2026-07-18-retail-shared-alpha-list-pseudocode.md`;
`docs/research/2026-07-18-retail-object-liveness-and-mesh-reclamation-pseudocode.md`.
`docs/research/2026-07-18-retail-object-liveness-and-mesh-reclamation-pseudocode.md`;
`docs/research/2026-07-18-retail-texture-resource-lifetime-pseudocode.md`.
**Acceptance:** At a translucent lifestone, smoke or flame behind the crystal
is attenuated by it while an effect in front remains bright. The lifestone's