Move scene request planning behind pipeline asset
This commit is contained in:
@@ -52,8 +52,9 @@ Editor viewport 边界补充:SceneViewport 的 render request 是 editor 每
|
||||
|
||||
```text
|
||||
SceneRenderer
|
||||
-> SceneRenderRequestPlanner::BuildRequests
|
||||
-> RenderPipelineHost
|
||||
-> RenderPipelineAsset::BuildSceneRenderRequests
|
||||
-> (default) SceneRenderRequestPlanner::BuildRequests
|
||||
-> CameraFramePlanBuilder
|
||||
-> CameraRenderer
|
||||
-> DirectionalShadowRuntime
|
||||
@@ -66,9 +67,10 @@ SceneRenderer
|
||||
|
||||
职责边界:
|
||||
|
||||
- `SceneRenderer`:场景级入口,生成/排序 camera stack frame plans,并委托执行;不做 scene extraction,不发 draw call。
|
||||
- `SceneRenderRequestPlanner`:收集可用相机、推导 viewport / clear / camera stack / directional shadow request;不创建执行期临时资源。
|
||||
- `RenderPipelineHost`:把 requests 变成 frame plans / stack plans,稳定排序并驱动 `CameraRenderer`。
|
||||
- `SceneRenderer`:场景级 façade,只把 scene/override camera/context/surface 交给当前 pipeline host;不再直接拥有 top-level request planner。
|
||||
- `RenderPipelineAsset`:顶层 scene/camera request authority。`BuildSceneRenderRequests(...)` 是对齐 Unity `RenderPipeline.Render(...)` 入口责任的首个 native 合约面;未来所有 SRP/URP 级 camera policy、camera list 裁剪、renderer routing、tooling request 安装,都必须先经过这里。
|
||||
- `SceneRenderRequestPlanner`:默认 native planning utility。它负责收集可用相机、推导 viewport / clear / camera stack / directional shadow request;不再是顶层 authority,而是 `RenderPipelineAsset::BuildSceneRenderRequests(...)` 的默认 fallback 实现。
|
||||
- `RenderPipelineHost`:向当前 asset 请求 scene render requests,把 requests 变成 frame plans / stack plans,稳定排序并驱动 `CameraRenderer`。
|
||||
- `CameraFramePlanBuilder`:从 `CameraRenderRequest` 建 `CameraFramePlan`,调用 `RenderPipelineAsset::ConfigureCameraFramePlan`。
|
||||
- `CameraRenderer`:单相机执行器,校验 plan,解析 pipeline binding,生成 shadow execution state,抽取 `RenderSceneData`,交给 camera frame graph。
|
||||
- `RenderPipeline` / `RenderPipelineBackend`:提供 scene setup、shadow execution setup、stage graph recording、fallback render。
|
||||
@@ -98,7 +100,7 @@ SceneRenderer
|
||||
- `UsesGraphManagedSceneColor` 和 `UsesGraphManagedOutputColor(stage)` 决定是否创建 graph-managed transient color。
|
||||
- fullscreen stage 的 source 必须通过 `CameraFrameColorSource` 表达,不要用隐式全局变量猜输入。
|
||||
|
||||
不要绕过 `RenderPipelineAsset::ConfigureCameraRenderRequest` 和 `ConfigureCameraFramePlan`。它们是 SRP/URP asset policy 对齐 Unity 的核心 hook。
|
||||
不要绕过 `RenderPipelineAsset::BuildSceneRenderRequests`、`ConfigureCameraRenderRequest` 和 `ConfigureCameraFramePlan`。顶层 request ingress、per-request policy、per-plan policy 现在都要先经过 asset contract;这是 SRP/URP asset policy 对齐 Unity 的核心 hook 面。
|
||||
|
||||
## 4. Stage 模型
|
||||
|
||||
@@ -412,7 +414,7 @@ cmake --build build --config Debug --target rendering_phase_regression
|
||||
1. 稳住 native RenderGraph / RHI / scene backend。
|
||||
2. 让 managed SRP runtime 持有真实 asset / pipeline / renderer runtime。
|
||||
3. 扩大 `ScriptableRenderContext` 和 managed RenderGraph 的受控能力面。
|
||||
4. 把 URP-like 的 asset policy、renderer data、feature queue、render pass event、post/final/shadow policy 逐步上移到 managed。
|
||||
4. 把 URP-like 的 top-level scene request planning、asset policy、renderer data、feature queue、render pass event、post/final/shadow policy 逐步上移到 managed。
|
||||
5. 保持 `BuiltinForwardPipeline` 作为可被 SRP 调度的 native backend,而不是重新变回唯一上层管线。
|
||||
|
||||
一句话:XCEngine Rendering 的对齐目标是 Unity SRP/URP 的分层模型,不是复制 Unity 某个版本的源码细节。C++ 做执行内核,C# 做可编排管线,RenderGraph 做中间契约。
|
||||
|
||||
@@ -2,11 +2,17 @@
|
||||
|
||||
#include <XCEngine/Rendering/Execution/CameraStackFramePlan.h>
|
||||
#include <XCEngine/Rendering/Execution/CameraRenderer.h>
|
||||
#include <XCEngine/Rendering/Planning/SceneRenderRequestPlanner.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
class CameraComponent;
|
||||
class Scene;
|
||||
} // namespace Components
|
||||
|
||||
namespace Rendering {
|
||||
|
||||
class CameraFramePlanBuilder;
|
||||
@@ -20,9 +26,23 @@ public:
|
||||
void SetPipelineAsset(std::shared_ptr<const RenderPipelineAsset> pipelineAsset);
|
||||
RenderPipeline* GetPipeline() const { return m_cameraRenderer.GetPipeline(); }
|
||||
const RenderPipelineAsset* GetPipelineAsset() const { return m_cameraRenderer.GetPipelineAsset(); }
|
||||
void SetDirectionalShadowPlanningSettings(
|
||||
const DirectionalShadowPlanningSettings& settings);
|
||||
const DirectionalShadowPlanningSettings&
|
||||
GetDirectionalShadowPlanningSettings() const;
|
||||
|
||||
std::vector<CameraFramePlan> BuildFramePlans(
|
||||
const Components::Scene& scene,
|
||||
Components::CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface);
|
||||
std::vector<CameraFramePlan> BuildFramePlans(
|
||||
const std::vector<CameraRenderRequest>& requests);
|
||||
std::vector<CameraStackFramePlan> BuildStackFramePlans(
|
||||
const Components::Scene& scene,
|
||||
Components::CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface);
|
||||
std::vector<CameraStackFramePlan> BuildStackFramePlans(
|
||||
const std::vector<CameraRenderRequest>& requests);
|
||||
|
||||
@@ -32,8 +52,15 @@ public:
|
||||
bool Render(const std::vector<CameraStackFramePlan>& stackPlans);
|
||||
|
||||
private:
|
||||
std::vector<CameraRenderRequest> BuildSceneRenderRequests(
|
||||
const Components::Scene& scene,
|
||||
Components::CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface) const;
|
||||
|
||||
CameraRenderer m_cameraRenderer;
|
||||
std::unique_ptr<CameraFramePlanBuilder> m_framePlanBuilder;
|
||||
SceneRenderRequestPlanner m_requestPlanner;
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <XCEngine/Rendering/Execution/CameraStackFramePlan.h>
|
||||
#include <XCEngine/Rendering/Execution/RenderPipelineHost.h>
|
||||
#include <XCEngine/Rendering/Planning/SceneRenderRequestPlanner.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -23,6 +22,10 @@ public:
|
||||
void SetPipelineAsset(std::shared_ptr<const RenderPipelineAsset> pipelineAsset);
|
||||
RenderPipeline* GetPipeline() const { return m_pipelineHost.GetPipeline(); }
|
||||
const RenderPipelineAsset* GetPipelineAsset() const { return m_pipelineHost.GetPipelineAsset(); }
|
||||
void SetDirectionalShadowPlanningSettings(
|
||||
const DirectionalShadowPlanningSettings& settings);
|
||||
const DirectionalShadowPlanningSettings&
|
||||
GetDirectionalShadowPlanningSettings() const;
|
||||
|
||||
std::vector<CameraFramePlan> BuildFramePlans(
|
||||
const Components::Scene& scene,
|
||||
@@ -45,7 +48,6 @@ public:
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface);
|
||||
|
||||
SceneRenderRequestPlanner m_requestPlanner;
|
||||
RenderPipelineHost m_pipelineHost;
|
||||
};
|
||||
|
||||
|
||||
@@ -7,8 +7,14 @@
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
class CameraComponent;
|
||||
class Scene;
|
||||
} // namespace Components
|
||||
|
||||
namespace Rendering {
|
||||
|
||||
struct CameraFramePlan;
|
||||
@@ -68,6 +74,13 @@ public:
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderPipeline> CreatePipeline() const override;
|
||||
std::vector<CameraRenderRequest> BuildSceneRenderRequests(
|
||||
const Components::Scene& scene,
|
||||
Components::CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface,
|
||||
const DirectionalShadowPlanningSettings& directionalShadowSettings)
|
||||
const override;
|
||||
void ConfigureCameraRenderRequest(
|
||||
CameraRenderRequest& request,
|
||||
size_t renderedBaseCameraCount,
|
||||
@@ -99,6 +112,15 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual bool BuildSceneRenderRequests(
|
||||
const Components::Scene&,
|
||||
Components::CameraComponent*,
|
||||
const RenderContext&,
|
||||
const RenderSurface&,
|
||||
const DirectionalShadowPlanningSettings&,
|
||||
std::vector<CameraRenderRequest>&) const {
|
||||
return false;
|
||||
}
|
||||
virtual void ConfigureCameraRenderRequest(
|
||||
CameraRenderRequest&,
|
||||
size_t,
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/Planning/CameraRenderRequest.h>
|
||||
#include <XCEngine/Rendering/Planning/FinalColorSettings.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
class CameraComponent;
|
||||
class Scene;
|
||||
} // namespace Components
|
||||
|
||||
namespace Rendering {
|
||||
|
||||
struct CameraRenderRequest;
|
||||
struct CameraFramePlan;
|
||||
struct DirectionalShadowPlanningSettings;
|
||||
class RenderPipeline;
|
||||
class RenderSurface;
|
||||
struct RenderContext;
|
||||
|
||||
void ApplyDefaultRenderPipelineAssetCameraRenderRequestPolicy(
|
||||
CameraRenderRequest& request,
|
||||
@@ -35,6 +39,12 @@ public:
|
||||
|
||||
virtual std::unique_ptr<RenderPipeline> CreatePipeline() const = 0;
|
||||
virtual void ConfigurePipeline(RenderPipeline&) const {}
|
||||
virtual std::vector<CameraRenderRequest> BuildSceneRenderRequests(
|
||||
const Components::Scene& scene,
|
||||
Components::CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface,
|
||||
const DirectionalShadowPlanningSettings& directionalShadowSettings) const;
|
||||
virtual void ConfigureCameraRenderRequest(
|
||||
CameraRenderRequest& request,
|
||||
size_t renderedBaseCameraCount,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Rendering/Planning/CameraFramePlanBuilder.h"
|
||||
#include "Rendering/Planning/SceneRenderRequestUtils.h"
|
||||
#include "Rendering/RenderPipelineAsset.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
@@ -53,6 +54,53 @@ void RenderPipelineHost::SetPipelineAsset(std::shared_ptr<const RenderPipelineAs
|
||||
m_cameraRenderer.SetPipelineAsset(std::move(pipelineAsset));
|
||||
}
|
||||
|
||||
void RenderPipelineHost::SetDirectionalShadowPlanningSettings(
|
||||
const DirectionalShadowPlanningSettings& settings) {
|
||||
m_requestPlanner.SetDirectionalShadowPlanningSettings(
|
||||
settings);
|
||||
}
|
||||
|
||||
const DirectionalShadowPlanningSettings&
|
||||
RenderPipelineHost::GetDirectionalShadowPlanningSettings() const {
|
||||
return m_requestPlanner.GetDirectionalShadowPlanningSettings();
|
||||
}
|
||||
|
||||
std::vector<CameraRenderRequest> RenderPipelineHost::BuildSceneRenderRequests(
|
||||
const Components::Scene& scene,
|
||||
Components::CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface) const {
|
||||
if (const RenderPipelineAsset* const pipelineAsset =
|
||||
GetPipelineAsset();
|
||||
pipelineAsset != nullptr) {
|
||||
return pipelineAsset->BuildSceneRenderRequests(
|
||||
scene,
|
||||
overrideCamera,
|
||||
context,
|
||||
surface,
|
||||
m_requestPlanner.GetDirectionalShadowPlanningSettings());
|
||||
}
|
||||
|
||||
return m_requestPlanner.BuildRequests(
|
||||
scene,
|
||||
overrideCamera,
|
||||
context,
|
||||
surface);
|
||||
}
|
||||
|
||||
std::vector<CameraFramePlan> RenderPipelineHost::BuildFramePlans(
|
||||
const Components::Scene& scene,
|
||||
Components::CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface) {
|
||||
return BuildFramePlans(
|
||||
BuildSceneRenderRequests(
|
||||
scene,
|
||||
overrideCamera,
|
||||
context,
|
||||
surface));
|
||||
}
|
||||
|
||||
std::vector<CameraFramePlan> RenderPipelineHost::BuildFramePlans(
|
||||
const std::vector<CameraRenderRequest>& requests) {
|
||||
return m_framePlanBuilder != nullptr
|
||||
@@ -62,6 +110,19 @@ std::vector<CameraFramePlan> RenderPipelineHost::BuildFramePlans(
|
||||
: std::vector<CameraFramePlan>();
|
||||
}
|
||||
|
||||
std::vector<CameraStackFramePlan> RenderPipelineHost::BuildStackFramePlans(
|
||||
const Components::Scene& scene,
|
||||
Components::CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface) {
|
||||
return BuildStackFramePlans(
|
||||
BuildSceneRenderRequests(
|
||||
scene,
|
||||
overrideCamera,
|
||||
context,
|
||||
surface));
|
||||
}
|
||||
|
||||
std::vector<CameraStackFramePlan> RenderPipelineHost::BuildStackFramePlans(
|
||||
const std::vector<CameraRenderRequest>& requests) {
|
||||
return m_framePlanBuilder != nullptr
|
||||
|
||||
@@ -19,19 +19,27 @@ void SceneRenderer::SetPipelineAsset(std::shared_ptr<const RenderPipelineAsset>
|
||||
m_pipelineHost.SetPipelineAsset(std::move(pipelineAsset));
|
||||
}
|
||||
|
||||
void SceneRenderer::SetDirectionalShadowPlanningSettings(
|
||||
const DirectionalShadowPlanningSettings& settings) {
|
||||
m_pipelineHost.SetDirectionalShadowPlanningSettings(
|
||||
settings);
|
||||
}
|
||||
|
||||
const DirectionalShadowPlanningSettings&
|
||||
SceneRenderer::GetDirectionalShadowPlanningSettings() const {
|
||||
return m_pipelineHost.GetDirectionalShadowPlanningSettings();
|
||||
}
|
||||
|
||||
std::vector<CameraFramePlan> SceneRenderer::BuildFramePlans(
|
||||
const Components::Scene& scene,
|
||||
Components::CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface) {
|
||||
const std::vector<CameraRenderRequest> requests =
|
||||
m_requestPlanner.BuildRequests(
|
||||
scene,
|
||||
overrideCamera,
|
||||
context,
|
||||
surface,
|
||||
m_pipelineHost.GetPipelineAsset());
|
||||
return m_pipelineHost.BuildFramePlans(requests);
|
||||
return m_pipelineHost.BuildFramePlans(
|
||||
scene,
|
||||
overrideCamera,
|
||||
context,
|
||||
surface);
|
||||
}
|
||||
|
||||
std::vector<CameraStackFramePlan> SceneRenderer::BuildStackFramePlans(
|
||||
@@ -39,14 +47,11 @@ std::vector<CameraStackFramePlan> SceneRenderer::BuildStackFramePlans(
|
||||
Components::CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface) {
|
||||
const std::vector<CameraRenderRequest> requests =
|
||||
m_requestPlanner.BuildRequests(
|
||||
scene,
|
||||
overrideCamera,
|
||||
context,
|
||||
surface,
|
||||
m_pipelineHost.GetPipelineAsset());
|
||||
return m_pipelineHost.BuildStackFramePlans(requests);
|
||||
return m_pipelineHost.BuildStackFramePlans(
|
||||
scene,
|
||||
overrideCamera,
|
||||
context,
|
||||
surface);
|
||||
}
|
||||
|
||||
bool SceneRenderer::Render(const CameraFramePlan& plan) {
|
||||
|
||||
@@ -118,6 +118,36 @@ std::unique_ptr<RenderPipeline> ManagedScriptableRenderPipelineAsset::CreatePipe
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
std::vector<CameraRenderRequest>
|
||||
ManagedScriptableRenderPipelineAsset::BuildSceneRenderRequests(
|
||||
const Components::Scene& scene,
|
||||
Components::CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface,
|
||||
const DirectionalShadowPlanningSettings& directionalShadowSettings) const {
|
||||
if (const std::shared_ptr<const ManagedRenderPipelineAssetRuntime> runtime =
|
||||
ResolveManagedAssetRuntime();
|
||||
runtime != nullptr) {
|
||||
std::vector<CameraRenderRequest> requests;
|
||||
if (runtime->BuildSceneRenderRequests(
|
||||
scene,
|
||||
overrideCamera,
|
||||
context,
|
||||
surface,
|
||||
directionalShadowSettings,
|
||||
requests)) {
|
||||
return requests;
|
||||
}
|
||||
}
|
||||
|
||||
return RenderPipelineAsset::BuildSceneRenderRequests(
|
||||
scene,
|
||||
overrideCamera,
|
||||
context,
|
||||
surface,
|
||||
directionalShadowSettings);
|
||||
}
|
||||
|
||||
void ManagedScriptableRenderPipelineAsset::ConfigureCameraRenderRequest(
|
||||
CameraRenderRequest& request,
|
||||
size_t renderedBaseCameraCount,
|
||||
|
||||
@@ -95,6 +95,23 @@ void RenderPipelineAsset::ConfigureCameraRenderRequest(
|
||||
directionalShadowSettings);
|
||||
}
|
||||
|
||||
std::vector<CameraRenderRequest> RenderPipelineAsset::BuildSceneRenderRequests(
|
||||
const Components::Scene& scene,
|
||||
Components::CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface,
|
||||
const DirectionalShadowPlanningSettings& directionalShadowSettings) const {
|
||||
SceneRenderRequestPlanner requestPlanner = {};
|
||||
requestPlanner.SetDirectionalShadowPlanningSettings(
|
||||
directionalShadowSettings);
|
||||
return requestPlanner.BuildRequests(
|
||||
scene,
|
||||
overrideCamera,
|
||||
context,
|
||||
surface,
|
||||
this);
|
||||
}
|
||||
|
||||
void RenderPipelineAsset::ConfigureCameraFramePlan(CameraFramePlan& plan) const {
|
||||
ApplyDefaultRenderPipelineAssetCameraFramePlanPolicy(
|
||||
plan,
|
||||
|
||||
@@ -517,6 +517,7 @@ public:
|
||||
|
||||
struct MockPipelineAssetState {
|
||||
int createCalls = 0;
|
||||
int buildSceneRenderRequestsCalls = 0;
|
||||
int configureCameraRenderRequestCalls = 0;
|
||||
int configureCameraFramePlanCalls = 0;
|
||||
bool createNullPipeline = false;
|
||||
@@ -525,6 +526,12 @@ struct MockPipelineAssetState {
|
||||
RenderPipeline* lastCreatedPipeline = nullptr;
|
||||
FinalColorSettings defaultFinalColorSettings = {};
|
||||
std::function<void(RenderPipeline&)> configurePipeline = {};
|
||||
std::function<std::vector<CameraRenderRequest>(
|
||||
const Scene&,
|
||||
CameraComponent*,
|
||||
const RenderContext&,
|
||||
const RenderSurface&,
|
||||
const DirectionalShadowPlanningSettings&)> buildSceneRenderRequests = {};
|
||||
std::function<void(
|
||||
CameraRenderRequest&,
|
||||
size_t,
|
||||
@@ -858,6 +865,30 @@ public:
|
||||
return m_state->defaultFinalColorSettings;
|
||||
}
|
||||
|
||||
std::vector<CameraRenderRequest> BuildSceneRenderRequests(
|
||||
const Scene& scene,
|
||||
CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface,
|
||||
const DirectionalShadowPlanningSettings& directionalShadowSettings) const override {
|
||||
++m_state->buildSceneRenderRequestsCalls;
|
||||
if (m_state->buildSceneRenderRequests) {
|
||||
return m_state->buildSceneRenderRequests(
|
||||
scene,
|
||||
overrideCamera,
|
||||
context,
|
||||
surface,
|
||||
directionalShadowSettings);
|
||||
}
|
||||
|
||||
return RenderPipelineAsset::BuildSceneRenderRequests(
|
||||
scene,
|
||||
overrideCamera,
|
||||
context,
|
||||
surface,
|
||||
directionalShadowSettings);
|
||||
}
|
||||
|
||||
void ConfigureCameraRenderRequest(
|
||||
CameraRenderRequest& request,
|
||||
size_t renderedBaseCameraCount,
|
||||
@@ -896,6 +927,7 @@ private:
|
||||
|
||||
struct MockManagedRenderPipelineAssetRuntimeState {
|
||||
int createStageRecorderCalls = 0;
|
||||
int buildSceneRenderRequestsCalls = 0;
|
||||
int configureCameraRenderRequestCalls = 0;
|
||||
int getPipelineBackendAssetCalls = 0;
|
||||
int getDefaultFinalColorSettingsCalls = 0;
|
||||
@@ -909,6 +941,13 @@ struct MockManagedRenderPipelineAssetRuntimeState {
|
||||
pipelineBackendAssetPolicy =
|
||||
Pipelines::ManagedPipelineBackendAssetPolicy::Unspecified;
|
||||
std::shared_ptr<MockStageRecorderState> lastCreatedStageRecorderState;
|
||||
std::function<bool(
|
||||
const Scene&,
|
||||
CameraComponent*,
|
||||
const RenderContext&,
|
||||
const RenderSurface&,
|
||||
const DirectionalShadowPlanningSettings&,
|
||||
std::vector<CameraRenderRequest>&)> buildSceneRenderRequests = {};
|
||||
std::function<void(
|
||||
CameraRenderRequest&,
|
||||
size_t,
|
||||
@@ -932,6 +971,27 @@ public:
|
||||
m_state->lastCreatedStageRecorderState);
|
||||
}
|
||||
|
||||
bool BuildSceneRenderRequests(
|
||||
const Scene& scene,
|
||||
CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface,
|
||||
const DirectionalShadowPlanningSettings& directionalShadowSettings,
|
||||
std::vector<CameraRenderRequest>& requests) const override {
|
||||
++m_state->buildSceneRenderRequestsCalls;
|
||||
if (!m_state->buildSceneRenderRequests) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_state->buildSceneRenderRequests(
|
||||
scene,
|
||||
overrideCamera,
|
||||
context,
|
||||
surface,
|
||||
directionalShadowSettings,
|
||||
requests);
|
||||
}
|
||||
|
||||
void ConfigureCameraRenderRequest(
|
||||
CameraRenderRequest& request,
|
||||
size_t renderedBaseCameraCount,
|
||||
@@ -993,6 +1053,13 @@ struct MockManagedRenderPipelineBridgeState {
|
||||
Pipelines::ManagedPipelineBackendAssetPolicy
|
||||
pipelineBackendAssetPolicy =
|
||||
Pipelines::ManagedPipelineBackendAssetPolicy::Unspecified;
|
||||
std::function<bool(
|
||||
const Scene&,
|
||||
CameraComponent*,
|
||||
const RenderContext&,
|
||||
const RenderSurface&,
|
||||
const DirectionalShadowPlanningSettings&,
|
||||
std::vector<CameraRenderRequest>&)> buildSceneRenderRequests = {};
|
||||
std::function<void(
|
||||
CameraRenderRequest&,
|
||||
size_t,
|
||||
@@ -1026,6 +1093,8 @@ public:
|
||||
m_state->pipelineBackendAsset;
|
||||
m_state->lastCreatedRuntimeState->pipelineBackendAssetPolicy =
|
||||
m_state->pipelineBackendAssetPolicy;
|
||||
m_state->lastCreatedRuntimeState->buildSceneRenderRequests =
|
||||
m_state->buildSceneRenderRequests;
|
||||
m_state->lastCreatedRuntimeState->configureCameraRenderRequest =
|
||||
m_state->configureCameraRenderRequest;
|
||||
return std::make_shared<MockManagedRenderPipelineAssetRuntime>(
|
||||
@@ -3834,6 +3903,56 @@ TEST(SceneRenderer_Test, UsesPipelineAssetCameraRenderRequestConfigurationHook)
|
||||
EXPECT_FALSE(plans[0].directionalShadow.IsValid());
|
||||
}
|
||||
|
||||
TEST(SceneRenderer_Test, DelegatesSceneRequestPlanningToPipelineAssetAuthority) {
|
||||
Scene scene("SceneRendererAssetOwnedPlanningScene");
|
||||
|
||||
GameObject* firstCameraObject = scene.CreateGameObject("FirstCamera");
|
||||
auto* firstCamera = firstCameraObject->AddComponent<CameraComponent>();
|
||||
firstCamera->SetPrimary(true);
|
||||
firstCamera->SetDepth(1.0f);
|
||||
|
||||
GameObject* secondCameraObject = scene.CreateGameObject("SecondCamera");
|
||||
auto* secondCamera = secondCameraObject->AddComponent<CameraComponent>();
|
||||
secondCamera->SetPrimary(true);
|
||||
secondCamera->SetDepth(5.0f);
|
||||
|
||||
auto assetState = std::make_shared<MockPipelineAssetState>();
|
||||
assetState->buildSceneRenderRequests =
|
||||
[secondCamera](
|
||||
const Scene& scene,
|
||||
CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface,
|
||||
const DirectionalShadowPlanningSettings&) {
|
||||
EXPECT_EQ(overrideCamera, nullptr);
|
||||
|
||||
CameraRenderRequest request = {};
|
||||
request.scene = &scene;
|
||||
request.camera = secondCamera;
|
||||
request.context = context;
|
||||
request.surface = surface;
|
||||
request.cameraStackId = 7u;
|
||||
request.cameraDepth = secondCamera->GetDepth();
|
||||
request.cameraStackOrder = 0u;
|
||||
request.clearFlags = RenderClearFlags::All;
|
||||
return std::vector<CameraRenderRequest>{ request };
|
||||
};
|
||||
|
||||
SceneRenderer renderer(std::make_shared<MockPipelineAsset>(assetState));
|
||||
const std::vector<CameraFramePlan> plans =
|
||||
renderer.BuildFramePlans(
|
||||
scene,
|
||||
nullptr,
|
||||
CreateValidContext(),
|
||||
RenderSurface(640, 360));
|
||||
|
||||
ASSERT_EQ(plans.size(), 1u);
|
||||
EXPECT_EQ(assetState->buildSceneRenderRequestsCalls, 1);
|
||||
EXPECT_EQ(assetState->configureCameraRenderRequestCalls, 0);
|
||||
EXPECT_EQ(plans[0].request.camera, secondCamera);
|
||||
EXPECT_EQ(plans[0].request.cameraStackId, 7u);
|
||||
}
|
||||
|
||||
TEST(SceneRenderer_Test, BuildsFinalOutputRequestFromResolvedFinalColorPolicy) {
|
||||
Scene scene("SceneRendererFinalOutputScene");
|
||||
|
||||
@@ -5472,6 +5591,79 @@ TEST(ManagedScriptableRenderPipelineAsset_Test, ReusesManagedAssetRuntimeAcrossP
|
||||
Pipelines::ClearManagedRenderPipelineBridge();
|
||||
}
|
||||
|
||||
TEST(ManagedScriptableRenderPipelineAsset_Test, LetsManagedBridgeBuildSceneRenderRequests) {
|
||||
Pipelines::ClearManagedRenderPipelineBridge();
|
||||
|
||||
Scene scene("ManagedPipelineAssetBuildSceneRequests");
|
||||
|
||||
GameObject* firstCameraObject = scene.CreateGameObject("FirstCamera");
|
||||
auto* firstCamera = firstCameraObject->AddComponent<CameraComponent>();
|
||||
firstCamera->SetPrimary(true);
|
||||
firstCamera->SetDepth(1.0f);
|
||||
|
||||
GameObject* secondCameraObject = scene.CreateGameObject("SecondCamera");
|
||||
auto* secondCamera = secondCameraObject->AddComponent<CameraComponent>();
|
||||
secondCamera->SetPrimary(true);
|
||||
secondCamera->SetDepth(3.0f);
|
||||
|
||||
const Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = {
|
||||
"GameScripts",
|
||||
"Gameplay",
|
||||
"ManagedRenderPipelineProbeAsset"
|
||||
};
|
||||
|
||||
auto bridgeState = std::make_shared<MockManagedRenderPipelineBridgeState>();
|
||||
bridgeState->pipelineBackendAsset = std::make_shared<MockPipelineAsset>(
|
||||
std::make_shared<MockPipelineAssetState>());
|
||||
bridgeState->buildSceneRenderRequests =
|
||||
[secondCamera](
|
||||
const Scene& scene,
|
||||
CameraComponent* overrideCamera,
|
||||
const RenderContext& context,
|
||||
const RenderSurface& surface,
|
||||
const DirectionalShadowPlanningSettings&,
|
||||
std::vector<CameraRenderRequest>& requests) {
|
||||
EXPECT_EQ(overrideCamera, nullptr);
|
||||
|
||||
CameraRenderRequest request = {};
|
||||
request.scene = &scene;
|
||||
request.camera = secondCamera;
|
||||
request.context = context;
|
||||
request.surface = surface;
|
||||
request.cameraStackId = 9u;
|
||||
request.cameraDepth = secondCamera->GetDepth();
|
||||
request.cameraStackOrder = 0u;
|
||||
request.clearFlags = RenderClearFlags::All;
|
||||
requests = { request };
|
||||
return true;
|
||||
};
|
||||
|
||||
Pipelines::SetManagedRenderPipelineBridge(
|
||||
std::make_shared<MockManagedRenderPipelineBridge>(bridgeState));
|
||||
|
||||
Pipelines::ManagedScriptableRenderPipelineAsset asset(descriptor);
|
||||
const std::vector<CameraRenderRequest> requests =
|
||||
asset.BuildSceneRenderRequests(
|
||||
scene,
|
||||
nullptr,
|
||||
CreateValidContext(),
|
||||
RenderSurface(320, 180),
|
||||
DirectionalShadowPlanningSettings{});
|
||||
|
||||
ASSERT_NE(bridgeState->lastCreatedRuntimeState, nullptr);
|
||||
ASSERT_EQ(requests.size(), 1u);
|
||||
EXPECT_EQ(
|
||||
bridgeState->lastCreatedRuntimeState->buildSceneRenderRequestsCalls,
|
||||
1);
|
||||
EXPECT_EQ(
|
||||
bridgeState->lastCreatedRuntimeState->configureCameraRenderRequestCalls,
|
||||
0);
|
||||
EXPECT_EQ(requests[0].camera, secondCamera);
|
||||
EXPECT_EQ(requests[0].cameraStackId, 9u);
|
||||
|
||||
Pipelines::ClearManagedRenderPipelineBridge();
|
||||
}
|
||||
|
||||
TEST(ManagedScriptableRenderPipelineAsset_Test, RebindsManagedAssetRuntimeWhenBridgeChanges) {
|
||||
Pipelines::ClearManagedRenderPipelineBridge();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user