diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 00abdac4..e4cbeb45 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -479,10 +479,12 @@ add_library(XCEngine STATIC ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Builtin/BuiltinPassMetadataUtils.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Builtin/BuiltinPassLayoutUtils.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Execution/CameraFramePlan.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Execution/CameraFrameStage.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Execution/CameraRenderer.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Execution/DirectionalShadowExecutionState.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Execution/DrawSettings.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Execution/FrameExecutionContext.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Execution/FrameStageRenderRequest.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Execution/ScenePhase.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Execution/SceneRenderer.h ${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/FrameData/CullingResults.h diff --git a/engine/include/XCEngine/Rendering/Execution/CameraFramePlan.h b/engine/include/XCEngine/Rendering/Execution/CameraFramePlan.h index 1d346816..1f19e7b5 100644 --- a/engine/include/XCEngine/Rendering/Execution/CameraFramePlan.h +++ b/engine/include/XCEngine/Rendering/Execution/CameraFramePlan.h @@ -1,5 +1,6 @@ #pragma once +#include #include namespace XCEngine { @@ -76,6 +77,21 @@ struct CameraFramePlan { } } + const ScenePassRenderRequest* GetScenePassRequest(CameraFrameStage stage) const { + switch (stage) { + case CameraFrameStage::ShadowCaster: + return &shadowCaster; + case CameraFrameStage::DepthOnly: + return &request.depthOnly; + default: + return nullptr; + } + } + + const ObjectIdRenderRequest* GetObjectIdRequest(CameraFrameStage stage) const { + return stage == CameraFrameStage::ObjectId ? &request.objectId : nullptr; + } + const RenderSurface& GetMainSceneSurface() const { if (postProcess.IsRequested()) { return postProcess.sourceSurface; diff --git a/engine/include/XCEngine/Rendering/Execution/CameraFrameStage.h b/engine/include/XCEngine/Rendering/Execution/CameraFrameStage.h new file mode 100644 index 00000000..6e1c0212 --- /dev/null +++ b/engine/include/XCEngine/Rendering/Execution/CameraFrameStage.h @@ -0,0 +1,65 @@ +#pragma once + +#include +#include + +namespace XCEngine { +namespace Rendering { + +enum class CameraFrameStage : uint8_t { + PreScenePasses, + ShadowCaster, + DepthOnly, + MainScene, + PostProcess, + FinalOutput, + ObjectId, + PostScenePasses, + OverlayPasses +}; + +struct CameraFrameStageInfo { + CameraFrameStage stage = CameraFrameStage::MainScene; + const char* name = ""; + bool runtimeStage = true; +}; + +inline constexpr std::array kOrderedCameraFrameStages = { { + { CameraFrameStage::PreScenePasses, "PreScenePasses", false }, + { CameraFrameStage::ShadowCaster, "ShadowCaster", true }, + { CameraFrameStage::DepthOnly, "DepthOnly", true }, + { CameraFrameStage::MainScene, "MainScene", true }, + { CameraFrameStage::PostProcess, "PostProcess", true }, + { CameraFrameStage::FinalOutput, "FinalOutput", true }, + { CameraFrameStage::ObjectId, "ObjectId", false }, + { CameraFrameStage::PostScenePasses, "PostScenePasses", false }, + { CameraFrameStage::OverlayPasses, "OverlayPasses", false } +} }; + +inline constexpr const char* GetCameraFrameStageName(CameraFrameStage stage) { + switch (stage) { + case CameraFrameStage::PreScenePasses: + return "PreScenePasses"; + case CameraFrameStage::ShadowCaster: + return "ShadowCaster"; + case CameraFrameStage::DepthOnly: + return "DepthOnly"; + case CameraFrameStage::MainScene: + return "MainScene"; + case CameraFrameStage::PostProcess: + return "PostProcess"; + case CameraFrameStage::FinalOutput: + return "FinalOutput"; + case CameraFrameStage::ObjectId: + return "ObjectId"; + case CameraFrameStage::PostScenePasses: + return "PostScenePasses"; + case CameraFrameStage::OverlayPasses: + return "OverlayPasses"; + default: + return "Unknown"; + } +} + +} // namespace Rendering +} // namespace XCEngine diff --git a/engine/include/XCEngine/Rendering/Execution/DirectionalShadowExecutionState.h b/engine/include/XCEngine/Rendering/Execution/DirectionalShadowExecutionState.h index 3ab80254..65db437c 100644 --- a/engine/include/XCEngine/Rendering/Execution/DirectionalShadowExecutionState.h +++ b/engine/include/XCEngine/Rendering/Execution/DirectionalShadowExecutionState.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include namespace XCEngine { diff --git a/engine/include/XCEngine/Rendering/Execution/FrameStageRenderRequest.h b/engine/include/XCEngine/Rendering/Execution/FrameStageRenderRequest.h new file mode 100644 index 00000000..079d8f1e --- /dev/null +++ b/engine/include/XCEngine/Rendering/Execution/FrameStageRenderRequest.h @@ -0,0 +1,116 @@ +#pragma once + +#include +#include +#include + +#include + +namespace XCEngine { +namespace RHI { +class RHIResourceView; +} // namespace RHI + +namespace Rendering { + +struct ScenePassRenderRequest { + RenderSurface surface; + RenderClearFlags clearFlags = RenderClearFlags::Depth; + bool hasClearColorOverride = false; + Math::Color clearColorOverride = Math::Color::Black(); + bool hasCameraDataOverride = false; + RenderCameraData cameraDataOverride = {}; + + bool IsRequested() const { + return surface.GetDepthAttachment() != nullptr || + !surface.GetColorAttachments().empty(); + } + + bool IsValid() const { + const std::vector& colorAttachments = surface.GetColorAttachments(); + return surface.GetDepthAttachment() != nullptr && + (colorAttachments.empty() || colorAttachments[0] != nullptr) && + surface.GetRenderAreaWidth() > 0 && + surface.GetRenderAreaHeight() > 0; + } +}; + +using DepthOnlyRenderRequest = ScenePassRenderRequest; +using ShadowCasterRenderRequest = ScenePassRenderRequest; + +inline bool HasValidColorTarget(const RenderSurface& surface) { + const std::vector& colorAttachments = surface.GetColorAttachments(); + return !colorAttachments.empty() && + colorAttachments[0] != nullptr && + surface.GetRenderAreaWidth() > 0 && + surface.GetRenderAreaHeight() > 0; +} + +inline bool HasValidSurfaceSampleDescription(const RenderSurface& surface) { + const uint32_t sampleCount = surface.GetSampleCount(); + const uint32_t sampleQuality = surface.GetSampleQuality(); + return sampleCount > 0u && + (sampleCount > 1u || sampleQuality == 0u); +} + +inline bool HasValidSingleSampleColorSource(const RenderSurface& surface) { + return HasValidColorTarget(surface) && + HasValidSurfaceSampleDescription(surface) && + surface.GetSampleCount() == 1u && + surface.GetSampleQuality() == 0u; +} + +struct ObjectIdRenderRequest { + RenderSurface surface; + + bool IsRequested() const { + return !surface.GetColorAttachments().empty(); + } + + bool IsValid() const { + const std::vector& colorAttachments = surface.GetColorAttachments(); + return !colorAttachments.empty() && + colorAttachments[0] != nullptr && + surface.GetDepthAttachment() != nullptr && + surface.GetRenderAreaWidth() > 0 && + surface.GetRenderAreaHeight() > 0; + } +}; + +struct FullscreenPassRenderRequest { + RenderSurface sourceSurface; + RHI::RHIResourceView* sourceColorView = nullptr; + RHI::ResourceStates sourceColorState = RHI::ResourceStates::Common; + RenderSurface destinationSurface; + RenderPassSequence* passes = nullptr; + + size_t GetPassCount() const { + return passes != nullptr ? passes->GetPassCount() : 0u; + } + + bool IsRequested() const { + return passes != nullptr; + } + + bool RequiresIntermediateSurface() const { + return GetPassCount() > 1u; + } + + bool IsValid() const { + const bool sourceStateIsUsable = + sourceSurface.IsAutoTransitionEnabled() || + sourceColorState == RHI::ResourceStates::PixelShaderResource; + return passes != nullptr && + HasValidSingleSampleColorSource(sourceSurface) && + sourceColorView != nullptr && + sourceStateIsUsable && + HasValidColorTarget(destinationSurface) && + HasValidSurfaceSampleDescription(destinationSurface); + } +}; + +using PostProcessRenderRequest = FullscreenPassRenderRequest; +using FinalOutputRenderRequest = FullscreenPassRenderRequest; + +} // namespace Rendering +} // namespace XCEngine diff --git a/engine/include/XCEngine/Rendering/Planning/CameraRenderRequest.h b/engine/include/XCEngine/Rendering/Planning/CameraRenderRequest.h index 8653d022..4eb2f723 100644 --- a/engine/include/XCEngine/Rendering/Planning/CameraRenderRequest.h +++ b/engine/include/XCEngine/Rendering/Planning/CameraRenderRequest.h @@ -1,13 +1,10 @@ #pragma once -#include +#include #include #include -#include -#include #include -#include #include namespace XCEngine { @@ -16,166 +13,8 @@ class CameraComponent; class Scene; } // namespace Components -namespace RHI { -class RHIResourceView; -} // namespace RHI - namespace Rendering { -enum class CameraFrameStage : uint8_t { - PreScenePasses, - ShadowCaster, - DepthOnly, - MainScene, - PostProcess, - FinalOutput, - ObjectId, - PostScenePasses, - OverlayPasses -}; - -struct CameraFrameStageInfo { - CameraFrameStage stage = CameraFrameStage::MainScene; - const char* name = ""; - bool runtimeStage = true; -}; - -inline constexpr std::array kOrderedCameraFrameStages = {{ - { CameraFrameStage::PreScenePasses, "PreScenePasses", false }, - { CameraFrameStage::ShadowCaster, "ShadowCaster", true }, - { CameraFrameStage::DepthOnly, "DepthOnly", true }, - { CameraFrameStage::MainScene, "MainScene", true }, - { CameraFrameStage::PostProcess, "PostProcess", true }, - { CameraFrameStage::FinalOutput, "FinalOutput", true }, - { CameraFrameStage::ObjectId, "ObjectId", false }, - { CameraFrameStage::PostScenePasses, "PostScenePasses", false }, - { CameraFrameStage::OverlayPasses, "OverlayPasses", false } -}}; - -inline constexpr const char* GetCameraFrameStageName(CameraFrameStage stage) { - switch (stage) { - case CameraFrameStage::PreScenePasses: - return "PreScenePasses"; - case CameraFrameStage::ShadowCaster: - return "ShadowCaster"; - case CameraFrameStage::DepthOnly: - return "DepthOnly"; - case CameraFrameStage::MainScene: - return "MainScene"; - case CameraFrameStage::PostProcess: - return "PostProcess"; - case CameraFrameStage::FinalOutput: - return "FinalOutput"; - case CameraFrameStage::ObjectId: - return "ObjectId"; - case CameraFrameStage::PostScenePasses: - return "PostScenePasses"; - case CameraFrameStage::OverlayPasses: - return "OverlayPasses"; - default: - return "Unknown"; - } -} - -struct ScenePassRenderRequest { - RenderSurface surface; - RenderClearFlags clearFlags = RenderClearFlags::Depth; - bool hasClearColorOverride = false; - Math::Color clearColorOverride = Math::Color::Black(); - bool hasCameraDataOverride = false; - RenderCameraData cameraDataOverride = {}; - - bool IsRequested() const { - return surface.GetDepthAttachment() != nullptr || - !surface.GetColorAttachments().empty(); - } - - bool IsValid() const { - const std::vector& colorAttachments = surface.GetColorAttachments(); - return surface.GetDepthAttachment() != nullptr && - (colorAttachments.empty() || colorAttachments[0] != nullptr) && - surface.GetRenderAreaWidth() > 0 && - surface.GetRenderAreaHeight() > 0; - } -}; - -using DepthOnlyRenderRequest = ScenePassRenderRequest; -using ShadowCasterRenderRequest = ScenePassRenderRequest; - -inline bool HasValidColorTarget(const RenderSurface& surface) { - const std::vector& colorAttachments = surface.GetColorAttachments(); - return !colorAttachments.empty() && - colorAttachments[0] != nullptr && - surface.GetRenderAreaWidth() > 0 && - surface.GetRenderAreaHeight() > 0; -} - -inline bool HasValidSurfaceSampleDescription(const RenderSurface& surface) { - const uint32_t sampleCount = surface.GetSampleCount(); - const uint32_t sampleQuality = surface.GetSampleQuality(); - return sampleCount > 0u && - (sampleCount > 1u || sampleQuality == 0u); -} - -inline bool HasValidSingleSampleColorSource(const RenderSurface& surface) { - return HasValidColorTarget(surface) && - HasValidSurfaceSampleDescription(surface) && - surface.GetSampleCount() == 1u && - surface.GetSampleQuality() == 0u; -} - -struct ObjectIdRenderRequest { - RenderSurface surface; - - bool IsRequested() const { - return !surface.GetColorAttachments().empty(); - } - - bool IsValid() const { - const std::vector& colorAttachments = surface.GetColorAttachments(); - return !colorAttachments.empty() && - colorAttachments[0] != nullptr && - surface.GetDepthAttachment() != nullptr && - surface.GetRenderAreaWidth() > 0 && - surface.GetRenderAreaHeight() > 0; - } -}; - -struct FullscreenPassRenderRequest { - RenderSurface sourceSurface; - RHI::RHIResourceView* sourceColorView = nullptr; - RHI::ResourceStates sourceColorState = RHI::ResourceStates::Common; - RenderSurface destinationSurface; - RenderPassSequence* passes = nullptr; - - size_t GetPassCount() const { - return passes != nullptr ? passes->GetPassCount() : 0u; - } - - bool IsRequested() const { - return passes != nullptr; - } - - bool RequiresIntermediateSurface() const { - return GetPassCount() > 1u; - } - - bool IsValid() const { - const bool sourceStateIsUsable = - sourceSurface.IsAutoTransitionEnabled() || - sourceColorState == RHI::ResourceStates::PixelShaderResource; - return passes != nullptr && - HasValidSingleSampleColorSource(sourceSurface) && - sourceColorView != nullptr && - sourceStateIsUsable && - HasValidColorTarget(destinationSurface) && - HasValidSurfaceSampleDescription(destinationSurface); - } -}; - -using PostProcessRenderRequest = FullscreenPassRenderRequest; -using FinalOutputRenderRequest = FullscreenPassRenderRequest; - struct CameraRenderRequest { const Components::Scene* scene = nullptr; Components::CameraComponent* camera = nullptr; @@ -197,147 +36,6 @@ struct CameraRenderRequest { RenderPassSequence* postScenePasses = nullptr; RenderPassSequence* overlayPasses = nullptr; - bool HasFrameStage(CameraFrameStage stage) const { - switch (stage) { - case CameraFrameStage::PreScenePasses: - return preScenePasses != nullptr; - case CameraFrameStage::ShadowCaster: - return shadowCaster.IsRequested() || directionalShadow.IsValid(); - case CameraFrameStage::DepthOnly: - return depthOnly.IsRequested(); - case CameraFrameStage::MainScene: - return true; - case CameraFrameStage::PostProcess: - return postProcess.IsRequested(); - case CameraFrameStage::FinalOutput: - return finalOutput.IsRequested(); - case CameraFrameStage::ObjectId: - return objectId.IsRequested(); - case CameraFrameStage::PostScenePasses: - return postScenePasses != nullptr; - case CameraFrameStage::OverlayPasses: - return overlayPasses != nullptr; - default: - return false; - } - } - - RenderPassSequence* GetPassSequence(CameraFrameStage stage) const { - switch (stage) { - case CameraFrameStage::PreScenePasses: - return preScenePasses; - case CameraFrameStage::PostProcess: - return postProcess.passes; - case CameraFrameStage::FinalOutput: - return finalOutput.passes; - case CameraFrameStage::PostScenePasses: - return postScenePasses; - case CameraFrameStage::OverlayPasses: - return overlayPasses; - default: - return nullptr; - } - } - - const ScenePassRenderRequest* GetScenePassRequest(CameraFrameStage stage) const { - switch (stage) { - case CameraFrameStage::ShadowCaster: - return &shadowCaster; - case CameraFrameStage::DepthOnly: - return &depthOnly; - default: - return nullptr; - } - } - - const ObjectIdRenderRequest* GetObjectIdRequest(CameraFrameStage stage) const { - return stage == CameraFrameStage::ObjectId ? &objectId : nullptr; - } - - const RenderSurface& GetMainSceneSurface() const { - if (postProcess.IsRequested()) { - return postProcess.sourceSurface; - } - - if (finalOutput.IsRequested()) { - return finalOutput.sourceSurface; - } - - return surface; - } - - const RenderSurface& GetFinalCompositedSurface() const { - if (finalOutput.IsRequested()) { - return finalOutput.destinationSurface; - } - - if (postProcess.IsRequested()) { - return postProcess.destinationSurface; - } - - return surface; - } - - const RenderSurface* GetOutputSurface(CameraFrameStage stage) const { - switch (stage) { - case CameraFrameStage::PreScenePasses: - case CameraFrameStage::MainScene: - return &GetMainSceneSurface(); - case CameraFrameStage::ShadowCaster: - return shadowCaster.IsRequested() ? &shadowCaster.surface : nullptr; - case CameraFrameStage::DepthOnly: - return depthOnly.IsRequested() ? &depthOnly.surface : nullptr; - case CameraFrameStage::PostProcess: - return postProcess.IsRequested() ? &postProcess.destinationSurface : nullptr; - case CameraFrameStage::FinalOutput: - return finalOutput.IsRequested() ? &finalOutput.destinationSurface : nullptr; - case CameraFrameStage::ObjectId: - return objectId.IsRequested() ? &objectId.surface : nullptr; - case CameraFrameStage::PostScenePasses: - case CameraFrameStage::OverlayPasses: - return &GetFinalCompositedSurface(); - default: - return nullptr; - } - } - - const RenderSurface* GetSourceSurface(CameraFrameStage stage) const { - switch (stage) { - case CameraFrameStage::PostProcess: - return postProcess.IsRequested() ? &postProcess.sourceSurface : nullptr; - case CameraFrameStage::FinalOutput: - return finalOutput.IsRequested() ? &finalOutput.sourceSurface : nullptr; - default: - return nullptr; - } - } - - RHI::RHIResourceView* GetSourceColorView(CameraFrameStage stage) const { - switch (stage) { - case CameraFrameStage::PostProcess: - return postProcess.IsRequested() ? postProcess.sourceColorView : nullptr; - case CameraFrameStage::FinalOutput: - return finalOutput.IsRequested() ? finalOutput.sourceColorView : nullptr; - default: - return nullptr; - } - } - - RHI::ResourceStates GetSourceColorState(CameraFrameStage stage) const { - switch (stage) { - case CameraFrameStage::PostProcess: - return postProcess.IsRequested() ? postProcess.sourceColorState : RHI::ResourceStates::Common; - case CameraFrameStage::FinalOutput: - return finalOutput.IsRequested() ? finalOutput.sourceColorState : RHI::ResourceStates::Common; - default: - return RHI::ResourceStates::Common; - } - } - - bool RequiresIntermediateSceneColor() const { - return postProcess.IsRequested() || finalOutput.IsRequested(); - } - bool IsValid() const { return scene != nullptr && camera != nullptr && diff --git a/tests/Rendering/unit/test_camera_scene_renderer.cpp b/tests/Rendering/unit/test_camera_scene_renderer.cpp index 967e9be0..002f9fc6 100644 --- a/tests/Rendering/unit/test_camera_scene_renderer.cpp +++ b/tests/Rendering/unit/test_camera_scene_renderer.cpp @@ -581,48 +581,49 @@ TEST(CameraRenderRequest_Test, ReportsFormalFrameStageContract) { EXPECT_STREQ(GetCameraFrameStageName(CameraFrameStage::FinalOutput), "FinalOutput"); 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::PostProcess)); - EXPECT_TRUE(request.HasFrameStage(CameraFrameStage::FinalOutput)); - EXPECT_TRUE(request.HasFrameStage(CameraFrameStage::ObjectId)); - EXPECT_TRUE(request.HasFrameStage(CameraFrameStage::PostScenePasses)); - EXPECT_TRUE(request.HasFrameStage(CameraFrameStage::OverlayPasses)); + const CameraFramePlan plan = CameraFramePlan::FromRequest(request); + EXPECT_TRUE(plan.HasFrameStage(CameraFrameStage::PreScenePasses)); + EXPECT_TRUE(plan.HasFrameStage(CameraFrameStage::ShadowCaster)); + EXPECT_TRUE(plan.HasFrameStage(CameraFrameStage::DepthOnly)); + EXPECT_TRUE(plan.HasFrameStage(CameraFrameStage::MainScene)); + EXPECT_TRUE(plan.HasFrameStage(CameraFrameStage::PostProcess)); + EXPECT_TRUE(plan.HasFrameStage(CameraFrameStage::FinalOutput)); + EXPECT_TRUE(plan.HasFrameStage(CameraFrameStage::ObjectId)); + EXPECT_TRUE(plan.HasFrameStage(CameraFrameStage::PostScenePasses)); + EXPECT_TRUE(plan.HasFrameStage(CameraFrameStage::OverlayPasses)); - EXPECT_EQ(request.GetPassSequence(CameraFrameStage::PreScenePasses), &prePasses); - EXPECT_EQ(request.GetPassSequence(CameraFrameStage::PostProcess), &postProcessPasses); - EXPECT_EQ(request.GetPassSequence(CameraFrameStage::FinalOutput), &finalOutputPasses); - 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); - EXPECT_TRUE(request.RequiresIntermediateSceneColor()); - EXPECT_EQ(request.GetMainSceneSurface().GetRenderAreaWidth(), 256u); - EXPECT_EQ(request.GetMainSceneSurface().GetRenderAreaHeight(), 128u); - EXPECT_EQ(request.GetFinalCompositedSurface().GetRenderAreaWidth(), 640u); - EXPECT_EQ(request.GetFinalCompositedSurface().GetRenderAreaHeight(), 360u); - ASSERT_NE(request.GetOutputSurface(CameraFrameStage::PostProcess), nullptr); - EXPECT_EQ(request.GetOutputSurface(CameraFrameStage::PostProcess)->GetRenderAreaWidth(), 512u); - ASSERT_NE(request.GetSourceSurface(CameraFrameStage::PostProcess), nullptr); - EXPECT_EQ(request.GetSourceSurface(CameraFrameStage::PostProcess)->GetRenderAreaWidth(), 256u); + EXPECT_EQ(plan.GetPassSequence(CameraFrameStage::PreScenePasses), &prePasses); + EXPECT_EQ(plan.GetPassSequence(CameraFrameStage::PostProcess), &postProcessPasses); + EXPECT_EQ(plan.GetPassSequence(CameraFrameStage::FinalOutput), &finalOutputPasses); + EXPECT_EQ(plan.GetPassSequence(CameraFrameStage::PostScenePasses), &postPasses); + EXPECT_EQ(plan.GetPassSequence(CameraFrameStage::OverlayPasses), &overlayPasses); + EXPECT_EQ(plan.GetScenePassRequest(CameraFrameStage::ShadowCaster), &plan.shadowCaster); + EXPECT_EQ(plan.GetScenePassRequest(CameraFrameStage::DepthOnly), &plan.request.depthOnly); + EXPECT_EQ(plan.GetScenePassRequest(CameraFrameStage::MainScene), nullptr); + EXPECT_EQ(plan.GetObjectIdRequest(CameraFrameStage::ObjectId), &plan.request.objectId); + EXPECT_EQ(plan.GetObjectIdRequest(CameraFrameStage::MainScene), nullptr); + EXPECT_TRUE(plan.RequiresIntermediateSceneColor()); + EXPECT_EQ(plan.GetMainSceneSurface().GetRenderAreaWidth(), 256u); + EXPECT_EQ(plan.GetMainSceneSurface().GetRenderAreaHeight(), 128u); + EXPECT_EQ(plan.GetFinalCompositedSurface().GetRenderAreaWidth(), 640u); + EXPECT_EQ(plan.GetFinalCompositedSurface().GetRenderAreaHeight(), 360u); + ASSERT_NE(plan.GetOutputSurface(CameraFrameStage::PostProcess), nullptr); + EXPECT_EQ(plan.GetOutputSurface(CameraFrameStage::PostProcess)->GetRenderAreaWidth(), 512u); + ASSERT_NE(plan.GetSourceSurface(CameraFrameStage::PostProcess), nullptr); + EXPECT_EQ(plan.GetSourceSurface(CameraFrameStage::PostProcess)->GetRenderAreaWidth(), 256u); EXPECT_EQ( - request.GetSourceColorView(CameraFrameStage::PostProcess), + plan.GetSourceColorView(CameraFrameStage::PostProcess), reinterpret_cast(20)); EXPECT_EQ( - request.GetSourceColorState(CameraFrameStage::PostProcess), + plan.GetSourceColorState(CameraFrameStage::PostProcess), XCEngine::RHI::ResourceStates::PixelShaderResource); - ASSERT_NE(request.GetSourceSurface(CameraFrameStage::FinalOutput), nullptr); - EXPECT_EQ(request.GetSourceSurface(CameraFrameStage::FinalOutput)->GetRenderAreaWidth(), 512u); + ASSERT_NE(plan.GetSourceSurface(CameraFrameStage::FinalOutput), nullptr); + EXPECT_EQ(plan.GetSourceSurface(CameraFrameStage::FinalOutput)->GetRenderAreaWidth(), 512u); EXPECT_EQ( - request.GetSourceColorView(CameraFrameStage::FinalOutput), + plan.GetSourceColorView(CameraFrameStage::FinalOutput), reinterpret_cast(40)); EXPECT_EQ( - request.GetSourceColorState(CameraFrameStage::FinalOutput), + plan.GetSourceColorState(CameraFrameStage::FinalOutput), XCEngine::RHI::ResourceStates::PixelShaderResource); } @@ -2334,8 +2335,9 @@ TEST(SceneRenderer_Test, ReusesTrackedSceneColorStateAcrossFramesWhenPostProcess std::vector firstFrameRequests = renderer.BuildRenderRequests(scene, nullptr, context, surface); ASSERT_EQ(firstFrameRequests.size(), 1u); + CameraFramePlan firstFramePlan = CameraFramePlan::FromRequest(firstFrameRequests[0]); EXPECT_EQ( - firstFrameRequests[0].GetMainSceneSurface().GetColorStateBefore(), + firstFramePlan.GetMainSceneSurface().GetColorStateBefore(), XCEngine::RHI::ResourceStates::Common); RenderPassSequence postProcessPasses; @@ -2347,11 +2349,12 @@ TEST(SceneRenderer_Test, ReusesTrackedSceneColorStateAcrossFramesWhenPostProcess const std::vector secondFrameRequests = renderer.BuildRenderRequests(scene, nullptr, context, surface); ASSERT_EQ(secondFrameRequests.size(), 1u); + const CameraFramePlan secondFramePlan = CameraFramePlan::FromRequest(secondFrameRequests[0]); EXPECT_EQ( - secondFrameRequests[0].GetMainSceneSurface().GetColorStateBefore(), + secondFramePlan.GetMainSceneSurface().GetColorStateBefore(), XCEngine::RHI::ResourceStates::PixelShaderResource); EXPECT_EQ( - secondFrameRequests[0].GetMainSceneSurface().GetColorStateAfter(), + secondFramePlan.GetMainSceneSurface().GetColorStateAfter(), XCEngine::RHI::ResourceStates::PixelShaderResource); delete depthView; @@ -2402,13 +2405,14 @@ TEST(SceneRenderer_Test, ReusesTrackedPostProcessOutputStateAcrossFramesWhenFina std::vector firstFrameRequests = renderer.BuildRenderRequests(scene, nullptr, context, surface); ASSERT_EQ(firstFrameRequests.size(), 1u); + CameraFramePlan firstFramePlan = CameraFramePlan::FromRequest(firstFrameRequests[0]); EXPECT_TRUE(firstFrameRequests[0].postProcess.IsRequested()); EXPECT_TRUE(firstFrameRequests[0].finalOutput.IsRequested()); EXPECT_EQ( - firstFrameRequests[0].GetMainSceneSurface().GetColorStateBefore(), + firstFramePlan.GetMainSceneSurface().GetColorStateBefore(), XCEngine::RHI::ResourceStates::Common); EXPECT_EQ( - firstFrameRequests[0].postProcess.destinationSurface.GetColorStateBefore(), + firstFramePlan.postProcess.destinationSurface.GetColorStateBefore(), XCEngine::RHI::ResourceStates::Common); RenderPassSequence postProcessPasses; @@ -2423,14 +2427,15 @@ TEST(SceneRenderer_Test, ReusesTrackedPostProcessOutputStateAcrossFramesWhenFina const std::vector secondFrameRequests = renderer.BuildRenderRequests(scene, nullptr, context, surface); ASSERT_EQ(secondFrameRequests.size(), 1u); + const CameraFramePlan secondFramePlan = CameraFramePlan::FromRequest(secondFrameRequests[0]); EXPECT_EQ( - secondFrameRequests[0].GetMainSceneSurface().GetColorStateBefore(), + secondFramePlan.GetMainSceneSurface().GetColorStateBefore(), XCEngine::RHI::ResourceStates::PixelShaderResource); EXPECT_EQ( - secondFrameRequests[0].postProcess.destinationSurface.GetColorStateBefore(), + secondFramePlan.postProcess.destinationSurface.GetColorStateBefore(), XCEngine::RHI::ResourceStates::PixelShaderResource); EXPECT_EQ( - secondFrameRequests[0].finalOutput.sourceSurface.GetColorStateBefore(), + secondFramePlan.finalOutput.sourceSurface.GetColorStateBefore(), XCEngine::RHI::ResourceStates::PixelShaderResource); delete depthView;