feat(rendering): add managed camera request planning seam

This commit is contained in:
2026-04-18 00:07:13 +08:00
parent fa9a5ffb00
commit a6c78af54c
11 changed files with 514 additions and 1 deletions

View File

@@ -774,8 +774,16 @@ private:
struct MockManagedRenderPipelineAssetRuntimeState {
int createStageRecorderCalls = 0;
int configureCameraRenderRequestCalls = 0;
int configureCameraFramePlanCalls = 0;
size_t lastRenderedBaseCameraCount = 0u;
size_t lastRenderedRequestCount = 0u;
std::shared_ptr<MockStageRecorderState> lastCreatedStageRecorderState;
std::function<void(
CameraRenderRequest&,
size_t,
size_t,
const DirectionalShadowPlanningSettings&)> configureCameraRenderRequest = {};
std::function<void(CameraFramePlan&)> configureCameraFramePlan = {};
};
@@ -795,6 +803,24 @@ public:
m_state->lastCreatedStageRecorderState);
}
void ConfigureCameraRenderRequest(
CameraRenderRequest& request,
size_t renderedBaseCameraCount,
size_t renderedRequestCount,
const DirectionalShadowPlanningSettings& directionalShadowSettings)
const override {
++m_state->configureCameraRenderRequestCalls;
m_state->lastRenderedBaseCameraCount = renderedBaseCameraCount;
m_state->lastRenderedRequestCount = renderedRequestCount;
if (m_state->configureCameraRenderRequest) {
m_state->configureCameraRenderRequest(
request,
renderedBaseCameraCount,
renderedRequestCount,
directionalShadowSettings);
}
}
void ConfigureCameraFramePlan(CameraFramePlan& plan) const override {
++m_state->configureCameraFramePlanCalls;
if (m_state->configureCameraFramePlan) {
@@ -810,6 +836,11 @@ struct MockManagedRenderPipelineBridgeState {
int createAssetRuntimeCalls = 0;
Pipelines::ManagedRenderPipelineAssetDescriptor lastDescriptor = {};
std::shared_ptr<MockManagedRenderPipelineAssetRuntimeState> lastCreatedRuntimeState;
std::function<void(
CameraRenderRequest&,
size_t,
size_t,
const DirectionalShadowPlanningSettings&)> configureCameraRenderRequest = {};
std::function<void(CameraFramePlan&)> configureCameraFramePlan = {};
};
@@ -828,6 +859,8 @@ public:
m_state->lastDescriptor = descriptor;
m_state->lastCreatedRuntimeState =
std::make_shared<MockManagedRenderPipelineAssetRuntimeState>();
m_state->lastCreatedRuntimeState->configureCameraRenderRequest =
m_state->configureCameraRenderRequest;
m_state->lastCreatedRuntimeState->configureCameraFramePlan =
m_state->configureCameraFramePlan;
return std::make_shared<MockManagedRenderPipelineAssetRuntime>(
@@ -4587,7 +4620,77 @@ TEST(ManagedScriptableRenderPipelineAsset_Test, LetsManagedBridgeRequestFullscre
Pipelines::ClearManagedRenderPipelineBridge();
}
TEST(ManagedScriptableRenderPipelineAsset_Test, ReusesManagedAssetRuntimeAcrossPipelineAndPlanRequests) {
TEST(ManagedScriptableRenderPipelineAsset_Test, LetsManagedBridgeConfigureCameraRenderRequests) {
Pipelines::ClearManagedRenderPipelineBridge();
Scene scene("ManagedRenderPipelineCameraRequestConfigurationScene");
GameObject* cameraObject = scene.CreateGameObject("Camera");
auto* camera = cameraObject->AddComponent<CameraComponent>();
camera->SetPrimary(true);
GameObject* lightObject = scene.CreateGameObject("Light");
auto* light = lightObject->AddComponent<LightComponent>();
light->SetLightType(LightType::Directional);
light->SetCastsShadows(true);
CameraRenderRequest baselineRequest = {};
baselineRequest.scene = &scene;
baselineRequest.camera = camera;
baselineRequest.surface = RenderSurface(320, 180);
ApplyDefaultRenderPipelineAssetCameraRenderRequestPolicy(
baselineRequest,
0u,
0u,
DirectionalShadowPlanningSettings{});
ASSERT_TRUE(baselineRequest.directionalShadow.IsValid());
const Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = {
"GameScripts",
"Gameplay",
"ManagedCameraRequestConfiguredRenderPipelineProbeAsset"
};
auto bridgeState = std::make_shared<MockManagedRenderPipelineBridgeState>();
bridgeState->configureCameraRenderRequest =
[](
CameraRenderRequest& request,
size_t,
size_t,
const DirectionalShadowPlanningSettings&) {
request.directionalShadow = {};
};
Pipelines::SetManagedRenderPipelineBridge(
std::make_shared<MockManagedRenderPipelineBridge>(bridgeState));
CameraRenderRequest request = {};
request.scene = &scene;
request.camera = camera;
request.surface = RenderSurface(320, 180);
Pipelines::ManagedScriptableRenderPipelineAsset asset(descriptor);
asset.ConfigureCameraRenderRequest(
request,
0u,
0u,
DirectionalShadowPlanningSettings{});
EXPECT_EQ(bridgeState->createAssetRuntimeCalls, 1);
ASSERT_NE(bridgeState->lastCreatedRuntimeState, nullptr);
EXPECT_EQ(
bridgeState->lastCreatedRuntimeState->configureCameraRenderRequestCalls,
1);
EXPECT_EQ(
bridgeState->lastCreatedRuntimeState->lastRenderedBaseCameraCount,
0u);
EXPECT_EQ(
bridgeState->lastCreatedRuntimeState->lastRenderedRequestCount,
0u);
EXPECT_FALSE(request.directionalShadow.IsValid());
Pipelines::ClearManagedRenderPipelineBridge();
}
TEST(ManagedScriptableRenderPipelineAsset_Test, ReusesManagedAssetRuntimeAcrossPipelineRequestAndPlanRequests) {
Pipelines::ClearManagedRenderPipelineBridge();
const Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = {
@@ -4623,12 +4726,20 @@ TEST(ManagedScriptableRenderPipelineAsset_Test, ReusesManagedAssetRuntimeAcrossP
CameraRenderRequest request = {};
request.surface = RenderSurface(128, 72);
asset.ConfigureCameraRenderRequest(
request,
1u,
2u,
DirectionalShadowPlanningSettings{});
CameraFramePlan firstPlan = CameraFramePlan::FromRequest(request);
CameraFramePlan secondPlan = CameraFramePlan::FromRequest(request);
asset.ConfigureCameraFramePlan(firstPlan);
asset.ConfigureCameraFramePlan(secondPlan);
EXPECT_EQ(bridgeState->createAssetRuntimeCalls, 1);
EXPECT_EQ(runtimeState->configureCameraRenderRequestCalls, 1);
EXPECT_EQ(runtimeState->lastRenderedBaseCameraCount, 1u);
EXPECT_EQ(runtimeState->lastRenderedRequestCount, 2u);
EXPECT_EQ(runtimeState->configureCameraFramePlanCalls, 2);
Pipelines::ClearManagedRenderPipelineBridge();