feat(rendering): prove packed dispatcher output parity

Build a compare-only dispatcher classifier from RenderFrameView and compare complete opaque, alpha, selection, clip, light, texture, transform, and draw payloads against the accepted path. Preserve retail's stable equal-CYpt ordering with explicit draw-local submission ordinals so material-group history cannot affect alpha ties.
This commit is contained in:
Erik 2026-07-25 01:31:56 +02:00
parent 58b712c6ec
commit 29195fb255
11 changed files with 1264 additions and 65 deletions

View file

@ -61,6 +61,9 @@ internal readonly record struct CurrentRenderDispatcherSubmission(
int OpaqueGroupCount,
int TransparentGroupCount,
bool TransparentDeferred,
RenderSceneHash128 OpaqueDigest,
RenderSceneHash128 TransparentDigest,
RenderSceneHash128 TransparentSetDigest,
RenderSceneHash128 Digest);
internal readonly record struct CurrentRenderSelectionFingerprint(
@ -209,6 +212,8 @@ internal sealed class CurrentRenderSceneOracle :
_pviewCandidates = [];
private readonly List<CurrentRenderDispatcherFingerprint>
_dispatcherCandidates = [];
private readonly List<CurrentRenderDispatcherSubmission>
_dispatcherSubmissions = [];
private readonly Dictionary<WorldEntity, CurrentRenderProjectionFingerprint>
_dispatcherProjectionByEntity =
new(ReferenceEqualityComparer.Instance);
@ -249,6 +254,8 @@ internal sealed class CurrentRenderSceneOracle :
PViewCandidates => _pviewCandidates;
internal IReadOnlyList<CurrentRenderDispatcherFingerprint>
DispatcherCandidates => _dispatcherCandidates;
internal IReadOnlyList<CurrentRenderDispatcherSubmission>
DispatcherSubmissions => _dispatcherSubmissions;
internal IReadOnlyList<CurrentRenderSelectionFingerprint>
SelectionParts => _selectionParts;
@ -470,6 +477,7 @@ internal sealed class CurrentRenderSceneOracle :
{
_dispatcherFrameOpen = true;
_dispatcherCandidates.Clear();
_dispatcherSubmissions.Clear();
_dispatcherProjectionByEntity.Clear();
_dispatcherDrawCount = 0;
_dispatcherEntityCount = 0;
@ -589,6 +597,7 @@ internal sealed class CurrentRenderSceneOracle :
_dispatcherInstanceCount = checked(
_dispatcherInstanceCount + submission.VisibleInstanceCount);
_dispatcherSubmissions.Add(submission);
_dispatcherOpaqueGroupCount = checked(
_dispatcherOpaqueGroupCount + submission.OpaqueGroupCount);
_dispatcherTransparentGroupCount = checked(
@ -621,6 +630,7 @@ internal sealed class CurrentRenderSceneOracle :
_dispatcherFrameOpen = false;
_dispatcherCandidates.Clear();
_dispatcherSubmissions.Clear();
_dispatcherProjectionByEntity.Clear();
_abortedDispatcherFrames = checked(_abortedDispatcherFrames + 1);
Snapshot = Snapshot with
@ -862,7 +872,7 @@ internal sealed class CurrentRenderSceneOracle :
return geometry.Finish();
}
private static RenderSceneHash128 FingerprintSelectionGeometry(
internal static RenderSceneHash128 FingerprintSelectionGeometry(
RetailSelectionMesh mesh)
{
StableRenderHash128 geometry = StableRenderHash128.Create();