Align URP pass queue to single camera snapshot

This commit is contained in:
2026-04-27 22:38:56 +08:00
parent 520413fa0d
commit eaa90d835f
9 changed files with 104 additions and 255 deletions

View File

@@ -17,66 +17,24 @@ namespace XCEngine.Rendering.Universal
public bool finalOutput;
}
private sealed class PassQueueStageSnapshot
{
public PassQueueStageSnapshot(
CameraFrameStage stage,
List<ScriptableRenderPass> activePassQueue,
RendererBlocks rendererBlocks)
{
this.stage = stage;
this.activePassQueue =
activePassQueue ??
new List<ScriptableRenderPass>();
this.rendererBlocks =
rendererBlocks ?? new RendererBlocks();
}
public readonly CameraFrameStage stage;
public readonly List<ScriptableRenderPass> activePassQueue;
public readonly RendererBlocks rendererBlocks;
}
private sealed class PassQueueFrameSnapshot
{
private readonly Dictionary<
CameraFrameStage,
PassQueueStageSnapshot> m_stageSnapshots =
new Dictionary<
CameraFrameStage,
PassQueueStageSnapshot>();
public PassQueueFrameSnapshot(
ulong framePlanId,
int rendererIndex)
int rendererIndex,
List<ScriptableRenderPass> activePassQueue)
{
this.framePlanId = framePlanId;
this.rendererIndex = rendererIndex;
this.activePassQueue =
activePassQueue ??
new List<ScriptableRenderPass>();
}
public readonly ulong framePlanId;
public readonly int rendererIndex;
public readonly List<ScriptableRenderPass> activePassQueue;
public PassQueueStageManifest manifest;
public void SetStageSnapshot(
PassQueueStageSnapshot snapshot)
{
if (snapshot == null)
{
return;
}
m_stageSnapshots[snapshot.stage] = snapshot;
}
public bool TryGetStageSnapshot(
CameraFrameStage stage,
out PassQueueStageSnapshot snapshot)
{
return m_stageSnapshots.TryGetValue(
stage,
out snapshot);
}
}
private readonly List<ScriptableRendererFeature> m_features =
@@ -90,9 +48,6 @@ namespace XCEngine.Rendering.Universal
new Dictionary<ulong, PassQueueFrameSnapshot>();
private readonly CommandBuffer m_finishCameraStackCommandBuffer =
new CommandBuffer("ScriptableRenderer.FinishCameraStack");
private bool m_isBuildingPassQueue;
private CameraFrameStage m_passQueueStage =
CameraFrameStage.MainScene;
private bool m_disposed;
protected ScriptableRenderer()
@@ -132,12 +87,6 @@ namespace XCEngine.Rendering.Universal
return;
}
if (m_isBuildingPassQueue &&
!renderPass.SupportsStage(m_passQueueStage))
{
return;
}
InsertActivePass(
renderPass);
}
@@ -246,8 +195,8 @@ namespace XCEngine.Rendering.Universal
RenderingData renderingData =
context.renderingData;
PassQueueStageSnapshot snapshot;
if (TryGetPassQueueStageSnapshot(
PassQueueFrameSnapshot snapshot;
if (TryGetPassQueueFrameSnapshot(
context,
out snapshot))
{
@@ -283,8 +232,8 @@ namespace XCEngine.Rendering.Universal
RenderingData renderingData =
context.renderingData;
PassQueueStageSnapshot snapshot;
if (TryGetPassQueueStageSnapshot(
PassQueueFrameSnapshot snapshot;
if (TryGetPassQueueFrameSnapshot(
context,
out snapshot))
{
@@ -481,101 +430,40 @@ namespace XCEngine.Rendering.Universal
int rendererIndex = context.rendererIndex;
ulong framePlanId = context.framePlanId;
PassQueueFrameSnapshot snapshot =
new PassQueueFrameSnapshot(
framePlanId,
rendererIndex);
snapshot.SetStageSnapshot(
BuildPassQueueStageSnapshot(
CameraFrameStage.ShadowCaster,
rendererIndex,
finalColorRequiresProcessing,
framePlanId));
snapshot.SetStageSnapshot(
BuildPassQueueStageSnapshot(
CameraFrameStage.DepthOnly,
rendererIndex,
finalColorRequiresProcessing,
framePlanId));
snapshot.SetStageSnapshot(
BuildPassQueueStageSnapshot(
CameraFrameStage.MainScene,
rendererIndex,
finalColorRequiresProcessing,
framePlanId));
snapshot.SetStageSnapshot(
BuildPassQueueStageSnapshot(
CameraFrameStage.PostProcess,
rendererIndex,
finalColorRequiresProcessing,
framePlanId));
snapshot.SetStageSnapshot(
BuildPassQueueStageSnapshot(
CameraFrameStage.FinalOutput,
rendererIndex,
finalColorRequiresProcessing,
framePlanId));
PassQueueStageSnapshot stageSnapshot;
snapshot.manifest = new PassQueueStageManifest
{
shadowCaster =
snapshot.TryGetStageSnapshot(
CameraFrameStage.ShadowCaster,
out stageSnapshot) &&
HasRendererStageBlocks(
CameraFrameStage.ShadowCaster,
stageSnapshot.rendererBlocks),
depthOnly =
snapshot.TryGetStageSnapshot(
CameraFrameStage.DepthOnly,
out stageSnapshot) &&
HasRendererStageBlocks(
CameraFrameStage.DepthOnly,
stageSnapshot.rendererBlocks),
postProcess =
snapshot.TryGetStageSnapshot(
CameraFrameStage.PostProcess,
out stageSnapshot) &&
HasRendererStageBlocks(
CameraFrameStage.PostProcess,
stageSnapshot.rendererBlocks),
finalOutput =
snapshot.TryGetStageSnapshot(
CameraFrameStage.FinalOutput,
out stageSnapshot) &&
HasRendererStageBlocks(
CameraFrameStage.FinalOutput,
stageSnapshot.rendererBlocks)
};
return snapshot;
}
private PassQueueStageSnapshot BuildPassQueueStageSnapshot(
CameraFrameStage stage,
int rendererIndex,
bool finalColorRequiresProcessing,
ulong framePlanId)
{
BuildPassQueue(
RenderingData.CreatePlanning(
stage,
rendererIndex,
finalColorRequiresProcessing,
framePlanId));
List<ScriptableRenderPass> activePassQueue =
new List<ScriptableRenderPass>(
m_activePassQueue);
RendererBlocks rendererBlocks =
new RendererBlocks();
rendererBlocks.Build(activePassQueue);
return new PassQueueStageSnapshot(
stage,
activePassQueue,
rendererBlocks);
PassQueueFrameSnapshot snapshot =
new PassQueueFrameSnapshot(
framePlanId,
rendererIndex,
activePassQueue);
snapshot.manifest = new PassQueueStageManifest
{
shadowCaster = HasRendererStageBlocks(
CameraFrameStage.ShadowCaster,
rendererBlocks),
depthOnly = HasRendererStageBlocks(
CameraFrameStage.DepthOnly,
rendererBlocks),
postProcess = HasRendererStageBlocks(
CameraFrameStage.PostProcess,
rendererBlocks),
finalOutput = HasRendererStageBlocks(
CameraFrameStage.FinalOutput,
rendererBlocks)
};
return snapshot;
}
private static void ApplyPassQueueStageManifest(
@@ -863,18 +751,17 @@ namespace XCEngine.Rendering.Universal
snapshot;
}
private bool TryGetPassQueueStageSnapshot(
private bool TryGetPassQueueFrameSnapshot(
RendererRecordingContext context,
out PassQueueStageSnapshot stageSnapshot)
out PassQueueFrameSnapshot frameSnapshot)
{
stageSnapshot = null;
frameSnapshot = null;
if (context == null ||
context.framePlanId == 0UL)
{
return false;
}
PassQueueFrameSnapshot frameSnapshot;
if (!m_framePlanSnapshots.TryGetValue(
context.framePlanId,
out frameSnapshot) ||
@@ -885,16 +772,14 @@ namespace XCEngine.Rendering.Universal
return false;
}
return frameSnapshot.TryGetStageSnapshot(
context.stage,
out stageSnapshot);
return true;
}
private bool SupportsRendererRecordingFromSnapshot(
RendererRecordingContext context,
PassQueueStageSnapshot snapshot)
PassQueueFrameSnapshot snapshot)
{
LoadPassQueueStageSnapshot(snapshot);
LoadPassQueueFrameSnapshot(snapshot);
try
{
return SupportsRendererStage(context);
@@ -907,9 +792,9 @@ namespace XCEngine.Rendering.Universal
private bool RecordRendererFromSnapshot(
RendererRecordingContext context,
PassQueueStageSnapshot snapshot)
PassQueueFrameSnapshot snapshot)
{
LoadPassQueueStageSnapshot(snapshot);
LoadPassQueueFrameSnapshot(snapshot);
try
{
bool recorded;
@@ -936,8 +821,8 @@ namespace XCEngine.Rendering.Universal
}
}
private void LoadPassQueueStageSnapshot(
PassQueueStageSnapshot snapshot)
private void LoadPassQueueFrameSnapshot(
PassQueueFrameSnapshot snapshot)
{
ClearPassQueue();
if (snapshot == null ||
@@ -955,39 +840,25 @@ namespace XCEngine.Rendering.Universal
RenderingData renderingData)
{
ClearPassQueue();
m_isBuildingPassQueue = true;
m_passQueueStage =
renderingData != null
? renderingData.stage
: CameraFrameStage.MainScene;
try
for (int i = 0; i < m_features.Count; ++i)
{
for (int i = 0; i < m_features.Count; ++i)
ScriptableRendererFeature feature = m_features[i];
if (feature == null || !feature.isActive)
{
ScriptableRendererFeature feature = m_features[i];
if (feature == null || !feature.isActive)
{
continue;
}
feature.SetupRenderPasses(
this,
in renderingData);
feature.AddRenderPasses(
this,
ref renderingData);
continue;
}
AddRenderPasses(renderingData);
m_rendererBlocks.Build(m_activePassQueue);
}
finally
{
m_isBuildingPassQueue = false;
m_passQueueStage =
CameraFrameStage.MainScene;
feature.SetupRenderPasses(
this,
in renderingData);
feature.AddRenderPasses(
this,
ref renderingData);
}
AddRenderPasses(renderingData);
m_rendererBlocks.Build(m_activePassQueue);
}
private void ClearPassQueue()