refactor(render): flush alpha at retail walk barriers

This commit is contained in:
Erik 2026-08-31 04:25:34 +02:00
parent 877e935ac4
commit a40a57b9b3
3 changed files with 15 additions and 24 deletions

View file

@ -189,10 +189,8 @@ internal sealed partial class RetailPViewPassExecutor
/// <item><see cref="ClearInteriorDepth"/>/<see cref="DrawExitSeals"/> →
/// caller-supplied actions (the renderer owns the pass scope and the
/// root-flood seal iteration; the adapter only provides the turns).</item>
/// <item><see cref="AlphaBarrier"/> → <c>FlushLandscapeAlphaFartherThan</c>
/// (the <c>DrawBuilding</c> barrier; retail's flush-all
/// <c>FlushAlphaList(0f)</c> @0x0059f30b is the FW4 adjudication
/// candidate recorded on the driver's interface).</item>
/// <item><see cref="AlphaBarrier"/> → <c>FlushLandscapeAlpha</c>, retail's
/// flush-all <c>FlushAlphaList(0f)</c> @0x0059f30b.</item>
/// </list>
/// </summary>
internal sealed class WalkProductionLeafRenderer : IWalkFrameLeafRenderer
@ -257,6 +255,5 @@ internal sealed class WalkProductionLeafRenderer : IWalkFrameLeafRenderer
public void DrawPunchFan(WalkPolygon worldPolygon, int activeViewIndex) =>
_passes.DrawWalkPunchFan(_frame, _clipAssembly, worldPolygon, activeViewIndex);
public void AlphaBarrier(float viewerDistance) =>
_passes.FlushLandscapeAlphaFartherThan(viewerDistance);
public void AlphaBarrier() => _passes.FlushLandscapeAlpha();
}

View file

@ -180,17 +180,11 @@ internal interface IWalkFrameLeafRenderer
/// that view's slice planes.</summary>
void DrawPunchFan(WalkPolygon worldPolygon, int activeViewIndex);
/// <summary><c>RetailAlphaQueue.FlushFartherThan</c>'s <c>DrawBuilding</c>
/// barrier — retail's own call site is
/// <c>D3DPolyRender::FlushAlphaList(0f)</c> @0x0059f30b, a FLUSH-ALL, not
/// a distance-gated flush; this stage keeps the DISPATCHED
/// <c>FlushFartherThan(viewerDistanceTo(building))</c> shape (the two
/// coincide under the walk's far-to-near landscape order, since a nearer
/// emitter has not been inserted into the alpha queue yet — see
/// <c>RetailAlphaQueue.FlushFartherThan</c>'s own doc comment) and flags
/// the 0f/address detail as an FW4 adjudication candidate rather than
/// silently reinterpreting the dispatched design.</summary>
void AlphaBarrier(float viewerDistance);
/// <summary>Retail <c>D3DPolyRender::FlushAlphaList(0f)</c>
/// @0x0059f30b. The walk is positional: only farther cells have submitted
/// alpha when a building turn fires, so this is a full drain with no
/// synthetic viewer-distance threshold.</summary>
void AlphaBarrier();
}
/// <summary>
@ -353,8 +347,8 @@ internal readonly struct WalkFrameEvent
internal static WalkFrameEvent PunchFan(WalkPolygon worldPolygon, int activeViewIndex) =>
new(WalkFrameEventKind.PunchFan, activeViewIndex, 0, 0f, worldPolygon);
internal static WalkFrameEvent AlphaBarrier(float viewerDistance) =>
new(WalkFrameEventKind.AlphaBarrier, 0, 0, viewerDistance, null);
internal static WalkFrameEvent AlphaBarrier() =>
new(WalkFrameEventKind.AlphaBarrier, 0, 0, 0f, null);
internal static WalkFrameEvent LandscapeCellParticles(uint cellId) =>
new(WalkFrameEventKind.StaticParticles, 0, cellId, 0f, null);
@ -711,7 +705,7 @@ internal sealed class WalkFrameDriver : IWalkEventSink, IWalkLookInViewSource
_leafRenderer.DrawPunchFan(e.Polygon!, e.IntArg);
break;
case WalkFrameEventKind.AlphaBarrier:
_leafRenderer.AlphaBarrier(e.FloatArg);
_leafRenderer.AlphaBarrier();
break;
case WalkFrameEventKind.ClearInteriorDepth:
_leafRenderer.ClearInteriorDepth();
@ -840,7 +834,7 @@ internal sealed class WalkFrameDriver : IWalkEventSink, IWalkLookInViewSource
void IWalkEventSink.OnBuildingTurn(WalkBuilding building)
{
ArgumentNullException.ThrowIfNull(building);
IWalkBuildingFrameContext ctx = RequireOpenFrame();
RequireOpenFrame();
VisitedBuildings.Add(building);
// D3DPolyRender::FlushAlphaList(0f) @0x0059f30b — retail's alpha
@ -848,7 +842,7 @@ internal sealed class WalkFrameDriver : IWalkEventSink, IWalkLookInViewSource
// look-ins) follows this call; the building's own shell content is
// appended only once that pass completes (OnBuildingShellTurn).
MarkIfGrown();
_events.Add(WalkFrameEvent.AlphaBarrier(ctx.ViewerDistanceTo(building)));
_events.Add(WalkFrameEvent.AlphaBarrier());
_currentDcStage = WalkDrawStage.LookInStatic;
}