feat(rendering): add managed fullscreen stage planning seam
This commit is contained in:
@@ -776,6 +776,9 @@ struct MockManagedRenderPipelineBridgeState {
|
||||
int createStageRecorderCalls = 0;
|
||||
Pipelines::ManagedRenderPipelineAssetDescriptor lastDescriptor = {};
|
||||
std::shared_ptr<MockStageRecorderState> lastCreatedStageRecorderState;
|
||||
int configureCameraFramePlanCalls = 0;
|
||||
Pipelines::ManagedRenderPipelineAssetDescriptor lastPlanningDescriptor = {};
|
||||
std::function<void(CameraFramePlan&)> configureCameraFramePlan = {};
|
||||
};
|
||||
|
||||
class MockManagedRenderPipelineBridge final
|
||||
@@ -796,6 +799,16 @@ public:
|
||||
m_state->lastCreatedStageRecorderState);
|
||||
}
|
||||
|
||||
void ConfigureCameraFramePlan(
|
||||
const Pipelines::ManagedRenderPipelineAssetDescriptor& descriptor,
|
||||
CameraFramePlan& plan) const override {
|
||||
++m_state->configureCameraFramePlanCalls;
|
||||
m_state->lastPlanningDescriptor = descriptor;
|
||||
if (m_state->configureCameraFramePlan) {
|
||||
m_state->configureCameraFramePlan(plan);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<MockManagedRenderPipelineBridgeState> m_state;
|
||||
};
|
||||
@@ -4471,6 +4484,180 @@ TEST(ManagedScriptableRenderPipelineAsset_Test, CreatesHostWithStageRecorderFrom
|
||||
Pipelines::ClearManagedRenderPipelineBridge();
|
||||
}
|
||||
|
||||
TEST(ManagedScriptableRenderPipelineAsset_Test, LetsManagedBridgeRequestFullscreenStagesDuringPlanConfiguration) {
|
||||
Pipelines::ClearManagedRenderPipelineBridge();
|
||||
|
||||
const Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = {
|
||||
"GameScripts",
|
||||
"Gameplay",
|
||||
"ManagedPlannedFullscreenRenderPipelineProbeAsset"
|
||||
};
|
||||
auto bridgeState = std::make_shared<MockManagedRenderPipelineBridgeState>();
|
||||
bridgeState->configureCameraFramePlan = [](
|
||||
CameraFramePlan& plan) {
|
||||
plan.ClearFullscreenStage(CameraFrameStage::PostProcess);
|
||||
plan.ClearFullscreenStage(CameraFrameStage::FinalOutput);
|
||||
EXPECT_TRUE(
|
||||
plan.RequestFullscreenStage(
|
||||
CameraFrameStage::PostProcess,
|
||||
CameraFrameColorSource::MainSceneColor,
|
||||
true));
|
||||
EXPECT_TRUE(
|
||||
plan.RequestFullscreenStage(
|
||||
CameraFrameStage::FinalOutput,
|
||||
CameraFrameColorSource::PostProcessColor));
|
||||
};
|
||||
Pipelines::SetManagedRenderPipelineBridge(
|
||||
std::make_shared<MockManagedRenderPipelineBridge>(bridgeState));
|
||||
|
||||
auto allocationState = std::make_shared<MockShadowAllocationState>();
|
||||
MockShadowView colorView(
|
||||
allocationState,
|
||||
XCEngine::RHI::ResourceViewType::RenderTarget,
|
||||
XCEngine::RHI::Format::R8G8B8A8_UNorm,
|
||||
XCEngine::RHI::ResourceViewDimension::Texture2D);
|
||||
MockShadowView depthView(
|
||||
allocationState,
|
||||
XCEngine::RHI::ResourceViewType::DepthStencil,
|
||||
XCEngine::RHI::Format::D24_UNorm_S8_UInt,
|
||||
XCEngine::RHI::ResourceViewDimension::Texture2D);
|
||||
|
||||
CameraRenderRequest request = {};
|
||||
request.context = CreateValidContext();
|
||||
request.surface = RenderSurface(320, 180);
|
||||
request.surface.SetColorAttachment(&colorView);
|
||||
request.surface.SetDepthAttachment(&depthView);
|
||||
|
||||
CameraFramePlan plan = CameraFramePlan::FromRequest(request);
|
||||
Pipelines::ManagedScriptableRenderPipelineAsset asset(descriptor);
|
||||
asset.ConfigureCameraFramePlan(plan);
|
||||
|
||||
EXPECT_EQ(bridgeState->configureCameraFramePlanCalls, 1);
|
||||
EXPECT_EQ(bridgeState->lastPlanningDescriptor.assemblyName, "GameScripts");
|
||||
EXPECT_EQ(bridgeState->lastPlanningDescriptor.namespaceName, "Gameplay");
|
||||
EXPECT_EQ(
|
||||
bridgeState->lastPlanningDescriptor.className,
|
||||
"ManagedPlannedFullscreenRenderPipelineProbeAsset");
|
||||
EXPECT_TRUE(plan.IsFullscreenStageRequested(CameraFrameStage::PostProcess));
|
||||
EXPECT_TRUE(plan.IsFullscreenStageRequested(CameraFrameStage::FinalOutput));
|
||||
EXPECT_EQ(plan.postProcess.passes, nullptr);
|
||||
EXPECT_EQ(plan.finalOutput.passes, nullptr);
|
||||
EXPECT_TRUE(plan.UsesGraphManagedSceneColor());
|
||||
EXPECT_TRUE(plan.UsesGraphManagedOutputColor(CameraFrameStage::PostProcess));
|
||||
EXPECT_EQ(
|
||||
plan.ResolveStageColorSource(CameraFrameStage::PostProcess),
|
||||
CameraFrameColorSource::MainSceneColor);
|
||||
EXPECT_EQ(
|
||||
plan.ResolveStageColorSource(CameraFrameStage::FinalOutput),
|
||||
CameraFrameColorSource::PostProcessColor);
|
||||
EXPECT_TRUE(plan.IsPostProcessStageValid());
|
||||
EXPECT_TRUE(plan.IsFinalOutputStageValid());
|
||||
|
||||
Pipelines::ClearManagedRenderPipelineBridge();
|
||||
}
|
||||
|
||||
TEST(CameraRenderer_Test, RendersManagedRequestedPostProcessWithoutLegacySequence) {
|
||||
Scene scene("CameraRendererManagedRequestedPostProcessScene");
|
||||
|
||||
GameObject* cameraObject = scene.CreateGameObject("Camera");
|
||||
auto* camera = cameraObject->AddComponent<CameraComponent>();
|
||||
camera->SetPrimary(true);
|
||||
|
||||
auto state = std::make_shared<MockPipelineState>();
|
||||
state->supportsMainSceneRenderGraph = true;
|
||||
state->supportsPostProcessRenderGraph = true;
|
||||
CameraRenderer renderer(std::make_unique<MockPipeline>(state));
|
||||
|
||||
auto allocationState = std::make_shared<MockShadowAllocationState>();
|
||||
MockShadowDevice device(allocationState);
|
||||
MockShadowView colorView(
|
||||
allocationState,
|
||||
XCEngine::RHI::ResourceViewType::RenderTarget,
|
||||
XCEngine::RHI::Format::R8G8B8A8_UNorm,
|
||||
XCEngine::RHI::ResourceViewDimension::Texture2D);
|
||||
MockShadowView depthView(
|
||||
allocationState,
|
||||
XCEngine::RHI::ResourceViewType::DepthStencil,
|
||||
XCEngine::RHI::Format::D24_UNorm_S8_UInt,
|
||||
XCEngine::RHI::ResourceViewDimension::Texture2D);
|
||||
|
||||
CameraRenderRequest request = {};
|
||||
request.scene = &scene;
|
||||
request.camera = camera;
|
||||
request.context = CreateValidContext();
|
||||
request.context.device = &device;
|
||||
request.surface = RenderSurface(320, 180);
|
||||
request.surface.SetColorAttachment(&colorView);
|
||||
request.surface.SetDepthAttachment(&depthView);
|
||||
request.cameraDepth = camera->GetDepth();
|
||||
|
||||
CameraFramePlan plan = CameraFramePlan::FromRequest(request);
|
||||
ASSERT_TRUE(
|
||||
plan.RequestFullscreenStage(
|
||||
CameraFrameStage::PostProcess,
|
||||
CameraFrameColorSource::MainSceneColor,
|
||||
false));
|
||||
|
||||
ASSERT_TRUE(plan.IsFullscreenStageRequested(CameraFrameStage::PostProcess));
|
||||
ASSERT_EQ(plan.postProcess.passes, nullptr);
|
||||
ASSERT_TRUE(plan.IsPostProcessStageValid());
|
||||
ASSERT_TRUE(renderer.Render(plan));
|
||||
EXPECT_EQ(state->recordMainSceneCalls, 1);
|
||||
EXPECT_EQ(state->recordPostProcessCalls, 1);
|
||||
EXPECT_EQ(
|
||||
state->eventLog,
|
||||
(std::vector<std::string>{
|
||||
"pipelineGraph",
|
||||
"pipelineGraph" }));
|
||||
}
|
||||
|
||||
TEST(CameraRenderer_Test, RejectsManagedRequestedPostProcessWithoutSupportedStageRecorder) {
|
||||
Scene scene("CameraRendererManagedRequestedPostProcessUnsupportedScene");
|
||||
|
||||
GameObject* cameraObject = scene.CreateGameObject("Camera");
|
||||
auto* camera = cameraObject->AddComponent<CameraComponent>();
|
||||
camera->SetPrimary(true);
|
||||
|
||||
auto state = std::make_shared<MockPipelineState>();
|
||||
state->supportsMainSceneRenderGraph = true;
|
||||
CameraRenderer renderer(std::make_unique<MockPipeline>(state));
|
||||
|
||||
auto allocationState = std::make_shared<MockShadowAllocationState>();
|
||||
MockShadowDevice device(allocationState);
|
||||
MockShadowView colorView(
|
||||
allocationState,
|
||||
XCEngine::RHI::ResourceViewType::RenderTarget,
|
||||
XCEngine::RHI::Format::R8G8B8A8_UNorm,
|
||||
XCEngine::RHI::ResourceViewDimension::Texture2D);
|
||||
MockShadowView depthView(
|
||||
allocationState,
|
||||
XCEngine::RHI::ResourceViewType::DepthStencil,
|
||||
XCEngine::RHI::Format::D24_UNorm_S8_UInt,
|
||||
XCEngine::RHI::ResourceViewDimension::Texture2D);
|
||||
|
||||
CameraRenderRequest request = {};
|
||||
request.scene = &scene;
|
||||
request.camera = camera;
|
||||
request.context = CreateValidContext();
|
||||
request.context.device = &device;
|
||||
request.surface = RenderSurface(320, 180);
|
||||
request.surface.SetColorAttachment(&colorView);
|
||||
request.surface.SetDepthAttachment(&depthView);
|
||||
request.cameraDepth = camera->GetDepth();
|
||||
|
||||
CameraFramePlan plan = CameraFramePlan::FromRequest(request);
|
||||
ASSERT_TRUE(
|
||||
plan.RequestFullscreenStage(
|
||||
CameraFrameStage::PostProcess,
|
||||
CameraFrameColorSource::MainSceneColor,
|
||||
false));
|
||||
|
||||
ASSERT_TRUE(plan.IsPostProcessStageValid());
|
||||
EXPECT_FALSE(renderer.Render(plan));
|
||||
EXPECT_EQ(state->recordMainSceneCalls, 0);
|
||||
EXPECT_EQ(state->recordPostProcessCalls, 0);
|
||||
}
|
||||
|
||||
TEST(CameraRenderer_Test, DefaultPipelineAssetUsesManagedSelectionWhenPresent) {
|
||||
const Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = {
|
||||
"GameScripts",
|
||||
|
||||
Reference in New Issue
Block a user