Ingest field evidence in renderer

This commit is contained in:
Meta Vens 2026-05-26 14:56:54 +01:00
commit 95a67a9be7
2 changed files with 39 additions and 0 deletions

View file

@ -217,6 +217,9 @@ public sealed class D3D12Renderer : IAquariumRenderer
private AquariumPackedTextureSplineFieldProgram[] activeTextureSplinePrograms = [];
private float[] activeTextureFieldSamples = [];
private AquariumSplineFrame activeSplineFrame = AquariumSplineFrame.Empty;
private AquariumFieldEvidenceFrame activeFieldEvidenceFrame = AquariumFieldEvidenceFrame.Empty;
private AquariumFieldEvidenceValidationReport activeFieldEvidenceValidation = AquariumFieldEvidenceValidationReport.Empty;
private AquariumFieldLoweringPlan activeFieldLoweringPlan = AquariumFieldLoweringPlan.Empty;
private Viewport viewport;
private RawRect scissorRect;
private int width;
@ -446,6 +449,8 @@ public sealed class D3D12Renderer : IAquariumRenderer
.Slider("Exposure", () => settings.SceneExposure, value => settings = (settings with { SceneExposure = Math.Clamp(value, GraphicsSettings.MinSceneExposure, GraphicsSettings.MaxSceneExposure) }).Normalized(), GraphicsSettings.MinSceneExposure, GraphicsSettings.MaxSceneExposure, "0.###", "Manual scene exposure before display transform.", () => activeDebugTab == 0)
.Slider("Bloom Intensity", () => settings.BloomIntensity, value => settings = (settings with { BloomIntensity = Math.Clamp(value, GraphicsSettings.MinBloomIntensity, GraphicsSettings.MaxBloomIntensity) }).Normalized(), GraphicsSettings.MinBloomIntensity, GraphicsSettings.MaxBloomIntensity, "0.###", "Strength of pre-tonemap bloom energy.", () => activeDebugTab == 0)
.Slider("Bloom Veil", () => settings.BloomVeilIntensity, value => settings = (settings with { BloomVeilIntensity = Math.Clamp(value, GraphicsSettings.MinBloomVeilIntensity, GraphicsSettings.MaxBloomVeilIntensity) }).Normalized(), GraphicsSettings.MinBloomVeilIntensity, GraphicsSettings.MaxBloomVeilIntensity, "0.###", "Low-frequency veil from bright HDR energy.", () => activeDebugTab == 0)
.Section("Field Evidence", () => activeDebugTab == 0)
.Readout("Field Evidence", FieldEvidenceDebugSummary, "Current field-evidence contract counts.", () => activeDebugTab == 0)
.Section("Terminal", () => activeDebugTab == 1)
.TextBox("", TerminalDisplay, UpdateTerminalInputFromDisplay, lines: 8, acceptsReturn: false, submit: ExecuteTerminalInput, monospace: true, alignBottom: true, tooltip: "Terminal log with live command prompt.", isVisible: () => activeDebugTab == 1)
.Section("Synth Playground", () => activeDebugTab == 2)
@ -482,6 +487,20 @@ public sealed class D3D12Renderer : IAquariumRenderer
return string.Join('\n', terminalLines.TakeLast(10).Append($"> {terminalInput}"));
}
private string FieldEvidenceDebugSummary()
{
if (!activeFieldEvidenceFrame.HasInput)
{
return "none";
}
var errorCount = activeFieldEvidenceValidation.Issues.Count(issue => issue.Severity == AquariumFieldEvidenceIssueSeverity.Error);
return
$"domains {activeFieldEvidenceFrame.Domains.Count} / claims {activeFieldEvidenceFrame.Claims.Count} / " +
$"candidates {activeFieldEvidenceFrame.Candidates.Count} / packets {activeFieldEvidenceFrame.BackendPackets.Count} / " +
$"planned {activeFieldLoweringPlan.Packets.Count} / deferred {activeFieldLoweringPlan.DeferredRequests.Count} / errors {errorCount}";
}
private void UpdateTerminalInputFromDisplay(string value)
{
if (value.EndsWith("\n>", StringComparison.Ordinal) || string.Equals(value, ">", StringComparison.Ordinal))
@ -2271,6 +2290,13 @@ public sealed class D3D12Renderer : IAquariumRenderer
activeSplineFrame = MergeSplineFrames(
scene.SplineFrame.HasInput ? scene.SplineFrame : AquariumSplineFrame.Empty,
BuildTextureSplineFrame(activeBufferFieldFrame, bufferFieldUsesReservoir));
activeFieldEvidenceFrame = scene.FieldEvidenceFrame.HasInput
? scene.FieldEvidenceFrame
: AquariumFieldEvidenceFrame.Empty;
activeFieldEvidenceValidation = AquariumFieldEvidenceValidator.Validate(activeFieldEvidenceFrame);
activeFieldLoweringPlan = activeFieldEvidenceValidation.HasErrors
? AquariumFieldLoweringPlan.Empty
: AquariumFieldLoweringPlanner.Plan(activeFieldEvidenceFrame);
activeFractalProgramTransforms = activeFractalReservoirField.HasInput && scene.FractalReservoirField.ProgramTransforms.Count > 0
? scene.FractalReservoirField.ProgramTransforms as AquariumPackedFractalIfsTransform[] ?? scene.FractalReservoirField.ProgramTransforms.ToArray()
: [];
@ -2749,6 +2775,18 @@ public sealed class D3D12Renderer : IAquariumRenderer
$"resident {residentBytes / (1024.0 * 1024.0):0.0} MiB");
}
if (activeFieldEvidenceFrame.HasInput)
{
Console.WriteLine(
$"D3D12 field evidence: domains {activeFieldEvidenceFrame.Domains.Count:N0}; " +
$"claims {activeFieldEvidenceFrame.Claims.Count:N0}; " +
$"candidates {activeFieldEvidenceFrame.Candidates.Count:N0}; " +
$"producer packets {activeFieldEvidenceFrame.BackendPackets.Count:N0}; " +
$"planned packets {activeFieldLoweringPlan.Packets.Count:N0}; " +
$"deferred {activeFieldLoweringPlan.DeferredRequests.Count:N0}; " +
$"issues {activeFieldEvidenceValidation.Issues.Count:N0}");
}
if (accumulatedTimingFrames > 0)
{
var scale = 1.0 / accumulatedTimingFrames;

View file

@ -231,3 +231,4 @@
{"lesson":"AquariumFieldEvidenceValidator now gives the field-evidence contract a falsification seam before backend lowering. It rejects missing domain/claim identity, inverted domains, unknown claim/domain references, invalid support/proposal, non-selectable candidates, and backend packets that cannot write reusable evidence. This keeps pixel-only/debug paths from silently becoming production field authority. dotnet test tests/Aquarium.Engine.Tests/Aquarium.Engine.Tests.csproj --no-restore passed with 10 tests.","timestamp":"2026-05-26T14:06:00+01:00","files":["src/Aquarium.Engine.Contracts/Render/AquariumFieldEvidence.cs","tests/Aquarium.Engine.Tests/FieldEvidenceContractTests.cs"],"source":"continued rendering rebuild Phase 1","topic":"field-evidence-validation"}
{"lesson":"AquariumFieldEvidenceNormalizer now builds pending lowering requests from valid claims and candidates without choosing a backend. This preserves the rebuild membrane: Mimir and other producers may publish field evidence and surface intent, while Fensalir later selects direct SDF, mesh, splat, page, tube, or debug lowerings. Invalid evidence yields no lowering requests. dotnet test tests/Aquarium.Engine.Tests/Aquarium.Engine.Tests.csproj --no-restore passed with 12 tests, and both Fensalir.sln and Mimir.slnx built cleanly.","timestamp":"2026-05-26T14:23:00+01:00","files":["src/Aquarium.Engine.Contracts/Render/AquariumFieldEvidence.cs","tests/Aquarium.Engine.Tests/FieldEvidenceContractTests.cs"],"source":"continued rendering rebuild Phase 1","topic":"field-evidence-normalizer"}
{"lesson":"AquariumFieldLoweringPlanner now converts pending lowering requests into backend packets only for unambiguous encodings: height/SDF2D to surface pages, SDF3D to direct SDF, density/extinction to volume splats, tube to tube field, and mesh to mesh. Ambiguous feature/confidence/material-style evidence is deferred instead of guessed. This keeps backend selection in Fensalir while avoiding new hidden policy. Engine tests passed with 14 tests; Fensalir.sln built cleanly, and Mimir.slnx still builds against the contract.","timestamp":"2026-05-26T14:42:00+01:00","files":["src/Aquarium.Engine.Contracts/Render/AquariumFieldEvidence.cs","tests/Aquarium.Engine.Tests/FieldEvidenceContractTests.cs"],"source":"continued rendering rebuild Phase 1","topic":"field-evidence-lowering-planner"}
{"lesson":"D3D12Renderer now consumes AquariumSceneState.FieldEvidenceFrame at the renderer boundary as planning telemetry. Each frame validates field evidence, builds the conservative backend-lowering plan, and exposes counts for domains, claims, candidates, producer packets, planned packets, deferred requests, and validation issues in debug/console. It does not render these packets yet, preserving the migration order. Fensalir.sln builds cleanly and Mimir.slnx builds against the integrated path.","timestamp":"2026-05-26T15:02:00+01:00","files":["src/Aquarium.Engine/Render/D3D12Renderer.cs"],"source":"continued rendering rebuild Phase 1","topic":"renderer-field-evidence-ingest"}