Align Universal renderer ownership with Unity SRP
This commit is contained in:
@@ -45,6 +45,15 @@ The URP object model should be the center of future work:
|
||||
- `ScriptableRenderPipelineAsset` owns pipeline defaults, renderer-data lists,
|
||||
default renderer selection, camera policy, final-color policy, shadow policy,
|
||||
and managed pipeline lifetime.
|
||||
- `UniversalRenderPipelineAsset` is the public URP asset spine. It owns
|
||||
`rendererDataList`, `defaultRendererIndex`, renderer-data synchronization,
|
||||
runtime renderer cache release, camera renderer override resolution, and
|
||||
`UniversalRenderPipeline` creation directly. Do not put another public
|
||||
renderer-backed bridge layer between URP assets and SRP assets.
|
||||
- `UniversalRenderPipeline` is the public URP pipeline object. It should route
|
||||
stage support and stage recording to the selected `ScriptableRenderer`
|
||||
through the owning `UniversalRenderPipelineAsset`, not through XCEngine-only
|
||||
public base classes.
|
||||
- `ScriptableRendererData` is the serialized renderer configuration. It owns
|
||||
renderer feature lists, default feature creation, runtime invalidation, and
|
||||
renderer instance rebuilds.
|
||||
@@ -105,6 +114,10 @@ Guardrails:
|
||||
|
||||
- Do not reintroduce public managed wrappers for native private scene injection
|
||||
points.
|
||||
- Do not reintroduce public managed bridge classes such as
|
||||
`RendererBackedRenderPipelineAsset`, `RendererBackedRenderPipeline`, or
|
||||
`RendererDrivenRenderPipeline`. Renderer-backed behavior belongs inside the
|
||||
Unity-facing URP asset/pipeline pair.
|
||||
- Do not make `RenderPassEvent` or renderer blocks a thin alias for native
|
||||
built-in pass order. They should describe URP scheduling semantics.
|
||||
- Do not add managed APIs that only work by reaching into one built-in native
|
||||
@@ -126,3 +139,8 @@ Guardrails:
|
||||
scope. Public `ContextContainer` state is now shared across renderer passes
|
||||
for the same stage, matching URP's frame-data mental model instead of
|
||||
pass-local scratch data.
|
||||
- Removed the non-Unity public renderer-backed bridge layer from the Universal
|
||||
package. `UniversalRenderPipelineAsset` now derives directly from
|
||||
`ScriptableRenderPipelineAsset`, owns renderer-data selection and runtime
|
||||
resource lifecycle itself, and creates `UniversalRenderPipeline` directly.
|
||||
The deleted bridge types must remain absent from the public API surface.
|
||||
|
||||
@@ -239,11 +239,8 @@ set(XCENGINE_RENDER_PIPELINES_UNIVERSAL_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/RenderPassEvent.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/RenderObjectsRendererFeature.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/RendererBlock.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/RendererBackedRenderPipeline.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/RendererBackedRenderPipelineAsset.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/RendererBlocks.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/RendererCameraRequestContext.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/RendererDrivenRenderPipeline.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/RendererRecordingContext.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/RenderingData.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/RenderingDataResolver.cs
|
||||
|
||||
@@ -1588,30 +1588,6 @@ namespace Gameplay
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class ManagedRendererInvalidationProbePipeline
|
||||
: RendererBackedRenderPipeline
|
||||
{
|
||||
public ManagedRendererInvalidationProbePipeline(
|
||||
RendererBackedRenderPipelineAsset asset)
|
||||
: base(asset)
|
||||
{
|
||||
ManagedRendererInvalidationProbeState
|
||||
.CreatePipelineCallCount++;
|
||||
}
|
||||
|
||||
protected override void Dispose(
|
||||
bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
ManagedRendererInvalidationProbeState
|
||||
.DisposePipelineCallCount++;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class ManagedRendererInvalidationProbeFeature
|
||||
: ScriptableRendererFeature
|
||||
{
|
||||
@@ -2146,6 +2122,35 @@ namespace Gameplay
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class ManagedCameraOverrideRendererSelectionProbeRenderer
|
||||
: ScriptableRenderer
|
||||
{
|
||||
public ManagedCameraOverrideRendererSelectionProbeRenderer()
|
||||
{
|
||||
AddFeature(
|
||||
new FullscreenFeature(
|
||||
new FullscreenPass(
|
||||
RenderPassEvent.BeforeRenderingPostProcessing,
|
||||
BuiltinShaderPaths.ColorScalePostProcess,
|
||||
new Vector4(1.05f, 1.0f, 0.95f, 1.0f),
|
||||
"ManagedCameraOverridePostProcess")));
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class ManagedCameraOverrideRendererSelectionProbeRendererData
|
||||
: ProbeRendererData
|
||||
{
|
||||
public ManagedCameraOverrideRendererSelectionProbeRendererData()
|
||||
: base(false)
|
||||
{
|
||||
}
|
||||
|
||||
protected override ScriptableRenderer CreateProbeRenderer()
|
||||
{
|
||||
return new ManagedCameraOverrideRendererSelectionProbeRenderer();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ManagedCameraOverrideRendererSelectionProbeAsset
|
||||
: UniversalRenderPipelineAsset
|
||||
{
|
||||
@@ -2157,16 +2162,10 @@ namespace Gameplay
|
||||
ProbeScriptableObjectFactory
|
||||
.Create<ManagedRenderPipelineProbeRendererData>(),
|
||||
ProbeScriptableObjectFactory
|
||||
.Create<ManagedRenderPipelineProbeRendererData>());
|
||||
.Create<ManagedCameraOverrideRendererSelectionProbeRendererData>());
|
||||
defaultRendererIndex = 0;
|
||||
}
|
||||
|
||||
protected override ScriptableRenderPipeline
|
||||
CreateRendererBackedPipeline()
|
||||
{
|
||||
return new ManagedCameraOverrideRendererSelectionProbePipeline();
|
||||
}
|
||||
|
||||
protected override void ConfigureCameraFramePlan(
|
||||
ScriptableRenderPipelinePlanningContext context)
|
||||
{
|
||||
@@ -2215,11 +2214,11 @@ namespace Gameplay
|
||||
m_rendererData);
|
||||
}
|
||||
|
||||
protected override ScriptableRenderPipeline
|
||||
CreateRendererBackedPipeline()
|
||||
protected override ScriptableRenderPipeline CreatePipeline()
|
||||
{
|
||||
return new ManagedRendererInvalidationProbePipeline(
|
||||
this);
|
||||
ManagedRendererInvalidationProbeState
|
||||
.CreatePipelineCallCount++;
|
||||
return base.CreatePipeline();
|
||||
}
|
||||
|
||||
public void InvalidateDefaultRendererForTest()
|
||||
@@ -2565,6 +2564,34 @@ namespace Gameplay
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class ManagedUnknownBackendRenderPipelineProbe
|
||||
: ScriptableRenderPipeline
|
||||
{
|
||||
protected override bool SupportsStageRenderGraph(
|
||||
CameraFrameStage stage)
|
||||
{
|
||||
return stage == CameraFrameStage.MainScene;
|
||||
}
|
||||
|
||||
protected override bool RecordStageRenderGraph(
|
||||
ScriptableRenderContext context)
|
||||
{
|
||||
return context != null &&
|
||||
context.DrawOpaqueRenderers() &&
|
||||
context.DrawSkybox() &&
|
||||
context.DrawTransparentRenderers();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ManagedUnknownBackendRenderPipelineProbeAsset
|
||||
: ScriptableRenderPipelineAsset
|
||||
{
|
||||
protected override ScriptableRenderPipeline CreatePipeline()
|
||||
{
|
||||
return new ManagedUnknownBackendRenderPipelineProbe();
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class ManagedMainSceneRasterPassProbePipeline
|
||||
: ScriptableRenderPipeline
|
||||
{
|
||||
@@ -2598,34 +2625,6 @@ namespace Gameplay
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class ManagedCameraOverrideRendererSelectionProbePipeline
|
||||
: ScriptableRenderPipeline
|
||||
{
|
||||
protected override bool SupportsStageRenderGraphContextual(
|
||||
CameraFrameStage stage,
|
||||
int rendererIndex)
|
||||
{
|
||||
return stage == CameraFrameStage.PostProcess &&
|
||||
rendererIndex == 1;
|
||||
}
|
||||
|
||||
protected override bool RecordStageRenderGraph(
|
||||
ScriptableRenderContext context)
|
||||
{
|
||||
return context != null &&
|
||||
context.stage == CameraFrameStage.PostProcess &&
|
||||
context.rendererIndex == 1 &&
|
||||
context
|
||||
.AddRasterPass(
|
||||
"ManagedCameraOverridePostProcess")
|
||||
.SetColorAttachment(
|
||||
context.primaryColorTarget)
|
||||
.SetColorScaleFullscreenExecution(
|
||||
new Vector4(1.05f, 1.0f, 0.95f, 1.0f))
|
||||
.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class ManagedRenderPipelineProbe
|
||||
: ProbeSceneRenderer
|
||||
{
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
using XCEngine;
|
||||
|
||||
namespace XCEngine.Rendering.Universal
|
||||
{
|
||||
public class RendererBackedRenderPipeline
|
||||
: RendererDrivenRenderPipeline
|
||||
{
|
||||
private readonly RendererBackedRenderPipelineAsset m_asset;
|
||||
|
||||
public RendererBackedRenderPipeline(
|
||||
RendererBackedRenderPipelineAsset asset)
|
||||
{
|
||||
m_asset = asset;
|
||||
}
|
||||
|
||||
protected override ScriptableRenderer ResolveRenderer(
|
||||
RendererRecordingContext context)
|
||||
{
|
||||
return m_asset != null
|
||||
? m_asset.ResolveRenderer(
|
||||
context != null
|
||||
? context.rendererIndex
|
||||
: -1)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,299 +0,0 @@
|
||||
using System;
|
||||
using XCEngine;
|
||||
using XCEngine.Rendering;
|
||||
|
||||
namespace XCEngine.Rendering.Universal
|
||||
{
|
||||
public abstract class RendererBackedRenderPipelineAsset
|
||||
: ScriptableRenderPipelineAsset
|
||||
{
|
||||
public ScriptableRendererData[] rendererDataList =
|
||||
Array.Empty<ScriptableRendererData>();
|
||||
public int defaultRendererIndex = 0;
|
||||
private readonly ScriptableRendererDataCollection
|
||||
m_rendererDataCollection;
|
||||
private int m_rendererDataRuntimeStateHash;
|
||||
private bool m_rendererDataRuntimeStateHashResolved;
|
||||
|
||||
protected RendererBackedRenderPipelineAsset()
|
||||
{
|
||||
m_rendererDataCollection =
|
||||
new ScriptableRendererDataCollection();
|
||||
}
|
||||
|
||||
protected override ScriptableRenderPipeline CreatePipeline()
|
||||
{
|
||||
return CreateRendererBackedPipeline();
|
||||
}
|
||||
|
||||
protected override void ConfigureCameraRenderRequest(
|
||||
CameraRenderRequestContext context)
|
||||
{
|
||||
ApplyResolvedRendererIndex(
|
||||
context,
|
||||
ResolveRendererIndex(context));
|
||||
|
||||
ConfigureRendererCameraRequest(
|
||||
new RendererCameraRequestContext(context));
|
||||
|
||||
ApplyResolvedRendererIndex(
|
||||
context,
|
||||
context != null
|
||||
? context.rendererIndex
|
||||
: -1);
|
||||
|
||||
ScriptableRendererData resolvedRendererData =
|
||||
ResolveRendererData(context);
|
||||
if (resolvedRendererData != null)
|
||||
{
|
||||
resolvedRendererData
|
||||
.ConfigureCameraRenderRequestInstance(
|
||||
context);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ConfigureCameraFramePlan(
|
||||
ScriptableRenderPipelinePlanningContext context)
|
||||
{
|
||||
if (UsesExplicitCameraFrameStagePlanning() &&
|
||||
context != null)
|
||||
{
|
||||
// Renderer-backed SRP owns optional stage planning explicitly.
|
||||
context.ClearShadowCasterStage();
|
||||
context.ClearDepthOnlyStage();
|
||||
context.ClearFullscreenStage(
|
||||
CameraFrameStage.PostProcess);
|
||||
context.ClearFullscreenStage(
|
||||
CameraFrameStage.FinalOutput);
|
||||
}
|
||||
|
||||
ScriptableRendererData resolvedRendererData =
|
||||
ResolveRendererData(context);
|
||||
if (resolvedRendererData != null)
|
||||
{
|
||||
resolvedRendererData
|
||||
.ConfigureCameraFramePlanInstance(
|
||||
context);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ConfigureDirectionalShadowExecutionState(
|
||||
DirectionalShadowExecutionContext context)
|
||||
{
|
||||
ScriptableRendererData resolvedRendererData =
|
||||
ResolveRendererData(context);
|
||||
return resolvedRendererData != null &&
|
||||
resolvedRendererData
|
||||
.ConfigureDirectionalShadowExecutionStateInstance(
|
||||
context);
|
||||
}
|
||||
|
||||
protected override bool ConfigureRenderSceneSetup(
|
||||
RenderSceneSetupContext context)
|
||||
{
|
||||
ScriptableRendererData resolvedRendererData =
|
||||
ResolveRendererData(context);
|
||||
return resolvedRendererData != null &&
|
||||
resolvedRendererData
|
||||
.ConfigureRenderSceneSetupInstance(
|
||||
context);
|
||||
}
|
||||
|
||||
protected override void ReleaseRuntimeResources()
|
||||
{
|
||||
m_rendererDataCollection.ReleaseRuntimeResources(
|
||||
ref rendererDataList,
|
||||
ref defaultRendererIndex,
|
||||
CreateDefaultRendererData);
|
||||
}
|
||||
|
||||
protected override void SynchronizeRuntimeResourceVersion()
|
||||
{
|
||||
m_rendererDataCollection.Synchronize(
|
||||
ref rendererDataList,
|
||||
ref defaultRendererIndex,
|
||||
ref m_rendererDataRuntimeStateHash,
|
||||
ref m_rendererDataRuntimeStateHashResolved,
|
||||
CreateDefaultRendererData,
|
||||
SetDirty);
|
||||
}
|
||||
|
||||
protected virtual ScriptableRenderPipeline
|
||||
CreateRendererBackedPipeline()
|
||||
{
|
||||
return new RendererBackedRenderPipeline(this);
|
||||
}
|
||||
|
||||
protected virtual void ConfigureRendererCameraRequest(
|
||||
RendererCameraRequestContext context)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual int ResolveRendererIndex(
|
||||
CameraRenderRequestContext context)
|
||||
{
|
||||
return ResolveSelectedRendererIndex();
|
||||
}
|
||||
|
||||
protected virtual ScriptableRendererData
|
||||
CreateDefaultRendererData()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual ScriptableRendererData[]
|
||||
CreateDefaultRendererDataList()
|
||||
{
|
||||
ScriptableRendererData defaultRendererData =
|
||||
CreateDefaultRendererData();
|
||||
return defaultRendererData != null
|
||||
? new ScriptableRendererData[]
|
||||
{
|
||||
defaultRendererData
|
||||
}
|
||||
: Array.Empty<ScriptableRendererData>();
|
||||
}
|
||||
|
||||
protected virtual ScriptableRendererDataComposition
|
||||
CreateDefaultRendererDataComposition()
|
||||
{
|
||||
ScriptableRendererData[] defaultRendererDataList =
|
||||
CreateDefaultRendererDataList() ??
|
||||
Array.Empty<ScriptableRendererData>();
|
||||
return new ScriptableRendererDataComposition(
|
||||
defaultRendererDataList,
|
||||
defaultRendererDataList.Length > 0
|
||||
? 0
|
||||
: -1);
|
||||
}
|
||||
|
||||
protected virtual bool UsesExplicitCameraFrameStagePlanning()
|
||||
{
|
||||
return UsesExplicitFullscreenStagePlanning();
|
||||
}
|
||||
|
||||
protected virtual bool UsesExplicitFullscreenStagePlanning()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void ResetRendererDataToDefault()
|
||||
{
|
||||
ScriptableRendererDataComposition composition =
|
||||
CreateDefaultRendererDataComposition();
|
||||
rendererDataList = composition.rendererDataList;
|
||||
defaultRendererIndex =
|
||||
composition.defaultRendererIndex;
|
||||
}
|
||||
|
||||
internal ScriptableRendererData GetDefaultRendererData()
|
||||
{
|
||||
return m_rendererDataCollection.GetDefaultRendererData(
|
||||
ref rendererDataList,
|
||||
ref defaultRendererIndex,
|
||||
CreateDefaultRendererData);
|
||||
}
|
||||
|
||||
internal ScriptableRenderer GetDefaultRenderer()
|
||||
{
|
||||
return ResolveSelectedRenderer();
|
||||
}
|
||||
|
||||
internal ScriptableRendererData ResolveSelectedRendererData()
|
||||
{
|
||||
return GetDefaultRendererData();
|
||||
}
|
||||
|
||||
internal ScriptableRenderer ResolveSelectedRenderer()
|
||||
{
|
||||
ScriptableRendererData rendererData =
|
||||
ResolveSelectedRendererData();
|
||||
return rendererData != null
|
||||
? rendererData.GetRendererInstance()
|
||||
: null;
|
||||
}
|
||||
|
||||
internal ScriptableRendererData GetRendererData(
|
||||
int rendererIndex)
|
||||
{
|
||||
return m_rendererDataCollection.GetRendererData(
|
||||
ref rendererDataList,
|
||||
ref defaultRendererIndex,
|
||||
rendererIndex,
|
||||
CreateDefaultRendererData);
|
||||
}
|
||||
|
||||
internal ScriptableRenderer ResolveRenderer(
|
||||
int rendererIndex)
|
||||
{
|
||||
ScriptableRendererData rendererData =
|
||||
GetRendererData(rendererIndex);
|
||||
return rendererData != null
|
||||
? rendererData.GetRendererInstance()
|
||||
: null;
|
||||
}
|
||||
|
||||
private int ResolveSelectedRendererIndex()
|
||||
{
|
||||
return m_rendererDataCollection
|
||||
.ResolveDefaultRendererIndex(
|
||||
ref rendererDataList,
|
||||
ref defaultRendererIndex,
|
||||
CreateDefaultRendererData);
|
||||
}
|
||||
|
||||
private ScriptableRendererData ResolveRendererData(
|
||||
CameraRenderRequestContext context)
|
||||
{
|
||||
return GetRendererData(
|
||||
context != null
|
||||
? context.rendererIndex
|
||||
: -1);
|
||||
}
|
||||
|
||||
private ScriptableRendererData ResolveRendererData(
|
||||
ScriptableRenderPipelinePlanningContext context)
|
||||
{
|
||||
return GetRendererData(
|
||||
context != null
|
||||
? context.rendererIndex
|
||||
: -1);
|
||||
}
|
||||
|
||||
private ScriptableRendererData ResolveRendererData(
|
||||
RenderSceneSetupContext context)
|
||||
{
|
||||
return GetRendererData(
|
||||
context != null
|
||||
? context.rendererIndex
|
||||
: -1);
|
||||
}
|
||||
|
||||
private ScriptableRendererData ResolveRendererData(
|
||||
DirectionalShadowExecutionContext context)
|
||||
{
|
||||
return GetRendererData(
|
||||
context != null
|
||||
? context.rendererIndex
|
||||
: -1);
|
||||
}
|
||||
|
||||
private void ApplyResolvedRendererIndex(
|
||||
CameraRenderRequestContext context,
|
||||
int rendererIndex)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
context.rendererIndex =
|
||||
m_rendererDataCollection
|
||||
.ResolveRendererIndexWithFallback(
|
||||
ref rendererDataList,
|
||||
ref defaultRendererIndex,
|
||||
rendererIndex,
|
||||
CreateDefaultRendererData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
using XCEngine;
|
||||
using XCEngine.Rendering;
|
||||
|
||||
namespace XCEngine.Rendering.Universal
|
||||
{
|
||||
public abstract class RendererDrivenRenderPipeline
|
||||
: ScriptableRenderPipeline
|
||||
{
|
||||
protected RendererDrivenRenderPipeline()
|
||||
{
|
||||
}
|
||||
|
||||
protected sealed override bool SupportsStageRenderGraph(
|
||||
CameraFrameStage stage)
|
||||
{
|
||||
return SupportsStageRenderGraphContextual(
|
||||
stage,
|
||||
-1);
|
||||
}
|
||||
|
||||
protected sealed override bool SupportsStageRenderGraphContextual(
|
||||
CameraFrameStage stage,
|
||||
int rendererIndex)
|
||||
{
|
||||
return SupportsRendererRecording(
|
||||
new RendererRecordingContext(
|
||||
stage,
|
||||
rendererIndex));
|
||||
}
|
||||
|
||||
protected sealed override bool RecordStageRenderGraph(
|
||||
ScriptableRenderContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return RecordRenderer(
|
||||
new RendererRecordingContext(context));
|
||||
}
|
||||
|
||||
protected virtual bool SupportsRendererRecording(
|
||||
RendererRecordingContext context)
|
||||
{
|
||||
ScriptableRenderer renderer =
|
||||
ResolveRenderer(context);
|
||||
return renderer != null &&
|
||||
renderer.SupportsRendererRecordingInstance(context);
|
||||
}
|
||||
|
||||
protected virtual bool RecordRenderer(
|
||||
RendererRecordingContext context)
|
||||
{
|
||||
ScriptableRenderer renderer =
|
||||
ResolveRenderer(context);
|
||||
return renderer != null &&
|
||||
renderer.RecordRendererInstance(context);
|
||||
}
|
||||
|
||||
protected abstract ScriptableRenderer ResolveRenderer(
|
||||
RendererRecordingContext context);
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,60 @@ using XCEngine.Rendering;
|
||||
|
||||
namespace XCEngine.Rendering.Universal
|
||||
{
|
||||
internal sealed class UniversalRenderPipeline
|
||||
: RendererBackedRenderPipeline
|
||||
public sealed class UniversalRenderPipeline
|
||||
: ScriptableRenderPipeline
|
||||
{
|
||||
private readonly UniversalRenderPipelineAsset m_asset;
|
||||
|
||||
public UniversalRenderPipeline(
|
||||
UniversalRenderPipelineAsset asset)
|
||||
: base(asset)
|
||||
{
|
||||
m_asset = asset;
|
||||
}
|
||||
|
||||
protected override bool SupportsStageRenderGraph(
|
||||
CameraFrameStage stage)
|
||||
{
|
||||
return SupportsStageRenderGraphContextual(
|
||||
stage,
|
||||
-1);
|
||||
}
|
||||
|
||||
protected override bool SupportsStageRenderGraphContextual(
|
||||
CameraFrameStage stage,
|
||||
int rendererIndex)
|
||||
{
|
||||
ScriptableRenderer renderer =
|
||||
ResolveRenderer(rendererIndex);
|
||||
return renderer != null &&
|
||||
renderer.SupportsRendererRecordingInstance(
|
||||
new RendererRecordingContext(
|
||||
stage,
|
||||
rendererIndex));
|
||||
}
|
||||
|
||||
protected override bool RecordStageRenderGraph(
|
||||
ScriptableRenderContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RendererRecordingContext recordingContext =
|
||||
new RendererRecordingContext(context);
|
||||
ScriptableRenderer renderer =
|
||||
ResolveRenderer(recordingContext.rendererIndex);
|
||||
return renderer != null &&
|
||||
renderer.RecordRendererInstance(recordingContext);
|
||||
}
|
||||
|
||||
private ScriptableRenderer ResolveRenderer(
|
||||
int rendererIndex)
|
||||
{
|
||||
return m_asset != null
|
||||
? m_asset.ResolveRenderer(rendererIndex)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,26 @@
|
||||
using System;
|
||||
using XCEngine;
|
||||
using XCEngine.Rendering;
|
||||
|
||||
namespace XCEngine.Rendering.Universal
|
||||
{
|
||||
public class UniversalRenderPipelineAsset
|
||||
: RendererBackedRenderPipelineAsset
|
||||
: ScriptableRenderPipelineAsset
|
||||
{
|
||||
public ScriptableRendererData[] rendererDataList =
|
||||
Array.Empty<ScriptableRendererData>();
|
||||
public int defaultRendererIndex = 0;
|
||||
public UniversalShadowSettings shadows;
|
||||
public UniversalFinalColorSettings finalColor;
|
||||
private readonly ScriptableRendererDataCollection
|
||||
m_rendererDataCollection;
|
||||
private int m_rendererDataRuntimeStateHash;
|
||||
private bool m_rendererDataRuntimeStateHashResolved;
|
||||
|
||||
public UniversalRenderPipelineAsset()
|
||||
{
|
||||
m_rendererDataCollection =
|
||||
new ScriptableRendererDataCollection();
|
||||
shadows =
|
||||
UniversalShadowSettings.CreateDefault();
|
||||
finalColor =
|
||||
@@ -18,8 +28,7 @@ namespace XCEngine.Rendering.Universal
|
||||
ResetRendererDataToDefault();
|
||||
}
|
||||
|
||||
protected override ScriptableRenderPipeline
|
||||
CreateRendererBackedPipeline()
|
||||
protected override ScriptableRenderPipeline CreatePipeline()
|
||||
{
|
||||
return new UniversalRenderPipeline(this);
|
||||
}
|
||||
@@ -30,7 +39,7 @@ namespace XCEngine.Rendering.Universal
|
||||
return GetFinalColorSettingsInstance().settings;
|
||||
}
|
||||
|
||||
protected override void ConfigureRendererCameraRequest(
|
||||
protected virtual void ConfigureRendererCameraRequest(
|
||||
RendererCameraRequestContext context)
|
||||
{
|
||||
if (context == null)
|
||||
@@ -85,21 +94,21 @@ namespace XCEngine.Rendering.Universal
|
||||
}
|
||||
}
|
||||
|
||||
protected override ScriptableRendererData
|
||||
protected virtual ScriptableRendererData
|
||||
CreateDefaultRendererData()
|
||||
{
|
||||
return UniversalDefaultRendererDataFactory
|
||||
.CreateDefaultRendererData();
|
||||
}
|
||||
|
||||
protected override ScriptableRendererDataComposition
|
||||
protected virtual ScriptableRendererDataComposition
|
||||
CreateDefaultRendererDataComposition()
|
||||
{
|
||||
return UniversalDefaultRendererDataFactory
|
||||
.CreateDefaultRendererDataComposition();
|
||||
}
|
||||
|
||||
protected override int ResolveRendererIndex(
|
||||
protected virtual int ResolveRendererIndex(
|
||||
CameraRenderRequestContext context)
|
||||
{
|
||||
Camera camera =
|
||||
@@ -117,7 +126,7 @@ namespace XCEngine.Rendering.Universal
|
||||
}
|
||||
}
|
||||
|
||||
return base.ResolveRendererIndex(context);
|
||||
return ResolveSelectedRendererIndex();
|
||||
}
|
||||
|
||||
private static RenderClearFlags ResolveRequestClearFlags(
|
||||
@@ -167,6 +176,107 @@ namespace XCEngine.Rendering.Universal
|
||||
return shadows;
|
||||
}
|
||||
|
||||
protected override void ConfigureCameraRenderRequest(
|
||||
CameraRenderRequestContext context)
|
||||
{
|
||||
ApplyResolvedRendererIndex(
|
||||
context,
|
||||
ResolveRendererIndex(context));
|
||||
|
||||
ConfigureRendererCameraRequest(
|
||||
new RendererCameraRequestContext(context));
|
||||
|
||||
ApplyResolvedRendererIndex(
|
||||
context,
|
||||
context != null
|
||||
? context.rendererIndex
|
||||
: -1);
|
||||
|
||||
ScriptableRendererData resolvedRendererData =
|
||||
ResolveRendererData(context);
|
||||
if (resolvedRendererData != null)
|
||||
{
|
||||
resolvedRendererData
|
||||
.ConfigureCameraRenderRequestInstance(
|
||||
context);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ConfigureCameraFramePlan(
|
||||
ScriptableRenderPipelinePlanningContext context)
|
||||
{
|
||||
if (UsesExplicitCameraFrameStagePlanning() &&
|
||||
context != null)
|
||||
{
|
||||
context.ClearShadowCasterStage();
|
||||
context.ClearDepthOnlyStage();
|
||||
context.ClearFullscreenStage(
|
||||
CameraFrameStage.PostProcess);
|
||||
context.ClearFullscreenStage(
|
||||
CameraFrameStage.FinalOutput);
|
||||
}
|
||||
|
||||
ScriptableRendererData resolvedRendererData =
|
||||
ResolveRendererData(context);
|
||||
if (resolvedRendererData != null)
|
||||
{
|
||||
resolvedRendererData
|
||||
.ConfigureCameraFramePlanInstance(
|
||||
context);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ConfigureDirectionalShadowExecutionState(
|
||||
DirectionalShadowExecutionContext context)
|
||||
{
|
||||
ScriptableRendererData resolvedRendererData =
|
||||
ResolveRendererData(context);
|
||||
return resolvedRendererData != null &&
|
||||
resolvedRendererData
|
||||
.ConfigureDirectionalShadowExecutionStateInstance(
|
||||
context);
|
||||
}
|
||||
|
||||
protected override bool ConfigureRenderSceneSetup(
|
||||
RenderSceneSetupContext context)
|
||||
{
|
||||
ScriptableRendererData resolvedRendererData =
|
||||
ResolveRendererData(context);
|
||||
return resolvedRendererData != null &&
|
||||
resolvedRendererData
|
||||
.ConfigureRenderSceneSetupInstance(
|
||||
context);
|
||||
}
|
||||
|
||||
protected override void ReleaseRuntimeResources()
|
||||
{
|
||||
m_rendererDataCollection.ReleaseRuntimeResources(
|
||||
ref rendererDataList,
|
||||
ref defaultRendererIndex,
|
||||
CreateDefaultRendererData);
|
||||
}
|
||||
|
||||
protected override void SynchronizeRuntimeResourceVersion()
|
||||
{
|
||||
m_rendererDataCollection.Synchronize(
|
||||
ref rendererDataList,
|
||||
ref defaultRendererIndex,
|
||||
ref m_rendererDataRuntimeStateHash,
|
||||
ref m_rendererDataRuntimeStateHashResolved,
|
||||
CreateDefaultRendererData,
|
||||
SetDirty);
|
||||
}
|
||||
|
||||
protected virtual bool UsesExplicitCameraFrameStagePlanning()
|
||||
{
|
||||
return UsesExplicitFullscreenStagePlanning();
|
||||
}
|
||||
|
||||
protected virtual bool UsesExplicitFullscreenStagePlanning()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private UniversalFinalColorSettings
|
||||
GetFinalColorSettingsInstance()
|
||||
{
|
||||
@@ -178,6 +288,125 @@ namespace XCEngine.Rendering.Universal
|
||||
|
||||
return finalColor;
|
||||
}
|
||||
|
||||
protected void ResetRendererDataToDefault()
|
||||
{
|
||||
ScriptableRendererDataComposition composition =
|
||||
CreateDefaultRendererDataComposition();
|
||||
rendererDataList = composition.rendererDataList;
|
||||
defaultRendererIndex =
|
||||
composition.defaultRendererIndex;
|
||||
}
|
||||
|
||||
internal ScriptableRendererData GetDefaultRendererData()
|
||||
{
|
||||
return m_rendererDataCollection.GetDefaultRendererData(
|
||||
ref rendererDataList,
|
||||
ref defaultRendererIndex,
|
||||
CreateDefaultRendererData);
|
||||
}
|
||||
|
||||
internal ScriptableRenderer GetDefaultRenderer()
|
||||
{
|
||||
return ResolveSelectedRenderer();
|
||||
}
|
||||
|
||||
internal ScriptableRendererData ResolveSelectedRendererData()
|
||||
{
|
||||
return GetDefaultRendererData();
|
||||
}
|
||||
|
||||
internal ScriptableRenderer ResolveSelectedRenderer()
|
||||
{
|
||||
ScriptableRendererData rendererData =
|
||||
ResolveSelectedRendererData();
|
||||
return rendererData != null
|
||||
? rendererData.GetRendererInstance()
|
||||
: null;
|
||||
}
|
||||
|
||||
internal ScriptableRendererData GetRendererData(
|
||||
int rendererIndex)
|
||||
{
|
||||
return m_rendererDataCollection.GetRendererData(
|
||||
ref rendererDataList,
|
||||
ref defaultRendererIndex,
|
||||
rendererIndex,
|
||||
CreateDefaultRendererData);
|
||||
}
|
||||
|
||||
internal ScriptableRenderer ResolveRenderer(
|
||||
int rendererIndex)
|
||||
{
|
||||
ScriptableRendererData rendererData =
|
||||
GetRendererData(rendererIndex);
|
||||
return rendererData != null
|
||||
? rendererData.GetRendererInstance()
|
||||
: null;
|
||||
}
|
||||
|
||||
private int ResolveSelectedRendererIndex()
|
||||
{
|
||||
return m_rendererDataCollection
|
||||
.ResolveDefaultRendererIndex(
|
||||
ref rendererDataList,
|
||||
ref defaultRendererIndex,
|
||||
CreateDefaultRendererData);
|
||||
}
|
||||
|
||||
private ScriptableRendererData ResolveRendererData(
|
||||
CameraRenderRequestContext context)
|
||||
{
|
||||
return GetRendererData(
|
||||
context != null
|
||||
? context.rendererIndex
|
||||
: -1);
|
||||
}
|
||||
|
||||
private ScriptableRendererData ResolveRendererData(
|
||||
ScriptableRenderPipelinePlanningContext context)
|
||||
{
|
||||
return GetRendererData(
|
||||
context != null
|
||||
? context.rendererIndex
|
||||
: -1);
|
||||
}
|
||||
|
||||
private ScriptableRendererData ResolveRendererData(
|
||||
RenderSceneSetupContext context)
|
||||
{
|
||||
return GetRendererData(
|
||||
context != null
|
||||
? context.rendererIndex
|
||||
: -1);
|
||||
}
|
||||
|
||||
private ScriptableRendererData ResolveRendererData(
|
||||
DirectionalShadowExecutionContext context)
|
||||
{
|
||||
return GetRendererData(
|
||||
context != null
|
||||
? context.rendererIndex
|
||||
: -1);
|
||||
}
|
||||
|
||||
private void ApplyResolvedRendererIndex(
|
||||
CameraRenderRequestContext context,
|
||||
int rendererIndex)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
context.rendererIndex =
|
||||
m_rendererDataCollection
|
||||
.ResolveRendererIndexWithFallback(
|
||||
ref rendererDataList,
|
||||
ref defaultRendererIndex,
|
||||
rendererIndex,
|
||||
CreateDefaultRendererData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -242,30 +242,6 @@ namespace ProjectScripts
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ProjectRendererInvalidationProbePipeline
|
||||
: RendererBackedRenderPipeline
|
||||
{
|
||||
public ProjectRendererInvalidationProbePipeline(
|
||||
RendererBackedRenderPipelineAsset asset)
|
||||
: base(asset)
|
||||
{
|
||||
ProjectRendererInvalidationProbeState
|
||||
.CreatePipelineCallCount++;
|
||||
}
|
||||
|
||||
protected override void Dispose(
|
||||
bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
ProjectRendererInvalidationProbeState
|
||||
.DisposePipelineCallCount++;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ProjectRendererInvalidationProbeFeature
|
||||
: ScriptableRendererFeature
|
||||
{
|
||||
@@ -357,11 +333,11 @@ namespace ProjectScripts
|
||||
};
|
||||
}
|
||||
|
||||
protected override ScriptableRenderPipeline
|
||||
CreateRendererBackedPipeline()
|
||||
protected override ScriptableRenderPipeline CreatePipeline()
|
||||
{
|
||||
return new ProjectRendererInvalidationProbePipeline(
|
||||
this);
|
||||
ProjectRendererInvalidationProbeState
|
||||
.CreatePipelineCallCount++;
|
||||
return base.CreatePipeline();
|
||||
}
|
||||
|
||||
public void InvalidateDefaultRendererForTest()
|
||||
|
||||
@@ -592,11 +592,14 @@ TEST_F(
|
||||
renderer.GetPipelineAsset()),
|
||||
nullptr);
|
||||
|
||||
auto* host =
|
||||
EXPECT_NE(
|
||||
dynamic_cast<XCEngine::Rendering::Pipelines::BuiltinForwardPipeline*>(
|
||||
renderer.GetPipeline()),
|
||||
nullptr);
|
||||
EXPECT_EQ(
|
||||
dynamic_cast<XCEngine::Rendering::Pipelines::ScriptableRenderPipelineHost*>(
|
||||
renderer.GetPipeline());
|
||||
ASSERT_NE(host, nullptr);
|
||||
EXPECT_EQ(host->GetStageRecorder(), nullptr);
|
||||
renderer.GetPipeline()),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
TEST_F(
|
||||
@@ -1631,9 +1634,9 @@ TEST_F(
|
||||
EXPECT_TRUE(hasRendererFeatureConfigureCameraFramePlan);
|
||||
EXPECT_TRUE(hasRendererRecordingContextType);
|
||||
EXPECT_TRUE(hasRendererCameraRequestContextType);
|
||||
EXPECT_TRUE(hasRendererBackedRenderPipelineAssetType);
|
||||
EXPECT_TRUE(hasRendererBackedRenderPipelineType);
|
||||
EXPECT_TRUE(hasRendererDrivenRenderPipelineType);
|
||||
EXPECT_FALSE(hasRendererBackedRenderPipelineAssetType);
|
||||
EXPECT_FALSE(hasRendererBackedRenderPipelineType);
|
||||
EXPECT_FALSE(hasRendererDrivenRenderPipelineType);
|
||||
EXPECT_TRUE(hasRendererDataSetupRenderer);
|
||||
EXPECT_TRUE(hasRendererDataSetDirty);
|
||||
EXPECT_TRUE(hasRendererDataIsInvalidated);
|
||||
@@ -3044,7 +3047,7 @@ TEST_F(
|
||||
EXPECT_EQ(observedCreatePipelineCallCount, 2);
|
||||
EXPECT_EQ(observedCreateRendererCallCount, 2);
|
||||
EXPECT_EQ(observedSetupRendererCallCount, 2);
|
||||
EXPECT_EQ(observedCreateFeatureCallCount, 2);
|
||||
EXPECT_EQ(observedCreateFeatureCallCount, 1);
|
||||
EXPECT_EQ(observedReleaseRendererDataRuntimeResourcesCallCount, 2);
|
||||
EXPECT_EQ(observedDisposePipelineCallCount, 0);
|
||||
EXPECT_EQ(observedReleaseAssetRuntimeResourcesCallCount, 2);
|
||||
@@ -3161,7 +3164,7 @@ TEST_F(
|
||||
EXPECT_EQ(observedCreatePipelineCallCount, 0);
|
||||
EXPECT_EQ(observedCreateRendererCallCount, 0);
|
||||
EXPECT_EQ(observedSetupRendererCallCount, 0);
|
||||
EXPECT_EQ(observedCreateFeatureCallCount, 2);
|
||||
EXPECT_EQ(observedCreateFeatureCallCount, 1);
|
||||
EXPECT_EQ(observedReleaseRendererDataRuntimeResourcesCallCount, 2);
|
||||
EXPECT_EQ(observedDisposePipelineCallCount, 0);
|
||||
EXPECT_EQ(observedReleaseAssetRuntimeResourcesCallCount, 2);
|
||||
@@ -3896,7 +3899,7 @@ TEST_F(
|
||||
observedRuntimeResourceVersionAfterInvalidation));
|
||||
|
||||
EXPECT_EQ(observedCreatePipelineCallCount, 2);
|
||||
EXPECT_EQ(observedDisposePipelineCallCount, 1);
|
||||
EXPECT_EQ(observedDisposePipelineCallCount, 0);
|
||||
EXPECT_EQ(observedCreateRendererCallCount, 2);
|
||||
EXPECT_EQ(observedSetupRendererCallCount, 2);
|
||||
EXPECT_EQ(observedCreateFeatureCallCount, 2);
|
||||
|
||||
@@ -598,7 +598,7 @@ TEST_F(
|
||||
observedRuntimeResourceVersionAfterInvalidation));
|
||||
|
||||
EXPECT_EQ(observedCreatePipelineCallCount, 2);
|
||||
EXPECT_EQ(observedDisposePipelineCallCount, 1);
|
||||
EXPECT_EQ(observedDisposePipelineCallCount, 0);
|
||||
EXPECT_EQ(observedCreateRendererCallCount, 2);
|
||||
EXPECT_EQ(observedSetupRendererCallCount, 2);
|
||||
EXPECT_EQ(observedCreateFeatureCallCount, 2);
|
||||
|
||||
Reference in New Issue
Block a user