feat(rendering): pack scene dispatcher inputs

Capture immutable presentation payloads in the render scene, flatten unique entity and mesh-part records into the borrowed frame arena, and compare every routed dispatcher input tuple without changing the production draw source.
This commit is contained in:
Erik 2026-07-25 00:44:58 +02:00
parent 720578592b
commit d8d9897376
13 changed files with 593 additions and 24 deletions

View file

@ -2,6 +2,7 @@ using System.Numerics;
using AcDream.App.Rendering;
using AcDream.App.Rendering.Scene;
using AcDream.App.Rendering.Scene.Arch;
using AcDream.App.Rendering.Wb;
using AcDream.Core.World;
namespace AcDream.App.Tests.Rendering;
@ -81,6 +82,7 @@ public sealed class RenderScenePViewFrameProductTests
[],
[Cell],
EmptyCellSource.Instance,
[],
RootIsOutdoor: true);
builder.Build(exchange, frameSequence: 1, in input);
@ -115,8 +117,12 @@ public sealed class RenderScenePViewFrameProductTests
AlphaClassificationCount: 0,
LightSetCount: 0,
SelectionPartCount: 0,
RouteCandidateCount: 5),
RouteCandidateCount: 5,
EntityCandidateCount: 5,
MeshPartCount: 5),
view.DiagnosticCounts);
Assert.Equal(5, view.EntityCandidates.Length);
Assert.Equal(5, view.MeshParts.Length);
Assert.Same(portal, view.PortalFrame);
Assert.Same(clip, view.ClipAssembly);
Assert.Equal(digest, view.SourceDigest);
@ -162,6 +168,22 @@ public sealed class RenderScenePViewFrameProductTests
0,
[outdoorDynamic, cellDynamic]);
oracle.CompletePViewFrame();
oracle.BeginDispatcherFrame();
oracle.ObserveDispatcherDraw(
WbDrawDispatcher.EntitySet.All,
entitiesWalked: 1,
[(outdoor, 0, Landblock)]);
oracle.ObserveDispatcherDraw(
WbDrawDispatcher.EntitySet.All,
entitiesWalked: 1,
[(cellStatic, 0, Landblock)]);
oracle.ObserveDispatcherDraw(
WbDrawDispatcher.EntitySet.All,
entitiesWalked: 2,
[
(outdoorDynamic, 0, Landblock),
(cellDynamic, 0, Landblock),
]);
using var shadow = new RenderSceneShadowRuntime(Generation);
foreach (WorldEntity entity in entities)
@ -187,6 +209,8 @@ public sealed class RenderScenePViewFrameProductTests
[],
[Cell],
EmptyCellSource.Instance,
[],
Landblock,
rootIsOutdoor: true);
RenderFrameProductComparisonSnapshot matched = controller.Snapshot;
@ -198,6 +222,15 @@ public sealed class RenderScenePViewFrameProductTests
Assert.Equal(0, matched.MismatchCount);
Assert.Null(matched.FirstMismatch);
Assert.Equal(matched.ExpectedDigest, matched.ActualDigest);
Assert.Equal(1uL, matched.PackedInputComparisonCount);
Assert.Equal(1uL, matched.PackedInputSuccessfulComparisonCount);
Assert.Equal(4, matched.PackedInputExpectedCount);
Assert.Equal(4, matched.PackedInputActualCount);
Assert.Equal(0, matched.PackedInputMismatchCount);
Assert.Null(matched.PackedInputFirstMismatch);
Assert.Equal(
matched.PackedInputExpectedDigest,
matched.PackedInputActualDigest);
Assert.Empty(logs);
RenderProjectionId withdrawnId =
@ -213,6 +246,8 @@ public sealed class RenderScenePViewFrameProductTests
[],
[Cell],
EmptyCellSource.Instance,
[],
Landblock,
rootIsOutdoor: true);
RenderFrameProductComparisonSnapshot mismatch = controller.Snapshot;
@ -220,7 +255,11 @@ public sealed class RenderScenePViewFrameProductTests
Assert.Equal(1uL, mismatch.SuccessfulComparisonCount);
Assert.Equal(1, mismatch.MismatchCount);
Assert.Contains("field=count expected=4 actual=3", mismatch.FirstMismatch);
Assert.Single(logs);
Assert.Equal(1, mismatch.PackedInputMismatchCount);
Assert.Contains(
"field=count expected=4 actual=3",
mismatch.PackedInputFirstMismatch);
Assert.Equal(2, logs.Count);
}
private static RenderProjectionRecord Project(WorldEntity entity)
@ -286,7 +325,11 @@ public sealed class RenderScenePViewFrameProductTests
BuildingShellAnchorCellId: 0,
TransformFingerprint: default,
GeometryFingerprint: default,
AppearanceFingerprint: default));
AppearanceFingerprint: default),
new RenderEntityPayload(
[new MeshRef((uint)id, Matrix4x4.Identity)],
PaletteOverride: null,
IsBuildingShell: false));
}
private static WorldEntity Entity(