fix(rendering): match empty packed submissions

The production dispatcher forces transparent deferral off when no top-level VAO was resolved, even if the frame alpha queue is active. Carry the same per-draw VAO sentinel into the compare-only packed classifier so its empty-submission state is exact rather than sampling only the later queue state.
This commit is contained in:
Erik 2026-07-25 01:48:02 +02:00
parent 29195fb255
commit 06e7754619
2 changed files with 43 additions and 4 deletions

View file

@ -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<RenderFrameMeshPart> meshParts)
ReadOnlySpan<RenderFrameMeshPart> 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
}
}
/// <summary>
/// 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.
/// </summary>
internal static bool ShouldDeferPackedTransparent(
uint anyVao,
bool alphaQueueCollecting) =>
anyVao != 0 && alphaQueueCollecting;
private float PackedPartOpacity(
uint localEntityId,
uint setupPartIndex)

View file

@ -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));
}
}