Add scriptable render pipeline host
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include <XCEngine/Rendering/Execution/CameraRenderer.h>
|
||||
#include <XCEngine/Rendering/Execution/RenderPipelineHost.h>
|
||||
#include <XCEngine/Rendering/Graph/RenderGraph.h>
|
||||
#include <XCEngine/Rendering/Pipelines/ScriptableRenderPipelineHost.h>
|
||||
#include <XCEngine/Rendering/RenderPipelineAsset.h>
|
||||
#include <XCEngine/Rendering/RenderSurface.h>
|
||||
#include <XCEngine/Rendering/Execution/SceneRenderer.h>
|
||||
@@ -861,6 +862,18 @@ RenderContext CreateValidContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
RenderSceneData CreateSceneDataForCamera(
|
||||
Scene&,
|
||||
CameraComponent& camera,
|
||||
const RenderSurface& surface) {
|
||||
RenderSceneData sceneData = {};
|
||||
sceneData.camera = &camera;
|
||||
sceneData.cameraData.viewportWidth = surface.GetRenderAreaWidth();
|
||||
sceneData.cameraData.viewportHeight = surface.GetRenderAreaHeight();
|
||||
sceneData.cameraData.clearFlags = RenderClearFlags::All;
|
||||
return sceneData;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(CameraRenderRequest_Test, ReportsFormalFrameStageContract) {
|
||||
@@ -3602,6 +3615,108 @@ TEST(RenderPipelineHost_Test, SortsManualFramePlansByDepthBeforeRendering) {
|
||||
EXPECT_EQ(state->renderedClearFlags[1], RenderClearFlags::None);
|
||||
}
|
||||
|
||||
TEST(ScriptableRenderPipelineHost_Test, ForwardsRendererLifetimeAndFrameRendering) {
|
||||
Scene scene("ScriptableRenderPipelineHostScene");
|
||||
|
||||
GameObject* cameraObject = scene.CreateGameObject("Camera");
|
||||
auto* camera = cameraObject->AddComponent<CameraComponent>();
|
||||
camera->SetPrimary(true);
|
||||
camera->SetDepth(2.0f);
|
||||
|
||||
auto initialState = std::make_shared<MockPipelineState>();
|
||||
auto replacementState = std::make_shared<MockPipelineState>();
|
||||
|
||||
{
|
||||
auto initialRenderer = std::make_unique<MockPipeline>(initialState);
|
||||
MockPipeline* initialRendererRaw = initialRenderer.get();
|
||||
Pipelines::ScriptableRenderPipelineHost host(std::move(initialRenderer));
|
||||
EXPECT_EQ(host.GetMainSceneRenderer(), initialRendererRaw);
|
||||
|
||||
auto replacementRenderer = std::make_unique<MockPipeline>(replacementState);
|
||||
MockPipeline* replacementRendererRaw = replacementRenderer.get();
|
||||
host.SetMainSceneRenderer(std::move(replacementRenderer));
|
||||
|
||||
EXPECT_EQ(initialState->shutdownCalls, 1);
|
||||
EXPECT_EQ(host.GetMainSceneRenderer(), replacementRendererRaw);
|
||||
|
||||
CameraRenderRequest request = {};
|
||||
request.scene = &scene;
|
||||
request.camera = camera;
|
||||
request.context = CreateValidContext();
|
||||
request.surface = RenderSurface(800, 600);
|
||||
request.cameraDepth = camera->GetDepth();
|
||||
request.clearFlags = RenderClearFlags::All;
|
||||
|
||||
RenderSceneData sceneData =
|
||||
CreateSceneDataForCamera(scene, *camera, request.surface);
|
||||
ASSERT_TRUE(host.Render(
|
||||
request.context,
|
||||
request.surface,
|
||||
sceneData));
|
||||
EXPECT_EQ(replacementState->renderCalls, 1);
|
||||
EXPECT_EQ(replacementState->lastSurfaceWidth, 800u);
|
||||
EXPECT_EQ(replacementState->lastSurfaceHeight, 600u);
|
||||
EXPECT_EQ(replacementState->lastCamera, camera);
|
||||
|
||||
replacementState->supportsMainSceneRenderGraph = true;
|
||||
RenderGraph graph = {};
|
||||
RenderGraphBuilder graphBuilder(graph);
|
||||
RenderGraphBlackboard blackboard = {};
|
||||
bool executionSucceeded = true;
|
||||
RenderSceneData graphSceneData =
|
||||
CreateSceneDataForCamera(scene, *camera, request.surface);
|
||||
const RenderPipelineMainSceneRenderGraphContext graphContext = {
|
||||
graphBuilder,
|
||||
"MainScene",
|
||||
request.context,
|
||||
graphSceneData,
|
||||
request.surface,
|
||||
nullptr,
|
||||
nullptr,
|
||||
XCEngine::RHI::ResourceStates::Common,
|
||||
{},
|
||||
{},
|
||||
&executionSucceeded,
|
||||
&blackboard
|
||||
};
|
||||
EXPECT_TRUE(host.SupportsMainSceneRenderGraph());
|
||||
EXPECT_TRUE(host.RecordMainSceneRenderGraph(graphContext));
|
||||
EXPECT_EQ(replacementState->recordMainSceneCalls, 1);
|
||||
}
|
||||
|
||||
EXPECT_EQ(initialState->shutdownCalls, 1);
|
||||
EXPECT_EQ(replacementState->shutdownCalls, 1);
|
||||
}
|
||||
|
||||
TEST(ScriptableRenderPipelineHostAsset_Test, CreatesHostFromRendererAssetAndForwardsDefaults) {
|
||||
auto assetState = std::make_shared<MockPipelineAssetState>();
|
||||
assetState->defaultFinalColorSettings.outputTransferMode =
|
||||
FinalColorOutputTransferMode::LinearToSRGB;
|
||||
assetState->defaultFinalColorSettings.exposureMode =
|
||||
FinalColorExposureMode::Fixed;
|
||||
assetState->defaultFinalColorSettings.exposureValue = 1.5f;
|
||||
|
||||
Pipelines::ScriptableRenderPipelineHostAsset asset(
|
||||
std::make_shared<MockPipelineAsset>(assetState));
|
||||
EXPECT_EQ(
|
||||
asset.GetDefaultFinalColorSettings().outputTransferMode,
|
||||
FinalColorOutputTransferMode::LinearToSRGB);
|
||||
EXPECT_EQ(
|
||||
asset.GetDefaultFinalColorSettings().exposureMode,
|
||||
FinalColorExposureMode::Fixed);
|
||||
EXPECT_FLOAT_EQ(
|
||||
asset.GetDefaultFinalColorSettings().exposureValue,
|
||||
1.5f);
|
||||
|
||||
std::unique_ptr<RenderPipeline> pipeline = asset.CreatePipeline();
|
||||
ASSERT_NE(pipeline, nullptr);
|
||||
auto* host =
|
||||
dynamic_cast<Pipelines::ScriptableRenderPipelineHost*>(pipeline.get());
|
||||
ASSERT_NE(host, nullptr);
|
||||
EXPECT_NE(host->GetMainSceneRenderer(), nullptr);
|
||||
EXPECT_EQ(assetState->createCalls, 1);
|
||||
}
|
||||
|
||||
TEST(SceneRenderer_Test, CreatesPipelineInstancesFromPipelineAssetsAndShutsDownReplacedPipelines) {
|
||||
Scene scene("SceneRendererAssetScene");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user