diff --git a/src/Aquarium.Engine/Render/D3D12Renderer.cs b/src/Aquarium.Engine/Render/D3D12Renderer.cs index d4f1806..16d46e8 100644 --- a/src/Aquarium.Engine/Render/D3D12Renderer.cs +++ b/src/Aquarium.Engine/Render/D3D12Renderer.cs @@ -2027,6 +2027,21 @@ public sealed class D3D12Renderer : IAquariumRenderer $"{frameResources.TransientShaderDescriptors.Describe()}; " + $"{staticShaderDescriptorArena.Describe()}; " + $"{renderTargetViewArena.Describe()}"); + if (activeFractalReservoirField.HasInput && fractalSplatBuffer is not null && fractalSdfReservoirBuffer is not null && fractalPbrReservoirBuffer is not null && fractalRadiosityReservoirBuffer is not null) + { + var residentBytes = + fractalSplatBuffer.SizeBytes + + fractalSdfReservoirBuffer.SizeBytes + + fractalPbrReservoirBuffer.SizeBytes + + fractalRadiosityReservoirBuffer.SizeBytes; + Console.WriteLine( + $"D3D12 fractal reservoirs: splats {activeFractalReservoirField.SplatCount:N0}; " + + $"visible {visibleFractalSplatCount:N0}; " + + $"updates/pass {activeFractalReservoirField.ReservoirUpdatesPerPass:N0}; " + + $"candidates/update {activeFractalReservoirField.CandidatesPerReservoirUpdate}; " + + $"resident {residentBytes / (1024.0 * 1024.0):0.0} MiB"); + } + if (accumulatedTimingFrames > 0) { var scale = 1.0 / accumulatedTimingFrames; diff --git a/state/map.yaml b/state/map.yaml index 4227667..d1e3c5e 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -141,6 +141,7 @@ renderer_state: - AquariumSceneState now carries AquariumFractalReservoirField as the narrow client-to-renderer request for GPU-resident fractal reservoirs: resident splat count, IFS depth/seed, candidates per reservoir update, and stochastic updates per pass. This is a budgeted GPU field request, not a CPU splat list. - D3D12Renderer owns the first live fractal reservoir compute hook: a separate root signature, four compute pipelines from D3D12FractalReservoirCompute.hlsl, lazy UAV buffers for splats/SDF/PBR/radiosity reservoirs, a UAV barrier after splat population, and per-frame dispatch when AquariumFractalReservoirField is present. Zyphos requests the 2M-splat, 50k-updates/pass field by default. - The renderer now has a first visible consumption path for computed fractal splats: D3D12FractalSplatRender.hlsl reads the GPU-resident splat buffer as an SRV and draws a capped 131,072-instance debug splat subset into the scene after the reservoir compute update. This is an observability/render-consumption proof, not the final terrain/material/radiosity shading path. + - D3D12 capacity logging now reports active fractal reservoir resident MiB, splat count, visible debug splat count, updates/pass, and candidates/update so the GPU cache has a receipt in normal runtime logs, not just in the standalone benchmark. - The consolidated fractal brush architecture plan defines the intended pipeline: client intent -> domain roots -> semantic IFS brush grammar -> ownership tree -> node summaries -> contribution cache/residency scheduler -> backend packets -> renderer passes -> debug/evidence, with explicit module boundaries and mockable unit-test seams. - The Perfect Machine architecture lives in docs/perfect-machine-architecture.md. It is the current waterfall design authority for fast 2D SDF splats, 3D SDF splats, 2D-projected-to-3D surface splats, IFS `.aquageo` structural probes, Mimir-style camera/audio evidence candidates, ReSTIR/GRIS reservoir reuse, heuristic occupancy graph updates, resource-tier residency, and TAA guide-buffer integration. - Fractal surface page planning now has a CPU boundary: FractalSurfacePagePlanner lowers selected IFS cuts into stable height, 2D signed-distance, material, and confidence page metadata; ZyphosFractalRenderPlan exposes these pages, while the live D3D12 page store and atlas remain future work.