Separate request and frame-stage execution contracts
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/Execution/CameraFrameStage.h>
|
||||
#include <XCEngine/Rendering/Planning/CameraRenderRequest.h>
|
||||
|
||||
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;
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
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<CameraFrameStageInfo, 9> 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
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/Planning/CameraRenderRequest.h>
|
||||
#include <XCEngine/Rendering/Execution/FrameStageRenderRequest.h>
|
||||
#include <XCEngine/Rendering/Shadow/DirectionalShadowData.h>
|
||||
|
||||
namespace XCEngine {
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/FrameData/RenderCameraData.h>
|
||||
#include <XCEngine/Rendering/RenderPass.h>
|
||||
#include <XCEngine/Rendering/RenderSurface.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
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<RHI::RHIResourceView*>& 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<RHI::RHIResourceView*>& 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<RHI::RHIResourceView*>& 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
|
||||
@@ -1,13 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/FrameData/RenderCameraData.h>
|
||||
#include <XCEngine/Rendering/Execution/FrameStageRenderRequest.h>
|
||||
#include <XCEngine/Rendering/Planning/FinalColorSettings.h>
|
||||
#include <XCEngine/Rendering/RenderContext.h>
|
||||
#include <XCEngine/Rendering/RenderPass.h>
|
||||
#include <XCEngine/Rendering/RenderSurface.h>
|
||||
#include <XCEngine/Rendering/Shadow/DirectionalShadowData.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
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<CameraFrameStageInfo, 9> 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<RHI::RHIResourceView*>& 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<RHI::RHIResourceView*>& 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<RHI::RHIResourceView*>& 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 &&
|
||||
|
||||
@@ -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<XCEngine::RHI::RHIResourceView*>(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<XCEngine::RHI::RHIResourceView*>(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<CameraRenderRequest> 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<CameraRenderRequest> 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<CameraRenderRequest> 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<CameraRenderRequest> 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;
|
||||
|
||||
Reference in New Issue
Block a user