Formalize camera frame composition stages
This commit is contained in:
@@ -453,6 +453,58 @@ RenderContext CreateValidContext() {
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(CameraRenderRequest_Test, ReportsFormalFrameStageContract) {
|
||||
CameraRenderRequest request;
|
||||
|
||||
RenderPassSequence prePasses;
|
||||
RenderPassSequence postPasses;
|
||||
RenderPassSequence overlayPasses;
|
||||
request.preScenePasses = &prePasses;
|
||||
request.postScenePasses = &postPasses;
|
||||
request.overlayPasses = &overlayPasses;
|
||||
|
||||
request.directionalShadow.enabled = true;
|
||||
request.directionalShadow.mapWidth = 128;
|
||||
request.directionalShadow.mapHeight = 64;
|
||||
request.directionalShadow.cameraData.viewportWidth = 128;
|
||||
request.directionalShadow.cameraData.viewportHeight = 64;
|
||||
|
||||
request.depthOnly.surface = RenderSurface(96, 48);
|
||||
request.depthOnly.surface.SetDepthAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(1));
|
||||
|
||||
request.objectId.surface = RenderSurface(320, 180);
|
||||
request.objectId.surface.SetColorAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(2));
|
||||
request.objectId.surface.SetDepthAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(3));
|
||||
|
||||
ASSERT_EQ(kOrderedCameraFrameStages.size(), 7u);
|
||||
EXPECT_EQ(kOrderedCameraFrameStages[0].stage, CameraFrameStage::PreScenePasses);
|
||||
EXPECT_EQ(kOrderedCameraFrameStages[1].stage, CameraFrameStage::ShadowCaster);
|
||||
EXPECT_EQ(kOrderedCameraFrameStages[2].stage, CameraFrameStage::DepthOnly);
|
||||
EXPECT_EQ(kOrderedCameraFrameStages[3].stage, CameraFrameStage::MainScene);
|
||||
EXPECT_EQ(kOrderedCameraFrameStages[4].stage, CameraFrameStage::ObjectId);
|
||||
EXPECT_EQ(kOrderedCameraFrameStages[5].stage, CameraFrameStage::PostScenePasses);
|
||||
EXPECT_EQ(kOrderedCameraFrameStages[6].stage, CameraFrameStage::OverlayPasses);
|
||||
EXPECT_STREQ(GetCameraFrameStageName(CameraFrameStage::MainScene), "MainScene");
|
||||
EXPECT_STREQ(GetCameraFrameStageName(CameraFrameStage::OverlayPasses), "OverlayPasses");
|
||||
|
||||
EXPECT_TRUE(request.HasFrameStage(CameraFrameStage::PreScenePasses));
|
||||
EXPECT_TRUE(request.HasFrameStage(CameraFrameStage::ShadowCaster));
|
||||
EXPECT_TRUE(request.HasFrameStage(CameraFrameStage::DepthOnly));
|
||||
EXPECT_TRUE(request.HasFrameStage(CameraFrameStage::MainScene));
|
||||
EXPECT_TRUE(request.HasFrameStage(CameraFrameStage::ObjectId));
|
||||
EXPECT_TRUE(request.HasFrameStage(CameraFrameStage::PostScenePasses));
|
||||
EXPECT_TRUE(request.HasFrameStage(CameraFrameStage::OverlayPasses));
|
||||
|
||||
EXPECT_EQ(request.GetPassSequence(CameraFrameStage::PreScenePasses), &prePasses);
|
||||
EXPECT_EQ(request.GetPassSequence(CameraFrameStage::PostScenePasses), &postPasses);
|
||||
EXPECT_EQ(request.GetPassSequence(CameraFrameStage::OverlayPasses), &overlayPasses);
|
||||
EXPECT_EQ(request.GetScenePassRequest(CameraFrameStage::ShadowCaster), &request.shadowCaster);
|
||||
EXPECT_EQ(request.GetScenePassRequest(CameraFrameStage::DepthOnly), &request.depthOnly);
|
||||
EXPECT_EQ(request.GetScenePassRequest(CameraFrameStage::MainScene), nullptr);
|
||||
EXPECT_EQ(request.GetObjectIdRequest(CameraFrameStage::ObjectId), &request.objectId);
|
||||
EXPECT_EQ(request.GetObjectIdRequest(CameraFrameStage::MainScene), nullptr);
|
||||
}
|
||||
|
||||
TEST(CameraRenderer_Test, UsesOverrideCameraAndSurfaceSizeWhenSubmittingScene) {
|
||||
Scene scene("CameraRendererScene");
|
||||
|
||||
@@ -608,6 +660,72 @@ TEST(CameraRenderer_Test, ExecutesObjectIdPassBetweenPipelineAndPostPassesWhenRe
|
||||
"shutdown:pre" }));
|
||||
}
|
||||
|
||||
TEST(CameraRenderer_Test, ExecutesFormalFrameStagesInDocumentedOrder) {
|
||||
Scene scene("CameraRendererFormalFrameStageScene");
|
||||
|
||||
GameObject* cameraObject = scene.CreateGameObject("Camera");
|
||||
auto* camera = cameraObject->AddComponent<CameraComponent>();
|
||||
camera->SetPrimary(true);
|
||||
camera->SetDepth(3.0f);
|
||||
|
||||
auto state = std::make_shared<MockPipelineState>();
|
||||
CameraRenderer renderer(
|
||||
std::make_unique<MockPipeline>(state),
|
||||
std::make_unique<MockObjectIdPass>(state));
|
||||
|
||||
auto shadowPass = std::make_unique<MockScenePass>(state, "shadowCaster");
|
||||
renderer.SetShadowCasterPass(std::move(shadowPass));
|
||||
|
||||
auto depthPass = std::make_unique<MockScenePass>(state, "depthOnly");
|
||||
renderer.SetDepthOnlyPass(std::move(depthPass));
|
||||
|
||||
RenderPassSequence prePasses;
|
||||
prePasses.AddPass(std::make_unique<TrackingPass>(state, "pre"));
|
||||
|
||||
RenderPassSequence postPasses;
|
||||
postPasses.AddPass(std::make_unique<TrackingPass>(state, "post"));
|
||||
|
||||
RenderPassSequence overlayPasses;
|
||||
overlayPasses.AddPass(std::make_unique<TrackingPass>(state, "overlay"));
|
||||
|
||||
CameraRenderRequest request;
|
||||
request.scene = &scene;
|
||||
request.camera = camera;
|
||||
request.context = CreateValidContext();
|
||||
request.surface = RenderSurface(320, 180);
|
||||
request.cameraDepth = camera->GetDepth();
|
||||
request.preScenePasses = &prePasses;
|
||||
request.postScenePasses = &postPasses;
|
||||
request.overlayPasses = &overlayPasses;
|
||||
request.shadowCaster.surface = RenderSurface(128, 64);
|
||||
request.shadowCaster.surface.SetDepthAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(1));
|
||||
request.depthOnly.surface = RenderSurface(96, 48);
|
||||
request.depthOnly.surface.SetDepthAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(2));
|
||||
request.objectId.surface = RenderSurface(320, 180);
|
||||
request.objectId.surface.SetColorAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(3));
|
||||
request.objectId.surface.SetDepthAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(4));
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
EXPECT_EQ(
|
||||
state->eventLog,
|
||||
(std::vector<std::string>{
|
||||
"init:pre",
|
||||
"pre",
|
||||
"init:shadowCaster",
|
||||
"shadowCaster",
|
||||
"init:depthOnly",
|
||||
"depthOnly",
|
||||
"pipeline",
|
||||
"objectId",
|
||||
"init:post",
|
||||
"post",
|
||||
"init:overlay",
|
||||
"overlay",
|
||||
"shutdown:overlay",
|
||||
"shutdown:post",
|
||||
"shutdown:pre" }));
|
||||
}
|
||||
|
||||
TEST(CameraRenderer_Test, ExecutesShadowCasterAndDepthOnlyRequestsBeforeMainPipeline) {
|
||||
Scene scene("CameraRendererDepthAndShadowScene");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user