fix(rendering): refresh managed pipelines on srp environment changes

This commit is contained in:
2026-04-18 01:10:45 +08:00
parent e388b6fbe3
commit df02a4e741
5 changed files with 140 additions and 3 deletions

View File

@@ -4,6 +4,7 @@
#include "Rendering/Execution/DirectionalShadowExecutionState.h"
#include "Rendering/Execution/Internal/CameraFrameGraph/Executor.h"
#include "Rendering/Internal/RenderPipelineFactory.h"
#include "Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h"
#include "Rendering/RenderPipelineAsset.h"
#include "Rendering/RenderSurface.h"
#include "Rendering/Shadow/DirectionalShadowRuntime.h"
@@ -21,10 +22,17 @@ bool RequiresPipelineStageRecording(
plan.GetPassSequence(stage) == nullptr;
}
bool IsManagedPipelineAsset(
const std::shared_ptr<const RenderPipelineAsset>& pipelineAsset) {
return dynamic_cast<const Pipelines::ManagedScriptableRenderPipelineAsset*>(
pipelineAsset.get()) != nullptr;
}
} // namespace
CameraRenderer::CameraRenderer()
: CameraRenderer(Internal::CreateDefaultRenderPipelineAsset()) {
: m_directionalShadowRuntime(std::make_unique<DirectionalShadowRuntime>()) {
SetPipelineAsset(nullptr);
}
CameraRenderer::CameraRenderer(std::unique_ptr<RenderPipeline> pipeline)
@@ -46,16 +54,53 @@ CameraRenderer::~CameraRenderer() {
void CameraRenderer::SetPipeline(std::unique_ptr<RenderPipeline> pipeline) {
m_pipelineAsset.reset();
m_usesDefaultPipelineAssetSelection = false;
m_managedPipelineEnvironmentGeneration = 0u;
ResetPipeline(std::move(pipeline));
}
void CameraRenderer::SetPipelineAsset(std::shared_ptr<const RenderPipelineAsset> pipelineAsset) {
m_usesDefaultPipelineAssetSelection = pipelineAsset == nullptr;
ResetPipeline(
Internal::CreateRenderPipelineOrDefault(
pipelineAsset,
&m_pipelineAsset));
}
RenderPipeline* CameraRenderer::GetPipeline() const {
const_cast<CameraRenderer*>(this)->RefreshManagedPipelineBindingIfNeeded();
return m_pipeline.get();
}
const RenderPipelineAsset* CameraRenderer::GetPipelineAsset() const {
const_cast<CameraRenderer*>(this)->RefreshManagedPipelineBindingIfNeeded();
return m_pipelineAsset.get();
}
bool CameraRenderer::UsesManagedPipelineBinding() const {
return m_usesDefaultPipelineAssetSelection ||
IsManagedPipelineAsset(m_pipelineAsset);
}
void CameraRenderer::RefreshManagedPipelineBindingIfNeeded() {
if (!UsesManagedPipelineBinding()) {
return;
}
const size_t currentGeneration =
Pipelines::GetManagedRenderPipelineEnvironmentGeneration();
if (currentGeneration == m_managedPipelineEnvironmentGeneration) {
return;
}
if (m_usesDefaultPipelineAssetSelection) {
SetPipelineAsset(nullptr);
return;
}
SetPipelineAsset(m_pipelineAsset);
}
void CameraRenderer::ResetPipeline(std::unique_ptr<RenderPipeline> pipeline) {
if (m_pipeline != nullptr) {
m_pipeline->Shutdown();
@@ -63,11 +108,17 @@ void CameraRenderer::ResetPipeline(std::unique_ptr<RenderPipeline> pipeline) {
m_pipeline = std::move(pipeline);
if (m_pipeline == nullptr) {
m_usesDefaultPipelineAssetSelection = true;
m_pipeline =
Internal::CreateRenderPipelineOrDefault(
nullptr,
&m_pipelineAsset);
}
m_managedPipelineEnvironmentGeneration =
UsesManagedPipelineBinding()
? Pipelines::GetManagedRenderPipelineEnvironmentGeneration()
: 0u;
}
bool CameraRenderer::BuildSceneDataForPlan(
@@ -109,6 +160,8 @@ bool CameraRenderer::ExecuteRenderPlan(
bool CameraRenderer::Render(
const CameraFramePlan& plan) {
RefreshManagedPipelineBindingIfNeeded();
if (!plan.IsValid() || m_pipeline == nullptr) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,

View File

@@ -23,6 +23,11 @@ size_t& GetManagedRenderPipelineBridgeGenerationStorage() {
return s_generation;
}
size_t& GetManagedRenderPipelineEnvironmentGenerationStorage() {
static size_t s_generation = 1u;
return s_generation;
}
} // namespace
ManagedScriptableRenderPipelineAsset::ManagedScriptableRenderPipelineAsset(
@@ -109,11 +114,13 @@ void SetManagedRenderPipelineBridge(
std::shared_ptr<const ManagedRenderPipelineBridge> bridge) {
GetManagedRenderPipelineBridgeStorage() = std::move(bridge);
++GetManagedRenderPipelineBridgeGenerationStorage();
++GetManagedRenderPipelineEnvironmentGenerationStorage();
}
void ClearManagedRenderPipelineBridge() {
GetManagedRenderPipelineBridgeStorage().reset();
++GetManagedRenderPipelineBridgeGenerationStorage();
++GetManagedRenderPipelineEnvironmentGenerationStorage();
}
std::shared_ptr<const ManagedRenderPipelineBridge>
@@ -121,13 +128,19 @@ GetManagedRenderPipelineBridge() {
return GetManagedRenderPipelineBridgeStorage();
}
size_t GetManagedRenderPipelineEnvironmentGeneration() {
return GetManagedRenderPipelineEnvironmentGenerationStorage();
}
void SetManagedRenderPipelineAssetDescriptor(
const ManagedRenderPipelineAssetDescriptor& descriptor) {
GetManagedRenderPipelineAssetDescriptorStorage() = descriptor;
++GetManagedRenderPipelineEnvironmentGenerationStorage();
}
void ClearManagedRenderPipelineAssetDescriptor() {
GetManagedRenderPipelineAssetDescriptorStorage() = {};
++GetManagedRenderPipelineEnvironmentGenerationStorage();
}
ManagedRenderPipelineAssetDescriptor GetManagedRenderPipelineAssetDescriptor() {