refactor(rendering): auto-initialize scriptable render pipeline host

This commit is contained in:
2026-04-15 21:15:39 +08:00
parent 966106e0c0
commit 02aa9a8ea5
3 changed files with 114 additions and 13 deletions

View File

@@ -46,12 +46,20 @@ public:
const RenderSceneData& sceneData) override;
private:
bool EnsureInitialized(const RenderContext& context);
void ShutdownInitializedComponents();
void ResetInitializationState();
void ClearInitializationContextIfNoComponentsAreInitialized();
void ResetStageRecorder(std::unique_ptr<RenderPipelineStageRecorder> stageRecorder);
void ResetPipelineRenderer(std::unique_ptr<RenderPipelineRenderer> pipelineRenderer);
std::unique_ptr<RenderPipelineStageRecorder> m_stageRecorder;
std::shared_ptr<const RenderPipelineAsset> m_pipelineRendererAsset;
std::unique_ptr<RenderPipelineRenderer> m_pipelineRenderer;
RHI::RHIDevice* m_initializedDevice = nullptr;
RHI::RHIType m_initializedBackendType = RHI::RHIType::D3D12;
bool m_pipelineRendererInitialized = false;
bool m_stageRecorderInitialized = false;
};
class ScriptableRenderPipelineHostAsset final : public RenderPipelineAsset {

View File

@@ -93,19 +93,7 @@ void ScriptableRenderPipelineHost::SetPipelineRendererAsset(
}
bool ScriptableRenderPipelineHost::Initialize(const RenderContext& context) {
if (m_pipelineRenderer == nullptr ||
!m_pipelineRenderer->Initialize(context)) {
return false;
}
if (m_stageRecorder != nullptr &&
!m_stageRecorder->Initialize(context)) {
m_stageRecorder->Shutdown();
m_pipelineRenderer->Shutdown();
return false;
}
return true;
return EnsureInitialized(context);
}
void ScriptableRenderPipelineHost::Shutdown() {
@@ -116,6 +104,7 @@ void ScriptableRenderPipelineHost::Shutdown() {
m_pipelineRenderer->Shutdown();
}
ShutdownCameraFrameStandalonePasses();
ResetInitializationState();
}
bool ScriptableRenderPipelineHost::SupportsStageRenderGraph(
@@ -128,6 +117,10 @@ bool ScriptableRenderPipelineHost::SupportsStageRenderGraph(
bool ScriptableRenderPipelineHost::RecordStageRenderGraph(
const RenderPipelineStageRenderGraphContext& context) {
if (!EnsureInitialized(context.renderContext)) {
return false;
}
if (m_stageRecorder != nullptr &&
m_stageRecorder->SupportsStageRenderGraph(context.stage)) {
return m_stageRecorder->RecordStageRenderGraph(context);
@@ -139,6 +132,10 @@ bool ScriptableRenderPipelineHost::RecordStageRenderGraph(
bool ScriptableRenderPipelineHost::Render(
const FrameExecutionContext& executionContext) {
if (!EnsureInitialized(executionContext.renderContext)) {
return false;
}
return m_pipelineRenderer != nullptr &&
m_pipelineRenderer->Render(executionContext);
}
@@ -147,10 +144,86 @@ bool ScriptableRenderPipelineHost::Render(
const RenderContext& context,
const RenderSurface& surface,
const RenderSceneData& sceneData) {
if (!EnsureInitialized(context)) {
return false;
}
return m_pipelineRenderer != nullptr &&
m_pipelineRenderer->Render(context, surface, sceneData);
}
bool ScriptableRenderPipelineHost::EnsureInitialized(const RenderContext& context) {
if (!context.IsValid() || m_pipelineRenderer == nullptr) {
return false;
}
const bool hasInitializationContext =
m_initializedDevice != nullptr ||
m_pipelineRendererInitialized ||
m_stageRecorderInitialized;
if (hasInitializationContext &&
(m_initializedDevice != context.device ||
m_initializedBackendType != context.backendType)) {
ShutdownInitializedComponents();
}
if (!m_pipelineRendererInitialized) {
if (!m_pipelineRenderer->Initialize(context)) {
m_pipelineRenderer->Shutdown();
ClearInitializationContextIfNoComponentsAreInitialized();
return false;
}
m_pipelineRendererInitialized = true;
m_initializedDevice = context.device;
m_initializedBackendType = context.backendType;
}
if (m_stageRecorder != nullptr &&
!m_stageRecorderInitialized) {
if (!m_stageRecorder->Initialize(context)) {
m_stageRecorder->Shutdown();
ShutdownInitializedComponents();
return false;
}
m_stageRecorderInitialized = true;
m_initializedDevice = context.device;
m_initializedBackendType = context.backendType;
}
return true;
}
void ScriptableRenderPipelineHost::ShutdownInitializedComponents() {
if (m_stageRecorderInitialized &&
m_stageRecorder != nullptr) {
m_stageRecorder->Shutdown();
}
if (m_pipelineRendererInitialized &&
m_pipelineRenderer != nullptr) {
m_pipelineRenderer->Shutdown();
}
ResetInitializationState();
}
void ScriptableRenderPipelineHost::ResetInitializationState() {
m_initializedDevice = nullptr;
m_initializedBackendType = RHI::RHIType::D3D12;
m_pipelineRendererInitialized = false;
m_stageRecorderInitialized = false;
}
void ScriptableRenderPipelineHost::ClearInitializationContextIfNoComponentsAreInitialized() {
if (!m_pipelineRendererInitialized &&
!m_stageRecorderInitialized) {
m_initializedDevice = nullptr;
m_initializedBackendType = RHI::RHIType::D3D12;
}
}
void ScriptableRenderPipelineHost::ResetStageRecorder(
std::unique_ptr<RenderPipelineStageRecorder> stageRecorder) {
if (m_stageRecorder != nullptr) {
@@ -158,6 +231,8 @@ void ScriptableRenderPipelineHost::ResetStageRecorder(
}
m_stageRecorder = std::move(stageRecorder);
m_stageRecorderInitialized = false;
ClearInitializationContextIfNoComponentsAreInitialized();
}
void ScriptableRenderPipelineHost::ResetPipelineRenderer(
@@ -174,6 +249,9 @@ void ScriptableRenderPipelineHost::ResetPipelineRenderer(
m_pipelineRenderer =
CreatePipelineRendererFromAsset(m_pipelineRendererAsset);
}
m_pipelineRendererInitialized = false;
ClearInitializationContextIfNoComponentsAreInitialized();
}
ScriptableRenderPipelineHostAsset::ScriptableRenderPipelineHostAsset()

View File

@@ -3853,11 +3853,19 @@ TEST(ScriptableRenderPipelineHost_Test, ForwardsRendererLifetimeAndFrameRenderin
request.context,
request.surface,
sceneData));
EXPECT_EQ(replacementState->initializeCalls, 1);
EXPECT_EQ(replacementState->renderCalls, 1);
EXPECT_EQ(replacementState->lastSurfaceWidth, 800u);
EXPECT_EQ(replacementState->lastSurfaceHeight, 600u);
EXPECT_EQ(replacementState->lastCamera, camera);
ASSERT_TRUE(host.Render(FrameExecutionContext(
request.context,
request.surface,
sceneData)));
EXPECT_EQ(replacementState->initializeCalls, 1);
EXPECT_EQ(replacementState->renderCalls, 2);
replacementState->supportsMainSceneRenderGraph = true;
RenderGraph graph = {};
RenderGraphBuilder graphBuilder(graph);
@@ -3883,6 +3891,7 @@ TEST(ScriptableRenderPipelineHost_Test, ForwardsRendererLifetimeAndFrameRenderin
};
EXPECT_TRUE(host.SupportsStageRenderGraph(CameraFrameStage::MainScene));
EXPECT_TRUE(host.RecordStageRenderGraph(graphContext));
EXPECT_EQ(replacementState->initializeCalls, 1);
EXPECT_EQ(replacementState->recordMainSceneCalls, 1);
}
@@ -3950,7 +3959,13 @@ TEST(ScriptableRenderPipelineHost_Test, PrefersStageRecorderBeforeFallbackRender
EXPECT_TRUE(host.SupportsStageRenderGraph(CameraFrameStage::MainScene));
EXPECT_TRUE(host.RecordStageRenderGraph(graphContext));
EXPECT_EQ(rendererState->initializeCalls, 1);
EXPECT_EQ(replacementRecorderState->initializeCalls, 1);
EXPECT_EQ(replacementRecorderState->recordMainSceneCalls, 1);
EXPECT_TRUE(host.RecordStageRenderGraph(graphContext));
EXPECT_EQ(rendererState->initializeCalls, 1);
EXPECT_EQ(replacementRecorderState->initializeCalls, 1);
EXPECT_EQ(replacementRecorderState->recordMainSceneCalls, 2);
EXPECT_TRUE(replacementRecorderState->lastReceivedRenderGraphBlackboard);
EXPECT_EQ(rendererState->recordMainSceneCalls, 0);
}