refactor(rendering): formalize camera frame stage contracts

This commit is contained in:
2026-04-15 15:14:06 +08:00
parent 3937badf37
commit 795eaf80df
16 changed files with 558 additions and 296 deletions

View File

@@ -1,6 +1,7 @@
#pragma once
#include <array>
#include <cstddef>
#include <cstdint>
namespace XCEngine {
@@ -18,6 +19,19 @@ enum class CameraFrameStage : uint8_t {
OverlayPasses
};
enum class CameraFrameStageExecutionKind : uint8_t {
Sequence,
StandalonePass,
MainScenePipeline
};
enum class CameraFrameStageRequestKind : uint8_t {
None,
ShadowCaster,
DepthOnly,
ObjectId
};
struct CameraFrameStageInfo {
CameraFrameStage stage = CameraFrameStage::MainScene;
const char* name = "";
@@ -36,6 +50,61 @@ inline constexpr std::array<CameraFrameStageInfo, 9> kOrderedCameraFrameStages =
{ CameraFrameStage::OverlayPasses, "OverlayPasses", false }
} };
inline constexpr size_t kCameraFrameStageCount = kOrderedCameraFrameStages.size();
inline constexpr size_t GetCameraFrameStageIndex(CameraFrameStage stage) {
return static_cast<size_t>(stage);
}
inline constexpr CameraFrameStageExecutionKind GetCameraFrameStageExecutionKind(
CameraFrameStage stage) {
switch (stage) {
case CameraFrameStage::PreScenePasses:
case CameraFrameStage::PostProcess:
case CameraFrameStage::FinalOutput:
case CameraFrameStage::PostScenePasses:
case CameraFrameStage::OverlayPasses:
return CameraFrameStageExecutionKind::Sequence;
case CameraFrameStage::ShadowCaster:
case CameraFrameStage::DepthOnly:
case CameraFrameStage::ObjectId:
return CameraFrameStageExecutionKind::StandalonePass;
default:
return CameraFrameStageExecutionKind::MainScenePipeline;
}
}
inline constexpr CameraFrameStageRequestKind GetCameraFrameStageRequestKind(
CameraFrameStage stage) {
switch (stage) {
case CameraFrameStage::ShadowCaster:
return CameraFrameStageRequestKind::ShadowCaster;
case CameraFrameStage::DepthOnly:
return CameraFrameStageRequestKind::DepthOnly;
case CameraFrameStage::ObjectId:
return CameraFrameStageRequestKind::ObjectId;
default:
return CameraFrameStageRequestKind::None;
}
}
inline constexpr bool IsCameraFrameSequenceStage(CameraFrameStage stage) {
return GetCameraFrameStageExecutionKind(stage) ==
CameraFrameStageExecutionKind::Sequence;
}
inline constexpr bool SupportsCameraFrameStandalonePass(CameraFrameStage stage) {
return GetCameraFrameStageExecutionKind(stage) ==
CameraFrameStageExecutionKind::StandalonePass;
}
inline constexpr bool IsCameraFrameScenePassRequestStage(CameraFrameStage stage) {
const CameraFrameStageRequestKind requestKind =
GetCameraFrameStageRequestKind(stage);
return requestKind == CameraFrameStageRequestKind::ShadowCaster ||
requestKind == CameraFrameStageRequestKind::DepthOnly;
}
inline constexpr const char* GetCameraFrameStageName(CameraFrameStage stage) {
switch (stage) {
case CameraFrameStage::PreScenePasses:

View File

@@ -2,7 +2,6 @@
#include <XCEngine/Rendering/Execution/CameraFramePlan.h>
#include <XCEngine/Rendering/Extraction/RenderSceneExtractor.h>
#include <XCEngine/Rendering/RenderPass.h>
#include <XCEngine/Rendering/RenderPipeline.h>
#include <memory>
@@ -30,23 +29,12 @@ public:
CameraRenderer();
explicit CameraRenderer(std::unique_ptr<RenderPipeline> pipeline);
explicit CameraRenderer(std::shared_ptr<const RenderPipelineAsset> pipelineAsset);
CameraRenderer(
std::unique_ptr<RenderPipeline> pipeline,
std::unique_ptr<RenderPass> objectIdPass,
std::unique_ptr<RenderPass> depthOnlyPass = nullptr,
std::unique_ptr<RenderPass> shadowCasterPass = nullptr);
~CameraRenderer();
void SetPipeline(std::unique_ptr<RenderPipeline> pipeline);
void SetPipelineAsset(std::shared_ptr<const RenderPipelineAsset> pipelineAsset);
void SetObjectIdPass(std::unique_ptr<RenderPass> objectIdPass);
void SetDepthOnlyPass(std::unique_ptr<RenderPass> depthOnlyPass);
void SetShadowCasterPass(std::unique_ptr<RenderPass> shadowCasterPass);
RenderPipeline* GetPipeline() const { return m_pipeline.get(); }
const RenderPipelineAsset* GetPipelineAsset() const { return m_pipelineAsset.get(); }
RenderPass* GetObjectIdPass() const { return m_objectIdPass.get(); }
RenderPass* GetDepthOnlyPass() const { return m_depthOnlyPass.get(); }
RenderPass* GetShadowCasterPass() const { return m_shadowCasterPass.get(); }
bool Render(const CameraFramePlan& plan);
@@ -64,9 +52,6 @@ private:
RenderSceneExtractor m_sceneExtractor;
std::shared_ptr<const RenderPipelineAsset> m_pipelineAsset;
std::unique_ptr<RenderPipeline> m_pipeline;
std::unique_ptr<RenderPass> m_objectIdPass;
std::unique_ptr<RenderPass> m_depthOnlyPass;
std::unique_ptr<RenderPass> m_shadowCasterPass;
std::unique_ptr<DirectionalShadowRuntime> m_directionalShadowRuntime;
};

View File

@@ -1,13 +1,17 @@
#pragma once
#include <XCEngine/Core/Containers/String.h>
#include <XCEngine/Rendering/Execution/CameraFrameStage.h>
#include <XCEngine/Rendering/Execution/CameraFrameRenderGraphFrameData.h>
#include <XCEngine/Rendering/Execution/FrameExecutionContext.h>
#include <XCEngine/Rendering/FrameData/RenderSceneData.h>
#include <XCEngine/Rendering/Graph/RenderGraphTypes.h>
#include <XCEngine/Rendering/RenderContext.h>
#include <XCEngine/Rendering/RenderPass.h>
#include <XCEngine/Rendering/RenderSurface.h>
#include <memory>
#include <array>
#include <vector>
namespace XCEngine {
@@ -61,6 +65,63 @@ public:
using RenderPipelineRenderer::Render;
~RenderPipeline() override = default;
void SetCameraFrameStandalonePass(
CameraFrameStage stage,
std::unique_ptr<RenderPass> pass) {
std::unique_ptr<RenderPass>* const passSlot =
ResolveCameraFrameStandalonePassSlot(stage);
if (passSlot == nullptr) {
return;
}
if (*passSlot != nullptr) {
(*passSlot)->Shutdown();
}
*passSlot = std::move(pass);
}
RenderPass* GetCameraFrameStandalonePass(CameraFrameStage stage) const {
const std::unique_ptr<RenderPass>* const passSlot =
ResolveCameraFrameStandalonePassSlot(stage);
return passSlot != nullptr
? passSlot->get()
: nullptr;
}
protected:
void ShutdownCameraFrameStandalonePasses() {
for (std::unique_ptr<RenderPass>& pass : m_cameraFrameStandalonePasses) {
if (pass != nullptr) {
pass->Shutdown();
}
}
}
private:
using CameraFrameStandalonePassStorage =
std::array<std::unique_ptr<RenderPass>, kCameraFrameStageCount>;
std::unique_ptr<RenderPass>* ResolveCameraFrameStandalonePassSlot(
CameraFrameStage stage) {
if (!SupportsCameraFrameStandalonePass(stage)) {
return nullptr;
}
return &m_cameraFrameStandalonePasses[GetCameraFrameStageIndex(stage)];
}
const std::unique_ptr<RenderPass>* ResolveCameraFrameStandalonePassSlot(
CameraFrameStage stage) const {
if (!SupportsCameraFrameStandalonePass(stage)) {
return nullptr;
}
return &m_cameraFrameStandalonePasses[GetCameraFrameStageIndex(stage)];
}
CameraFrameStandalonePassStorage m_cameraFrameStandalonePasses = {};
};
} // namespace Rendering