Tighten SRP stage fallback gate
This commit is contained in:
@@ -91,6 +91,9 @@ Unity 兼容的公开命名、对象所有权和扩展点。
|
||||
哪些 stages 存在;native 只执行这些声明,不夹带 built-in pipeline policy。
|
||||
- Hidden fallback 很危险。如果 managed URP stage 声明支持但无法 record,失败必须可见。不要静默用
|
||||
default built-in path 画同一个 stage,然后称之为 URP。
|
||||
- Camera-frame graph dispatch 必须询问所选 pipeline 是否允许 legacy stage fallback。Managed
|
||||
`ScriptableRenderPipelineHost` 在 stage recorder 或 managed runtime 权威时不允许 fallback;此时缺少
|
||||
recorder、sequence 或 standalone pass 要在 graph recording 阶段失败,而不是排入 built-in fallback。
|
||||
- 测试体系已经有有价值的覆盖,但还不足以宣称 SRP/URP stack 完全锁定。随着架构边界收口,应补高价值
|
||||
contract tests;现阶段不要为了大范围测试体系重写而暂停架构工作。
|
||||
|
||||
@@ -333,3 +336,6 @@ Scene data 每个 camera frame 提取一次,然后由 pipeline 调整。
|
||||
`CameraFrameStage` 和 `CameraFramePlan`。
|
||||
- Final color processing 表示为 policy 和 final output stage,而不是 implicit swapchain behavior。
|
||||
- Object-id rendering 是 top-level tooling pass,并由 `XCENGINE_ENABLE_RENDERING_EDITOR_SUPPORT` guard。
|
||||
- Camera-frame graph dispatch 已收紧 legacy fallback gate:只有所选 pipeline 明确允许时,未被
|
||||
render-graph recorder、pass sequence 或 standalone pass 处理的 stage 才能进入 fallback raster pass。
|
||||
Managed SRP/URP host 不允许 hidden built-in fallback。
|
||||
|
||||
@@ -49,6 +49,9 @@ public:
|
||||
bool SupportsStageRenderGraph(CameraFrameStage stage) const override;
|
||||
bool SupportsStageRenderGraph(
|
||||
const RenderPipelineStageSupportContext& context) const override;
|
||||
bool AllowsCameraFrameStageFallback(CameraFrameStage stage) const override;
|
||||
bool AllowsCameraFrameStageFallback(
|
||||
const RenderPipelineStageSupportContext& context) const override;
|
||||
bool RecordStageRenderGraph(
|
||||
const RenderPipelineStageRenderGraphContext& context) override;
|
||||
bool Render(const FrameExecutionContext& executionContext) override;
|
||||
|
||||
@@ -103,6 +103,13 @@ public:
|
||||
const RenderPipelineStageSupportContext& context) const {
|
||||
return SupportsStageRenderGraph(context.stage);
|
||||
}
|
||||
virtual bool AllowsCameraFrameStageFallback(CameraFrameStage) const {
|
||||
return true;
|
||||
}
|
||||
virtual bool AllowsCameraFrameStageFallback(
|
||||
const RenderPipelineStageSupportContext& context) const {
|
||||
return AllowsCameraFrameStageFallback(context.stage);
|
||||
}
|
||||
virtual bool RecordStageRenderGraph(
|
||||
const RenderPipelineStageRenderGraphContext&) {
|
||||
return false;
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include "Rendering/Execution/Internal/CameraFrameGraph/PassRecorder.h"
|
||||
#include "Rendering/Execution/Internal/CameraFrameGraph/SequenceRecorder.h"
|
||||
#include "Rendering/Execution/Internal/CameraFrameGraph/State.h"
|
||||
#include "Debug/Logger.h"
|
||||
#include "Rendering/RenderPipeline.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
@@ -23,6 +25,25 @@ constexpr std::array<CameraFrameStageRecordHandler, 3u> kCameraFrameStageRecordH
|
||||
&TryRecordCameraFrameStageStandaloneRenderGraphPass
|
||||
};
|
||||
|
||||
RenderPipelineStageSupportContext BuildStageSupportContext(
|
||||
const CameraFrameStageGraphBuildState& stageState,
|
||||
const CameraFrameRenderGraphStageContext& context) {
|
||||
return RenderPipelineStageSupportContext{
|
||||
stageState.stage,
|
||||
context.plan.request.rendererIndex };
|
||||
}
|
||||
|
||||
bool AllowsCameraFrameStageFallback(
|
||||
const CameraFrameStageGraphBuildState& stageState,
|
||||
const CameraFrameRenderGraphStageContext& context) {
|
||||
RenderPipeline* const pipeline = context.builder.executionState.pipeline;
|
||||
return pipeline == nullptr ||
|
||||
pipeline->AllowsCameraFrameStageFallback(
|
||||
BuildStageSupportContext(
|
||||
stageState,
|
||||
context));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool RecordCameraFrameRenderGraphStage(
|
||||
@@ -44,6 +65,15 @@ bool RecordCameraFrameRenderGraphStage(
|
||||
}
|
||||
}
|
||||
|
||||
if (!AllowsCameraFrameStageFallback(stageState, context)) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
Containers::String(
|
||||
"CameraRenderer::Render failed: stage has no render-graph recorder or sequence, and the selected pipeline disallows fallback: ") +
|
||||
stageState.stageName);
|
||||
return false;
|
||||
}
|
||||
|
||||
AddCameraFrameStageFallbackRasterPass(stageState, context);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -118,6 +118,24 @@ bool ScriptableRenderPipelineHost::SupportsStageRenderGraph(
|
||||
m_pipelineBackend->SupportsStageRenderGraph(context);
|
||||
}
|
||||
|
||||
bool ScriptableRenderPipelineHost::AllowsCameraFrameStageFallback(
|
||||
CameraFrameStage stage) const {
|
||||
return AllowsCameraFrameStageFallback(
|
||||
RenderPipelineStageSupportContext{ stage, -1 });
|
||||
}
|
||||
|
||||
bool ScriptableRenderPipelineHost::AllowsCameraFrameStageFallback(
|
||||
const RenderPipelineStageSupportContext& context) const {
|
||||
if (UsesAuthoritativeStageRecorder(
|
||||
m_stageRecorder.get(),
|
||||
m_managedAssetRuntime.get())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_pipelineBackend != nullptr &&
|
||||
m_pipelineBackend->AllowsCameraFrameStageFallback(context);
|
||||
}
|
||||
|
||||
bool ScriptableRenderPipelineHost::RecordStageRenderGraph(
|
||||
const RenderPipelineStageRenderGraphContext& context) {
|
||||
if (!EnsureInitialized(context.renderContext)) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "Rendering/Execution/Internal/CameraFrameGraph/BuilderContext.h"
|
||||
#include "Rendering/Execution/Internal/CameraFrameGraph/StageContract.h"
|
||||
#include "Rendering/Execution/Internal/CameraFrameGraph/StageDispatch.h"
|
||||
#include "Rendering/Execution/Internal/CameraFrameGraph/ExecutionState.h"
|
||||
#include "Rendering/Graph/RenderGraph.h"
|
||||
|
||||
@@ -102,7 +103,13 @@ public:
|
||||
}
|
||||
|
||||
bool SupportsStageRenderGraph(CameraFrameStage stage) const override {
|
||||
return SupportsCameraFramePipelineGraphRecording(stage);
|
||||
return supportsMainSceneRenderGraph &&
|
||||
SupportsCameraFramePipelineGraphRecording(stage);
|
||||
}
|
||||
|
||||
bool AllowsCameraFrameStageFallback(CameraFrameStage stage) const override {
|
||||
(void)stage;
|
||||
return allowsStageFallback;
|
||||
}
|
||||
|
||||
bool RecordStageRenderGraph(
|
||||
@@ -138,6 +145,8 @@ public:
|
||||
|
||||
bool recordResult = true;
|
||||
bool renderResult = true;
|
||||
bool supportsMainSceneRenderGraph = true;
|
||||
bool allowsStageFallback = true;
|
||||
int recordCalls = 0;
|
||||
int renderCalls = 0;
|
||||
std::string lastPassName = {};
|
||||
@@ -443,22 +452,26 @@ TEST(CameraFrameRenderGraphStageContract_Test, ResolvesStandaloneStagePassFromEx
|
||||
EXPECT_EQ(
|
||||
ResolveCameraFrameStandaloneStagePass(
|
||||
CameraFrameStage::ObjectId,
|
||||
executionState),
|
||||
executionState,
|
||||
-1),
|
||||
objectIdPass);
|
||||
EXPECT_EQ(
|
||||
ResolveCameraFrameStandaloneStagePass(
|
||||
CameraFrameStage::DepthOnly,
|
||||
executionState),
|
||||
executionState,
|
||||
-1),
|
||||
depthOnlyPass);
|
||||
EXPECT_EQ(
|
||||
ResolveCameraFrameStandaloneStagePass(
|
||||
CameraFrameStage::ShadowCaster,
|
||||
executionState),
|
||||
executionState,
|
||||
-1),
|
||||
shadowCasterPass);
|
||||
EXPECT_EQ(
|
||||
ResolveCameraFrameStandaloneStagePass(
|
||||
CameraFrameStage::MainScene,
|
||||
executionState),
|
||||
executionState,
|
||||
-1),
|
||||
nullptr);
|
||||
}
|
||||
|
||||
@@ -1547,3 +1560,21 @@ TEST(CameraFrameRenderGraphStageContract_Test, ExecutesDepthOnlyFallbackPassUsin
|
||||
EXPECT_EQ(depthOnlyPass->lastExecuteSceneData.cameraData.clearFlags, RenderClearFlags::Color);
|
||||
}
|
||||
|
||||
TEST(CameraFrameRenderGraphStageContract_Test, FailsRecordingWhenSelectedPipelineDisallowsStageFallback) {
|
||||
StageContractTestContext testContext = {};
|
||||
RecordingPipeline pipeline = {};
|
||||
pipeline.supportsMainSceneRenderGraph = false;
|
||||
pipeline.allowsStageFallback = false;
|
||||
testContext.executionState.pipeline = &pipeline;
|
||||
testContext.plan.request.surface = RenderSurface(320, 180);
|
||||
|
||||
const CameraFrameRenderGraphStageContext context =
|
||||
testContext.BuildStageContext();
|
||||
|
||||
EXPECT_FALSE(RecordCameraFrameRenderGraphStage(
|
||||
CameraFrameStage::MainScene,
|
||||
context));
|
||||
EXPECT_EQ(pipeline.recordCalls, 0);
|
||||
EXPECT_EQ(pipeline.renderCalls, 0);
|
||||
EXPECT_EQ(testContext.graph.GetPassCount(), 0u);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user