diff --git a/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.PackedOracle.cs b/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.PackedOracle.cs index 93cded25..c5634063 100644 --- a/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.PackedOracle.cs +++ b/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.PackedOracle.cs @@ -85,6 +85,7 @@ public sealed unsafe partial class WbDrawDispatcher rangeIndex++) { _nextPackedInstanceSubmissionOrder = 0; + uint anyVao = 0; foreach (InstanceGroup group in _packedGroups.Values) group.ClearPerInstanceData(); @@ -134,11 +135,13 @@ public sealed unsafe partial class WbDrawDispatcher in candidate, meshParts.Slice( source.MeshPartOffset, - source.MeshPartCount)); + source.MeshPartCount), + ref anyVao); } - bool deferTransparent = - _alphaQueue?.IsCollecting == true; + bool deferTransparent = ShouldDeferPackedTransparent( + anyVao, + _alphaQueue?.IsCollecting == true); InstanceLayoutCounts counts = PartitionInstanceGroups( _packedGroups.Values, deferTransparent, @@ -165,7 +168,8 @@ public sealed unsafe partial class WbDrawDispatcher private void ClassifyPackedEntity( in RenderInstanceCandidate entity, - ReadOnlySpan meshParts) + ReadOnlySpan meshParts, + ref uint anyVao) { (uint slot, bool culled) = ResolveSlotForFrame( _clipRoutingActive, @@ -216,6 +220,8 @@ public sealed unsafe partial class WbDrawDispatcher _meshAdapter.TryGetRenderData(meshRef.GfxObjId); if (renderData is null) continue; + if (anyVao == 0) + anyVao = renderData.VAO; if (renderData.IsSetup && renderData.SetupParts.Count > 0) @@ -291,6 +297,16 @@ public sealed unsafe partial class WbDrawDispatcher } } + /// + /// Mirrors the production dispatcher's no-VAO early return. That return + /// records an empty submission with transparent deferral disabled even + /// when the frame alpha queue is collecting. + /// + internal static bool ShouldDeferPackedTransparent( + uint anyVao, + bool alphaQueueCollecting) => + anyVao != 0 && alphaQueueCollecting; + private float PackedPartOpacity( uint localEntityId, uint setupPartIndex) diff --git a/tests/AcDream.App.Tests/Rendering/Wb/PackedDispatcherOracleTests.cs b/tests/AcDream.App.Tests/Rendering/Wb/PackedDispatcherOracleTests.cs new file mode 100644 index 00000000..3fc4df8f --- /dev/null +++ b/tests/AcDream.App.Tests/Rendering/Wb/PackedDispatcherOracleTests.cs @@ -0,0 +1,23 @@ +using AcDream.App.Rendering.Wb; + +namespace AcDream.App.Tests.Rendering.Wb; + +public sealed class PackedDispatcherOracleTests +{ + [Theory] + [InlineData(0u, false, false)] + [InlineData(0u, true, false)] + [InlineData(7u, false, false)] + [InlineData(7u, true, true)] + public void TransparentDeferral_MatchesProductionNoVaoEarlyReturn( + uint anyVao, + bool alphaQueueCollecting, + bool expected) + { + Assert.Equal( + expected, + WbDrawDispatcher.ShouldDeferPackedTransparent( + anyVao, + alphaQueueCollecting)); + } +}