Remove scene viewport postprocess API from engine
This commit is contained in:
@@ -18,7 +18,6 @@ namespace XCEngine {
|
||||
namespace Editor {
|
||||
|
||||
struct SceneViewportRenderPlan {
|
||||
Rendering::BuiltinPostProcessRequest builtinPostProcess = {};
|
||||
Rendering::RenderPassSequence postScenePasses = {};
|
||||
Rendering::RenderPassSequence overlayPasses = {};
|
||||
bool hasClearColorOverride = true;
|
||||
@@ -105,7 +104,6 @@ inline void ApplySceneViewportRenderPlan(
|
||||
Rendering::CameraRenderRequest& request) {
|
||||
ApplySceneViewportRenderRequestSetup(
|
||||
targets,
|
||||
plan.builtinPostProcess.IsRequested() ? &plan.builtinPostProcess : nullptr,
|
||||
&plan.postScenePasses,
|
||||
request);
|
||||
|
||||
|
||||
@@ -115,11 +115,6 @@ inline ViewportRenderFallbackPolicy BuildGameViewportRenderFailurePolicy(
|
||||
return policy;
|
||||
}
|
||||
|
||||
struct SceneViewportBuiltinPostProcessBuildResult {
|
||||
Rendering::BuiltinPostProcessRequest request = {};
|
||||
const char* warningStatusText = nullptr;
|
||||
};
|
||||
|
||||
inline Rendering::Passes::InfiniteGridPassData BuildSceneViewportGridPassData(
|
||||
const SceneViewportOverlayData& overlay) {
|
||||
Rendering::Passes::InfiniteGridPassData data = {};
|
||||
@@ -144,50 +139,19 @@ inline Rendering::Passes::ObjectIdOutlineStyle BuildSceneViewportSelectionOutlin
|
||||
return style;
|
||||
}
|
||||
|
||||
inline SceneViewportBuiltinPostProcessBuildResult BuildSceneViewportBuiltinPostProcess(
|
||||
const SceneViewportOverlayData& overlay,
|
||||
const std::vector<uint64_t>& selectedObjectIds,
|
||||
bool hasObjectIdShaderView,
|
||||
bool debugSelectionMask = false) {
|
||||
SceneViewportBuiltinPostProcessBuildResult result = {};
|
||||
if (!overlay.valid) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result.request.gridPassData = BuildSceneViewportGridPassData(overlay);
|
||||
result.request.selectedObjectIds = selectedObjectIds;
|
||||
result.request.outlineStyle = BuildSceneViewportSelectionOutlineStyle(debugSelectionMask);
|
||||
|
||||
if (!selectedObjectIds.empty() &&
|
||||
!debugSelectionMask &&
|
||||
!hasObjectIdShaderView) {
|
||||
result.warningStatusText = "Scene object id shader view is unavailable";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void ApplySceneViewportRenderRequestSetup(
|
||||
const ViewportRenderTargets& targets,
|
||||
const Rendering::BuiltinPostProcessRequest* builtinPostProcess,
|
||||
Rendering::RenderPassSequence* postPasses,
|
||||
Rendering::CameraRenderRequest& request) {
|
||||
request.preScenePasses = nullptr;
|
||||
request.postScenePasses = nullptr;
|
||||
request.overlayPasses = nullptr;
|
||||
request.objectId = {};
|
||||
request.builtinPostProcess = {};
|
||||
|
||||
if (postPasses != nullptr && postPasses->GetPassCount() > 0) {
|
||||
request.postScenePasses = postPasses;
|
||||
}
|
||||
|
||||
if (builtinPostProcess != nullptr &&
|
||||
builtinPostProcess->IsRequested()) {
|
||||
request.builtinPostProcess = *builtinPostProcess;
|
||||
request.builtinPostProcess.objectIdTextureView = targets.objectIdShaderView;
|
||||
}
|
||||
|
||||
if (targets.objectIdView == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -361,14 +361,11 @@ add_library(XCEngine STATIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/SceneRenderer.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinObjectIdPass.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinInfiniteGridPass.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinPostProcessPassPlan.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinPostProcessPassSequenceBuilder.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/XCEngine/Rendering/Pipelines/BuiltinForwardPipeline.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/CameraRenderer.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Passes/BuiltinObjectIdPass.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Passes/BuiltinInfiniteGridPass.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Passes/BuiltinPostProcessPassSequenceBuilder.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/Passes/BuiltinObjectIdOutlinePass.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/RenderSurface.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Rendering/RenderSceneExtractor.cpp
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/Passes/BuiltinInfiniteGridPass.h>
|
||||
#include <XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass.h>
|
||||
#include <XCEngine/Rendering/RenderPass.h>
|
||||
#include <XCEngine/Rendering/RenderCameraData.h>
|
||||
#include <XCEngine/Rendering/RenderContext.h>
|
||||
@@ -32,24 +30,12 @@ struct ObjectIdRenderRequest {
|
||||
}
|
||||
};
|
||||
|
||||
struct BuiltinPostProcessRequest {
|
||||
Passes::InfiniteGridPassData gridPassData = {};
|
||||
RHI::RHIResourceView* objectIdTextureView = nullptr;
|
||||
std::vector<uint64_t> selectedObjectIds = {};
|
||||
Passes::ObjectIdOutlineStyle outlineStyle = {};
|
||||
|
||||
bool IsRequested() const {
|
||||
return gridPassData.valid || !selectedObjectIds.empty();
|
||||
}
|
||||
};
|
||||
|
||||
struct CameraRenderRequest {
|
||||
const Components::Scene* scene = nullptr;
|
||||
Components::CameraComponent* camera = nullptr;
|
||||
RenderContext context;
|
||||
RenderSurface surface;
|
||||
ObjectIdRenderRequest objectId;
|
||||
BuiltinPostProcessRequest builtinPostProcess;
|
||||
float cameraDepth = 0.0f;
|
||||
uint8_t cameraStackOrder = 0;
|
||||
RenderClearFlags clearFlags = RenderClearFlags::All;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <XCEngine/Rendering/CameraRenderRequest.h>
|
||||
#include <XCEngine/Rendering/ObjectIdPass.h>
|
||||
#include <XCEngine/Rendering/Passes/BuiltinPostProcessPassSequenceBuilder.h>
|
||||
#include <XCEngine/Rendering/RenderPipeline.h>
|
||||
|
||||
#include <memory>
|
||||
@@ -44,7 +43,6 @@ private:
|
||||
std::shared_ptr<const RenderPipelineAsset> m_pipelineAsset;
|
||||
std::unique_ptr<RenderPipeline> m_pipeline;
|
||||
std::unique_ptr<ObjectIdPass> m_objectIdPass;
|
||||
Passes::BuiltinPostProcessPassSequenceBuilder m_builtinPostProcessBuilder;
|
||||
};
|
||||
|
||||
} // namespace Rendering
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
namespace Passes {
|
||||
|
||||
enum class BuiltinPostProcessPassStep : uint8_t {
|
||||
ColorToRenderTarget,
|
||||
InfiniteGrid,
|
||||
SelectionOutline,
|
||||
ColorToShaderResource,
|
||||
SelectionMaskDebug
|
||||
};
|
||||
|
||||
struct BuiltinPostProcessPassPlanInput {
|
||||
bool hasGridOverlay = false;
|
||||
bool hasSelection = false;
|
||||
bool debugSelectionMask = false;
|
||||
bool hasObjectIdShaderView = false;
|
||||
};
|
||||
|
||||
struct BuiltinPostProcessPassPlan {
|
||||
bool valid = false;
|
||||
std::vector<BuiltinPostProcessPassStep> steps;
|
||||
};
|
||||
|
||||
inline BuiltinPostProcessPassPlan BuildBuiltinPostProcessPassPlan(
|
||||
const BuiltinPostProcessPassPlanInput& input) {
|
||||
BuiltinPostProcessPassPlan plan = {};
|
||||
plan.valid = true;
|
||||
|
||||
if (input.debugSelectionMask) {
|
||||
if (input.hasSelection && input.hasObjectIdShaderView) {
|
||||
plan.steps = {
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::SelectionMaskDebug,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
};
|
||||
return plan;
|
||||
}
|
||||
|
||||
if (input.hasGridOverlay) {
|
||||
plan.steps = {
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
};
|
||||
return plan;
|
||||
}
|
||||
|
||||
plan.valid = false;
|
||||
return plan;
|
||||
}
|
||||
|
||||
if (input.hasGridOverlay && input.hasSelection && input.hasObjectIdShaderView) {
|
||||
plan.steps = {
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::InfiniteGrid,
|
||||
BuiltinPostProcessPassStep::SelectionOutline,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
};
|
||||
return plan;
|
||||
}
|
||||
|
||||
if (input.hasGridOverlay) {
|
||||
plan.steps = {
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::InfiniteGrid,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
};
|
||||
return plan;
|
||||
}
|
||||
|
||||
if (input.hasSelection && input.hasObjectIdShaderView) {
|
||||
plan.steps = {
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::SelectionOutline,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
};
|
||||
return plan;
|
||||
}
|
||||
|
||||
plan.valid = false;
|
||||
return plan;
|
||||
}
|
||||
|
||||
} // namespace Passes
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
@@ -1,59 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/Rendering/Passes/BuiltinInfiniteGridPass.h>
|
||||
#include <XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass.h>
|
||||
#include <XCEngine/Rendering/RenderPass.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
namespace Passes {
|
||||
|
||||
struct BuiltinPostProcessPassSequenceInput {
|
||||
InfiniteGridPassData gridPassData = {};
|
||||
RHI::RHIResourceView* objectIdTextureView = nullptr;
|
||||
std::vector<uint64_t> selectedObjectIds = {};
|
||||
ObjectIdOutlineStyle outlineStyle = {};
|
||||
};
|
||||
|
||||
struct BuiltinPostProcessPassSequenceBuildResult {
|
||||
bool valid = false;
|
||||
bool missingObjectIdTextureViewForSelection = false;
|
||||
};
|
||||
|
||||
class BuiltinPostProcessPassSequenceBuilder {
|
||||
public:
|
||||
~BuiltinPostProcessPassSequenceBuilder();
|
||||
|
||||
void Shutdown();
|
||||
|
||||
BuiltinPostProcessPassSequenceBuildResult Build(
|
||||
const BuiltinPostProcessPassSequenceInput& input,
|
||||
RenderPassSequence& outSequence);
|
||||
|
||||
private:
|
||||
void AddColorToRenderTargetPass(RenderPassSequence& outSequence);
|
||||
void AddInfiniteGridPass(
|
||||
const InfiniteGridPassData& gridPassData,
|
||||
RenderPassSequence& outSequence);
|
||||
void AddSelectionOutlinePass(
|
||||
RHI::RHIResourceView* objectIdTextureView,
|
||||
const std::vector<uint64_t>& selectedObjectIds,
|
||||
const ObjectIdOutlineStyle& outlineStyle,
|
||||
RenderPassSequence& outSequence);
|
||||
void AddColorToShaderResourcePass(RenderPassSequence& outSequence);
|
||||
void AddSelectionMaskDebugPass(
|
||||
RHI::RHIResourceView* objectIdTextureView,
|
||||
const std::vector<uint64_t>& selectedObjectIds,
|
||||
const ObjectIdOutlineStyle& outlineStyle,
|
||||
RenderPassSequence& outSequence);
|
||||
|
||||
BuiltinInfiniteGridPass m_gridPass;
|
||||
BuiltinObjectIdOutlinePass m_outlinePass;
|
||||
};
|
||||
|
||||
} // namespace Passes
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
@@ -86,7 +86,6 @@ CameraRenderer::~CameraRenderer() {
|
||||
if (m_objectIdPass != nullptr) {
|
||||
m_objectIdPass->Shutdown();
|
||||
}
|
||||
m_builtinPostProcessBuilder.Shutdown();
|
||||
}
|
||||
|
||||
void CameraRenderer::SetPipeline(std::unique_ptr<RenderPipeline> pipeline) {
|
||||
@@ -136,12 +135,6 @@ bool CameraRenderer::Render(
|
||||
!request.objectId.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
if (request.builtinPostProcess.IsRequested() &&
|
||||
request.builtinPostProcess.objectIdTextureView != nullptr &&
|
||||
!request.objectId.IsRequested()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RenderSceneData sceneData = m_sceneExtractor.ExtractForCamera(
|
||||
*request.scene,
|
||||
*request.camera,
|
||||
@@ -201,37 +194,6 @@ bool CameraRenderer::Render(
|
||||
return false;
|
||||
}
|
||||
|
||||
RenderPassSequence builtinPostProcessPasses = {};
|
||||
bool builtinPostProcessPassesInitialized = false;
|
||||
if (request.builtinPostProcess.IsRequested()) {
|
||||
const Passes::BuiltinPostProcessPassSequenceBuildResult buildResult =
|
||||
m_builtinPostProcessBuilder.Build(
|
||||
{
|
||||
request.builtinPostProcess.gridPassData,
|
||||
request.builtinPostProcess.objectIdTextureView,
|
||||
request.builtinPostProcess.selectedObjectIds,
|
||||
request.builtinPostProcess.outlineStyle
|
||||
},
|
||||
builtinPostProcessPasses);
|
||||
if (!buildResult.valid ||
|
||||
!InitializePassSequence(
|
||||
&builtinPostProcessPasses,
|
||||
request.context,
|
||||
builtinPostProcessPassesInitialized)) {
|
||||
ShutdownPassSequence(request.postScenePasses, postScenePassesInitialized);
|
||||
ShutdownPassSequence(request.preScenePasses, preScenePassesInitialized);
|
||||
return false;
|
||||
}
|
||||
if (!builtinPostProcessPasses.Execute(passContext)) {
|
||||
ShutdownPassSequence(&builtinPostProcessPasses, builtinPostProcessPassesInitialized);
|
||||
ShutdownPassSequence(request.postScenePasses, postScenePassesInitialized);
|
||||
ShutdownPassSequence(request.preScenePasses, preScenePassesInitialized);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ShutdownPassSequence(&builtinPostProcessPasses, builtinPostProcessPassesInitialized);
|
||||
|
||||
bool overlayPassesInitialized = false;
|
||||
if (!InitializePassSequence(
|
||||
request.overlayPasses,
|
||||
|
||||
@@ -1,214 +0,0 @@
|
||||
#include "Rendering/Passes/BuiltinPostProcessPassSequenceBuilder.h"
|
||||
|
||||
#include "Rendering/Passes/BuiltinPostProcessPassPlan.h"
|
||||
|
||||
#include <XCEngine/Core/Math/Color.h>
|
||||
#include <XCEngine/RHI/RHICommandList.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
namespace Passes {
|
||||
|
||||
namespace {
|
||||
|
||||
class LambdaRenderPass final : public RenderPass {
|
||||
public:
|
||||
using ExecuteCallback = std::function<bool(const RenderPassContext&)>;
|
||||
|
||||
LambdaRenderPass(std::string name, ExecuteCallback executeCallback)
|
||||
: m_name(std::move(name))
|
||||
, m_executeCallback(std::move(executeCallback)) {
|
||||
}
|
||||
|
||||
const char* GetName() const override {
|
||||
return m_name.c_str();
|
||||
}
|
||||
|
||||
bool Execute(const RenderPassContext& context) override {
|
||||
return m_executeCallback != nullptr && m_executeCallback(context);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
ExecuteCallback m_executeCallback;
|
||||
};
|
||||
|
||||
template <typename Callback>
|
||||
std::unique_ptr<RenderPass> MakeLambdaRenderPass(const char* name, Callback&& callback) {
|
||||
return std::make_unique<LambdaRenderPass>(
|
||||
name,
|
||||
LambdaRenderPass::ExecuteCallback(std::forward<Callback>(callback)));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
BuiltinPostProcessPassSequenceBuilder::~BuiltinPostProcessPassSequenceBuilder() {
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void BuiltinPostProcessPassSequenceBuilder::Shutdown() {
|
||||
m_outlinePass.Shutdown();
|
||||
m_gridPass.Shutdown();
|
||||
}
|
||||
|
||||
BuiltinPostProcessPassSequenceBuildResult BuiltinPostProcessPassSequenceBuilder::Build(
|
||||
const BuiltinPostProcessPassSequenceInput& input,
|
||||
RenderPassSequence& outSequence) {
|
||||
BuiltinPostProcessPassSequenceBuildResult result = {};
|
||||
const bool hasSelection = !input.selectedObjectIds.empty();
|
||||
const bool hasObjectIdTextureView = input.objectIdTextureView != nullptr;
|
||||
|
||||
if (hasSelection && !hasObjectIdTextureView) {
|
||||
result.missingObjectIdTextureViewForSelection = true;
|
||||
}
|
||||
|
||||
const BuiltinPostProcessPassPlan plan = BuildBuiltinPostProcessPassPlan({
|
||||
input.gridPassData.valid,
|
||||
hasSelection,
|
||||
input.outlineStyle.debugSelectionMask,
|
||||
hasObjectIdTextureView
|
||||
});
|
||||
if (!plan.valid) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result.valid = true;
|
||||
for (const BuiltinPostProcessPassStep step : plan.steps) {
|
||||
switch (step) {
|
||||
case BuiltinPostProcessPassStep::ColorToRenderTarget:
|
||||
AddColorToRenderTargetPass(outSequence);
|
||||
break;
|
||||
case BuiltinPostProcessPassStep::InfiniteGrid:
|
||||
AddInfiniteGridPass(input.gridPassData, outSequence);
|
||||
break;
|
||||
case BuiltinPostProcessPassStep::SelectionOutline:
|
||||
AddSelectionOutlinePass(
|
||||
input.objectIdTextureView,
|
||||
input.selectedObjectIds,
|
||||
input.outlineStyle,
|
||||
outSequence);
|
||||
break;
|
||||
case BuiltinPostProcessPassStep::ColorToShaderResource:
|
||||
AddColorToShaderResourcePass(outSequence);
|
||||
break;
|
||||
case BuiltinPostProcessPassStep::SelectionMaskDebug:
|
||||
AddSelectionMaskDebugPass(
|
||||
input.objectIdTextureView,
|
||||
input.selectedObjectIds,
|
||||
input.outlineStyle,
|
||||
outSequence);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void BuiltinPostProcessPassSequenceBuilder::AddColorToRenderTargetPass(
|
||||
RenderPassSequence& outSequence) {
|
||||
outSequence.AddPass(MakeLambdaRenderPass(
|
||||
"SceneColorToRenderTarget",
|
||||
[](const RenderPassContext& context) {
|
||||
const std::vector<RHI::RHIResourceView*>& colorAttachments = context.surface.GetColorAttachments();
|
||||
if (colorAttachments.empty() || colorAttachments[0] == nullptr || context.renderContext.commandList == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
context.renderContext.commandList->TransitionBarrier(
|
||||
colorAttachments[0],
|
||||
context.surface.GetColorStateAfter(),
|
||||
RHI::ResourceStates::RenderTarget);
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
void BuiltinPostProcessPassSequenceBuilder::AddInfiniteGridPass(
|
||||
const InfiniteGridPassData& gridPassData,
|
||||
RenderPassSequence& outSequence) {
|
||||
outSequence.AddPass(MakeLambdaRenderPass(
|
||||
"SceneInfiniteGrid",
|
||||
[this, gridPassData](const RenderPassContext& context) {
|
||||
return m_gridPass.Render(
|
||||
context.renderContext,
|
||||
context.surface,
|
||||
gridPassData);
|
||||
}));
|
||||
}
|
||||
|
||||
void BuiltinPostProcessPassSequenceBuilder::AddSelectionOutlinePass(
|
||||
RHI::RHIResourceView* objectIdTextureView,
|
||||
const std::vector<uint64_t>& selectedObjectIds,
|
||||
const ObjectIdOutlineStyle& outlineStyle,
|
||||
RenderPassSequence& outSequence) {
|
||||
outSequence.AddPass(MakeLambdaRenderPass(
|
||||
"SceneSelectionOutline",
|
||||
[this, objectIdTextureView, selectedObjectIds, outlineStyle](const RenderPassContext& context) {
|
||||
return m_outlinePass.Render(
|
||||
context.renderContext,
|
||||
context.surface,
|
||||
objectIdTextureView,
|
||||
selectedObjectIds,
|
||||
outlineStyle);
|
||||
}));
|
||||
}
|
||||
|
||||
void BuiltinPostProcessPassSequenceBuilder::AddColorToShaderResourcePass(
|
||||
RenderPassSequence& outSequence) {
|
||||
outSequence.AddPass(MakeLambdaRenderPass(
|
||||
"SceneColorToShaderResource",
|
||||
[](const RenderPassContext& context) {
|
||||
const std::vector<RHI::RHIResourceView*>& colorAttachments = context.surface.GetColorAttachments();
|
||||
if (colorAttachments.empty() || colorAttachments[0] == nullptr || context.renderContext.commandList == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
context.renderContext.commandList->TransitionBarrier(
|
||||
colorAttachments[0],
|
||||
RHI::ResourceStates::RenderTarget,
|
||||
context.surface.GetColorStateAfter());
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
void BuiltinPostProcessPassSequenceBuilder::AddSelectionMaskDebugPass(
|
||||
RHI::RHIResourceView* objectIdTextureView,
|
||||
const std::vector<uint64_t>& selectedObjectIds,
|
||||
const ObjectIdOutlineStyle& outlineStyle,
|
||||
RenderPassSequence& outSequence) {
|
||||
outSequence.AddPass(MakeLambdaRenderPass(
|
||||
"SceneSelectionMaskDebug",
|
||||
[this, objectIdTextureView, selectedObjectIds, outlineStyle](const RenderPassContext& context) {
|
||||
const std::vector<RHI::RHIResourceView*>& colorAttachments = context.surface.GetColorAttachments();
|
||||
if (colorAttachments.empty() || colorAttachments[0] == nullptr || context.renderContext.commandList == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const float debugClearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
RHI::RHIResourceView* colorView = colorAttachments[0];
|
||||
context.renderContext.commandList->SetRenderTargets(
|
||||
1,
|
||||
&colorView,
|
||||
context.surface.GetDepthAttachment());
|
||||
context.renderContext.commandList->ClearRenderTarget(colorView, debugClearColor);
|
||||
|
||||
ObjectIdOutlineStyle debugStyle = outlineStyle;
|
||||
debugStyle.debugSelectionMask = true;
|
||||
return m_outlinePass.Render(
|
||||
context.renderContext,
|
||||
context.surface,
|
||||
objectIdTextureView,
|
||||
selectedObjectIds,
|
||||
debugStyle);
|
||||
}));
|
||||
}
|
||||
|
||||
} // namespace Passes
|
||||
} // namespace Rendering
|
||||
} // namespace XCEngine
|
||||
@@ -1,143 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <XCEngine/Rendering/Passes/BuiltinPostProcessPassPlan.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
using XCEngine::Rendering::Passes::BuildBuiltinPostProcessPassPlan;
|
||||
using XCEngine::Rendering::Passes::BuiltinPostProcessPassPlanInput;
|
||||
using XCEngine::Rendering::Passes::BuiltinPostProcessPassStep;
|
||||
|
||||
TEST(BuiltinPostProcessPassPlan_Test, ReturnsInvalidPlanWhenNoBuiltinEffectIsAvailable) {
|
||||
const auto plan = BuildBuiltinPostProcessPassPlan({});
|
||||
|
||||
EXPECT_FALSE(plan.valid);
|
||||
EXPECT_TRUE(plan.steps.empty());
|
||||
}
|
||||
|
||||
TEST(BuiltinPostProcessPassPlan_Test, BuildsGridOnlyPlanWhenNothingIsSelected) {
|
||||
BuiltinPostProcessPassPlanInput input = {};
|
||||
input.hasGridOverlay = true;
|
||||
|
||||
const auto plan = BuildBuiltinPostProcessPassPlan(input);
|
||||
|
||||
ASSERT_TRUE(plan.valid);
|
||||
EXPECT_EQ(
|
||||
plan.steps,
|
||||
(std::vector<BuiltinPostProcessPassStep>{
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::InfiniteGrid,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
}));
|
||||
}
|
||||
|
||||
TEST(BuiltinPostProcessPassPlan_Test, BuildsGridAndSelectionOutlinePlanWhenObjectIdShaderViewExists) {
|
||||
BuiltinPostProcessPassPlanInput input = {};
|
||||
input.hasGridOverlay = true;
|
||||
input.hasSelection = true;
|
||||
input.hasObjectIdShaderView = true;
|
||||
|
||||
const auto plan = BuildBuiltinPostProcessPassPlan(input);
|
||||
|
||||
ASSERT_TRUE(plan.valid);
|
||||
EXPECT_EQ(
|
||||
plan.steps,
|
||||
(std::vector<BuiltinPostProcessPassStep>{
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::InfiniteGrid,
|
||||
BuiltinPostProcessPassStep::SelectionOutline,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
}));
|
||||
}
|
||||
|
||||
TEST(BuiltinPostProcessPassPlan_Test, SkipsSelectionOutlineWhenObjectIdShaderViewIsMissingAndGridExists) {
|
||||
BuiltinPostProcessPassPlanInput input = {};
|
||||
input.hasGridOverlay = true;
|
||||
input.hasSelection = true;
|
||||
|
||||
const auto plan = BuildBuiltinPostProcessPassPlan(input);
|
||||
|
||||
ASSERT_TRUE(plan.valid);
|
||||
EXPECT_EQ(
|
||||
plan.steps,
|
||||
(std::vector<BuiltinPostProcessPassStep>{
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::InfiniteGrid,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
}));
|
||||
}
|
||||
|
||||
TEST(BuiltinPostProcessPassPlan_Test, BuildsDebugMaskPlanFromObjectIdShaderView) {
|
||||
BuiltinPostProcessPassPlanInput input = {};
|
||||
input.hasGridOverlay = true;
|
||||
input.hasSelection = true;
|
||||
input.debugSelectionMask = true;
|
||||
input.hasObjectIdShaderView = true;
|
||||
|
||||
const auto plan = BuildBuiltinPostProcessPassPlan(input);
|
||||
|
||||
ASSERT_TRUE(plan.valid);
|
||||
EXPECT_EQ(
|
||||
plan.steps,
|
||||
(std::vector<BuiltinPostProcessPassStep>{
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::SelectionMaskDebug,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
}));
|
||||
}
|
||||
|
||||
TEST(BuiltinPostProcessPassPlan_Test, DebugMaskPlanFallsBackToTransitionsWhenGridExistsButObjectIdShaderViewIsMissing) {
|
||||
BuiltinPostProcessPassPlanInput input = {};
|
||||
input.hasGridOverlay = true;
|
||||
input.hasSelection = true;
|
||||
input.debugSelectionMask = true;
|
||||
|
||||
const auto plan = BuildBuiltinPostProcessPassPlan(input);
|
||||
|
||||
ASSERT_TRUE(plan.valid);
|
||||
EXPECT_EQ(
|
||||
plan.steps,
|
||||
(std::vector<BuiltinPostProcessPassStep>{
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
}));
|
||||
}
|
||||
|
||||
TEST(BuiltinPostProcessPassPlan_Test, BuildsSelectionOnlyOutlinePlanWhenGridOverlayIsUnavailable) {
|
||||
BuiltinPostProcessPassPlanInput input = {};
|
||||
input.hasSelection = true;
|
||||
input.hasObjectIdShaderView = true;
|
||||
|
||||
const auto plan = BuildBuiltinPostProcessPassPlan(input);
|
||||
|
||||
ASSERT_TRUE(plan.valid);
|
||||
EXPECT_EQ(
|
||||
plan.steps,
|
||||
(std::vector<BuiltinPostProcessPassStep>{
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::SelectionOutline,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
}));
|
||||
}
|
||||
|
||||
TEST(BuiltinPostProcessPassPlan_Test, BuildsDebugMaskWithoutGridWhenObjectIdShaderViewExists) {
|
||||
BuiltinPostProcessPassPlanInput input = {};
|
||||
input.hasSelection = true;
|
||||
input.debugSelectionMask = true;
|
||||
input.hasObjectIdShaderView = true;
|
||||
|
||||
const auto plan = BuildBuiltinPostProcessPassPlan(input);
|
||||
|
||||
ASSERT_TRUE(plan.valid);
|
||||
EXPECT_EQ(
|
||||
plan.steps,
|
||||
(std::vector<BuiltinPostProcessPassStep>{
|
||||
BuiltinPostProcessPassStep::ColorToRenderTarget,
|
||||
BuiltinPostProcessPassStep::SelectionMaskDebug,
|
||||
BuiltinPostProcessPassStep::ColorToShaderResource
|
||||
}));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -1,109 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <XCEngine/Rendering/Passes/BuiltinPostProcessPassSequenceBuilder.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using XCEngine::Rendering::Passes::BuiltinPostProcessPassSequenceBuilder;
|
||||
using XCEngine::Rendering::Passes::BuiltinPostProcessPassSequenceInput;
|
||||
using XCEngine::Rendering::Passes::ObjectIdOutlineStyle;
|
||||
using XCEngine::Rendering::RenderPassSequence;
|
||||
|
||||
TEST(BuiltinPostProcessPassSequenceBuilder_Test, ReturnsInvalidSequenceWhenNoBuiltinEffectIsRequested) {
|
||||
BuiltinPostProcessPassSequenceBuilder builder;
|
||||
RenderPassSequence sequence;
|
||||
|
||||
const auto result = builder.Build({}, sequence);
|
||||
|
||||
EXPECT_FALSE(result.valid);
|
||||
EXPECT_FALSE(result.missingObjectIdTextureViewForSelection);
|
||||
EXPECT_EQ(sequence.GetPassCount(), 0u);
|
||||
}
|
||||
|
||||
TEST(BuiltinPostProcessPassSequenceBuilder_Test, BuildsGridOnlySequenceWhenNothingIsSelected) {
|
||||
BuiltinPostProcessPassSequenceBuilder builder;
|
||||
RenderPassSequence sequence;
|
||||
BuiltinPostProcessPassSequenceInput input = {};
|
||||
input.gridPassData.valid = true;
|
||||
|
||||
const auto result = builder.Build(input, sequence);
|
||||
|
||||
EXPECT_TRUE(result.valid);
|
||||
EXPECT_FALSE(result.missingObjectIdTextureViewForSelection);
|
||||
EXPECT_EQ(sequence.GetPassCount(), 3u);
|
||||
}
|
||||
|
||||
TEST(BuiltinPostProcessPassSequenceBuilder_Test, BuildsGridAndSelectionOutlineSequenceWhenObjectIdTextureViewExists) {
|
||||
BuiltinPostProcessPassSequenceBuilder builder;
|
||||
RenderPassSequence sequence;
|
||||
BuiltinPostProcessPassSequenceInput input = {};
|
||||
input.gridPassData.valid = true;
|
||||
input.objectIdTextureView = reinterpret_cast<XCEngine::RHI::RHIResourceView*>(1);
|
||||
input.selectedObjectIds = { 7u, 11u };
|
||||
|
||||
const auto result = builder.Build(input, sequence);
|
||||
|
||||
EXPECT_TRUE(result.valid);
|
||||
EXPECT_FALSE(result.missingObjectIdTextureViewForSelection);
|
||||
EXPECT_EQ(sequence.GetPassCount(), 4u);
|
||||
}
|
||||
|
||||
TEST(BuiltinPostProcessPassSequenceBuilder_Test, ReportsMissingObjectIdTextureViewAndFallsBackToGridOnlySequence) {
|
||||
BuiltinPostProcessPassSequenceBuilder builder;
|
||||
RenderPassSequence sequence;
|
||||
BuiltinPostProcessPassSequenceInput input = {};
|
||||
input.gridPassData.valid = true;
|
||||
input.selectedObjectIds = { 42u };
|
||||
|
||||
const auto result = builder.Build(input, sequence);
|
||||
|
||||
EXPECT_TRUE(result.valid);
|
||||
EXPECT_TRUE(result.missingObjectIdTextureViewForSelection);
|
||||
EXPECT_EQ(sequence.GetPassCount(), 3u);
|
||||
}
|
||||
|
||||
TEST(BuiltinPostProcessPassSequenceBuilder_Test, BuildsDebugMaskSequenceWhenRequested) {
|
||||
BuiltinPostProcessPassSequenceBuilder builder;
|
||||
RenderPassSequence sequence;
|
||||
BuiltinPostProcessPassSequenceInput input = {};
|
||||
input.gridPassData.valid = true;
|
||||
input.objectIdTextureView = reinterpret_cast<XCEngine::RHI::RHIResourceView*>(1);
|
||||
input.selectedObjectIds = { 5u };
|
||||
input.outlineStyle = ObjectIdOutlineStyle{};
|
||||
input.outlineStyle.debugSelectionMask = true;
|
||||
|
||||
const auto result = builder.Build(input, sequence);
|
||||
|
||||
EXPECT_TRUE(result.valid);
|
||||
EXPECT_FALSE(result.missingObjectIdTextureViewForSelection);
|
||||
EXPECT_EQ(sequence.GetPassCount(), 3u);
|
||||
}
|
||||
|
||||
TEST(BuiltinPostProcessPassSequenceBuilder_Test, BuildsSelectionOnlyOutlineSequenceWhenGridDataIsUnavailable) {
|
||||
BuiltinPostProcessPassSequenceBuilder builder;
|
||||
RenderPassSequence sequence;
|
||||
BuiltinPostProcessPassSequenceInput input = {};
|
||||
input.objectIdTextureView = reinterpret_cast<XCEngine::RHI::RHIResourceView*>(1);
|
||||
input.selectedObjectIds = { 13u };
|
||||
|
||||
const auto result = builder.Build(input, sequence);
|
||||
|
||||
EXPECT_TRUE(result.valid);
|
||||
EXPECT_FALSE(result.missingObjectIdTextureViewForSelection);
|
||||
EXPECT_EQ(sequence.GetPassCount(), 3u);
|
||||
}
|
||||
|
||||
TEST(BuiltinPostProcessPassSequenceBuilder_Test, ReportsInvalidSelectionOnlySequenceWhenObjectIdTextureViewIsMissing) {
|
||||
BuiltinPostProcessPassSequenceBuilder builder;
|
||||
RenderPassSequence sequence;
|
||||
BuiltinPostProcessPassSequenceInput input = {};
|
||||
input.selectedObjectIds = { 13u };
|
||||
|
||||
const auto result = builder.Build(input, sequence);
|
||||
|
||||
EXPECT_FALSE(result.valid);
|
||||
EXPECT_TRUE(result.missingObjectIdTextureViewForSelection);
|
||||
EXPECT_EQ(sequence.GetPassCount(), 0u);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -438,31 +438,6 @@ TEST(CameraRenderer_Test, ShutsDownSequencesWhenPostPassInitializationFails) {
|
||||
"shutdown:pre" }));
|
||||
}
|
||||
|
||||
TEST(CameraRenderer_Test, RejectsBuiltinPostProcessThatCannotProduceFreshObjectIdData) {
|
||||
Scene scene("CameraRendererBuiltinPostProcessValidationScene");
|
||||
|
||||
GameObject* cameraObject = scene.CreateGameObject("Camera");
|
||||
auto* camera = cameraObject->AddComponent<CameraComponent>();
|
||||
camera->SetPrimary(true);
|
||||
camera->SetDepth(4.0f);
|
||||
|
||||
auto state = std::make_shared<MockPipelineState>();
|
||||
CameraRenderer renderer(std::make_unique<MockPipeline>(state));
|
||||
|
||||
CameraRenderRequest request;
|
||||
request.scene = &scene;
|
||||
request.camera = camera;
|
||||
request.context = CreateValidContext();
|
||||
request.surface = RenderSurface(512, 512);
|
||||
request.cameraDepth = camera->GetDepth();
|
||||
request.builtinPostProcess.gridPassData.valid = true;
|
||||
request.builtinPostProcess.objectIdTextureView =
|
||||
reinterpret_cast<XCEngine::RHI::RHIResourceView*>(1);
|
||||
|
||||
EXPECT_FALSE(renderer.Render(request));
|
||||
EXPECT_TRUE(state->eventLog.empty());
|
||||
}
|
||||
|
||||
TEST(SceneRenderer_Test, BuildsSortedRequestsForAllUsableCamerasAndHonorsOverrideCamera) {
|
||||
Scene scene("SceneRendererRequestScene");
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ using XCEngine::Editor::ApplySceneViewportRenderRequestSetup;
|
||||
using XCEngine::Editor::ApplySceneViewportRenderPlan;
|
||||
using XCEngine::Editor::ApplyViewportFailureStatus;
|
||||
using XCEngine::Editor::BuildGameViewportRenderFailurePolicy;
|
||||
using XCEngine::Editor::BuildSceneViewportBuiltinPostProcess;
|
||||
using XCEngine::Editor::BuildSceneViewportRenderPlan;
|
||||
using XCEngine::Editor::BuildSceneViewportRenderFailurePolicy;
|
||||
using XCEngine::Editor::BuildSceneViewportSelectionOutlineStyle;
|
||||
@@ -32,7 +31,6 @@ using XCEngine::RHI::RHIResourceView;
|
||||
using XCEngine::RHI::ResourceStates;
|
||||
using XCEngine::RHI::ResourceViewDimension;
|
||||
using XCEngine::RHI::ResourceViewType;
|
||||
using XCEngine::Rendering::BuiltinPostProcessRequest;
|
||||
using XCEngine::Rendering::RenderPass;
|
||||
using XCEngine::Rendering::RenderPassContext;
|
||||
using XCEngine::Rendering::RenderPassSequence;
|
||||
@@ -163,56 +161,28 @@ TEST(ViewportRenderFlowUtilsTest, ApplyViewportFailureStatusRespectsSetIfEmptyBe
|
||||
EXPECT_EQ(statusText, "No active scene");
|
||||
}
|
||||
|
||||
TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportBuiltinPostProcessReturnsEmptyRequestWhenOverlayIsInvalid) {
|
||||
const auto result = BuildSceneViewportBuiltinPostProcess({}, {}, true, false);
|
||||
TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportGridPassDataCopiesSceneCameraState) {
|
||||
const SceneViewportOverlayData overlay = CreateValidOverlay();
|
||||
const auto gridPassData = XCEngine::Editor::BuildSceneViewportGridPassData(overlay);
|
||||
|
||||
EXPECT_FALSE(result.request.IsRequested());
|
||||
EXPECT_EQ(result.warningStatusText, nullptr);
|
||||
EXPECT_TRUE(gridPassData.valid);
|
||||
EXPECT_FLOAT_EQ(gridPassData.cameraPosition.x, overlay.cameraPosition.x);
|
||||
EXPECT_FLOAT_EQ(gridPassData.cameraPosition.y, overlay.cameraPosition.y);
|
||||
EXPECT_FLOAT_EQ(gridPassData.cameraPosition.z, overlay.cameraPosition.z);
|
||||
EXPECT_FLOAT_EQ(gridPassData.verticalFovDegrees, overlay.verticalFovDegrees);
|
||||
EXPECT_FLOAT_EQ(gridPassData.orbitDistance, overlay.orbitDistance);
|
||||
}
|
||||
|
||||
TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportBuiltinPostProcessConfiguresGridAndOutlineDefaults) {
|
||||
const auto result = BuildSceneViewportBuiltinPostProcess(
|
||||
CreateValidOverlay(),
|
||||
{ 7u, 11u },
|
||||
true,
|
||||
false);
|
||||
TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportSelectionOutlineStyleAppliesSceneDefaults) {
|
||||
const auto style = BuildSceneViewportSelectionOutlineStyle(false);
|
||||
const auto debugStyle = BuildSceneViewportSelectionOutlineStyle(true);
|
||||
|
||||
EXPECT_TRUE(result.request.IsRequested());
|
||||
EXPECT_TRUE(result.request.gridPassData.valid);
|
||||
EXPECT_EQ(result.request.selectedObjectIds.size(), 2u);
|
||||
EXPECT_EQ(result.request.selectedObjectIds[0], 7u);
|
||||
EXPECT_EQ(result.request.selectedObjectIds[1], 11u);
|
||||
EXPECT_FLOAT_EQ(result.request.outlineStyle.outlineColor.r, 1.0f);
|
||||
EXPECT_FLOAT_EQ(result.request.outlineStyle.outlineColor.g, 0.4f);
|
||||
EXPECT_FLOAT_EQ(result.request.outlineStyle.outlineColor.b, 0.0f);
|
||||
EXPECT_FLOAT_EQ(result.request.outlineStyle.outlineWidthPixels, 2.0f);
|
||||
EXPECT_FALSE(result.request.outlineStyle.debugSelectionMask);
|
||||
EXPECT_EQ(result.warningStatusText, nullptr);
|
||||
}
|
||||
|
||||
TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportBuiltinPostProcessReportsMissingObjectIdShaderViewForSelectionOutline) {
|
||||
const auto result = BuildSceneViewportBuiltinPostProcess(
|
||||
CreateValidOverlay(),
|
||||
{ 42u },
|
||||
false,
|
||||
false);
|
||||
|
||||
EXPECT_TRUE(result.request.IsRequested());
|
||||
EXPECT_TRUE(result.request.gridPassData.valid);
|
||||
EXPECT_EQ(result.request.selectedObjectIds.size(), 1u);
|
||||
EXPECT_STREQ(result.warningStatusText, "Scene object id shader view is unavailable");
|
||||
}
|
||||
|
||||
TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportBuiltinPostProcessDoesNotWarnWhenDebugMaskDisablesSelectionOutlineFallback) {
|
||||
const auto result = BuildSceneViewportBuiltinPostProcess(
|
||||
CreateValidOverlay(),
|
||||
{ 42u },
|
||||
false,
|
||||
true);
|
||||
|
||||
EXPECT_TRUE(result.request.IsRequested());
|
||||
EXPECT_TRUE(result.request.outlineStyle.debugSelectionMask);
|
||||
EXPECT_EQ(result.warningStatusText, nullptr);
|
||||
EXPECT_FLOAT_EQ(style.outlineColor.r, 1.0f);
|
||||
EXPECT_FLOAT_EQ(style.outlineColor.g, 0.4f);
|
||||
EXPECT_FLOAT_EQ(style.outlineColor.b, 0.0f);
|
||||
EXPECT_FLOAT_EQ(style.outlineWidthPixels, 2.0f);
|
||||
EXPECT_FALSE(style.debugSelectionMask);
|
||||
EXPECT_TRUE(debugStyle.debugSelectionMask);
|
||||
}
|
||||
|
||||
TEST(ViewportRenderFlowUtilsTest, ApplySceneRenderRequestSetupAttachesOptionalPassesAndObjectIdSurface) {
|
||||
@@ -231,26 +201,17 @@ TEST(ViewportRenderFlowUtilsTest, ApplySceneRenderRequestSetupAttachesOptionalPa
|
||||
RenderPassSequence postPasses;
|
||||
postPasses.AddPass(std::make_unique<NoopRenderPass>());
|
||||
|
||||
BuiltinPostProcessRequest builtinPostProcess = {};
|
||||
builtinPostProcess.gridPassData.valid = true;
|
||||
builtinPostProcess.selectedObjectIds = { 7u };
|
||||
|
||||
XCEngine::Rendering::CameraRenderRequest request = {};
|
||||
request.surface = RenderSurface(800, 600);
|
||||
request.surface.SetRenderArea(XCEngine::Math::RectInt(64, 32, 320, 240));
|
||||
|
||||
ApplySceneViewportRenderRequestSetup(
|
||||
targets,
|
||||
&builtinPostProcess,
|
||||
&postPasses,
|
||||
request);
|
||||
|
||||
EXPECT_EQ(request.postScenePasses, &postPasses);
|
||||
EXPECT_TRUE(request.objectId.IsRequested());
|
||||
EXPECT_TRUE(request.builtinPostProcess.IsRequested());
|
||||
EXPECT_EQ(request.builtinPostProcess.objectIdTextureView, &objectIdShaderView);
|
||||
ASSERT_EQ(request.builtinPostProcess.selectedObjectIds.size(), 1u);
|
||||
EXPECT_EQ(request.builtinPostProcess.selectedObjectIds[0], 7u);
|
||||
ASSERT_EQ(request.objectId.surface.GetColorAttachments().size(), 1u);
|
||||
EXPECT_EQ(request.objectId.surface.GetColorAttachments()[0], &objectIdView);
|
||||
EXPECT_EQ(request.objectId.surface.GetDepthAttachment(), &depthView);
|
||||
@@ -273,46 +234,13 @@ TEST(ViewportRenderFlowUtilsTest, ApplySceneRenderRequestSetupSkipsUnavailableOp
|
||||
XCEngine::Rendering::CameraRenderRequest request = {};
|
||||
request.postScenePasses = reinterpret_cast<RenderPassSequence*>(static_cast<uintptr_t>(0x1));
|
||||
request.objectId.surface = RenderSurface(1, 1);
|
||||
request.builtinPostProcess.gridPassData.valid = true;
|
||||
request.objectId.surface.SetColorAttachment(
|
||||
reinterpret_cast<RHIResourceView*>(static_cast<uintptr_t>(0x2)));
|
||||
|
||||
ApplySceneViewportRenderRequestSetup(targets, nullptr, &postPasses, request);
|
||||
ApplySceneViewportRenderRequestSetup(targets, &postPasses, request);
|
||||
|
||||
EXPECT_EQ(request.postScenePasses, nullptr);
|
||||
EXPECT_FALSE(request.objectId.IsRequested());
|
||||
EXPECT_FALSE(request.builtinPostProcess.IsRequested());
|
||||
}
|
||||
|
||||
TEST(ViewportRenderFlowUtilsTest, ApplySceneRenderRequestSetupPreservesBuiltinGridFallbackWhenObjectIdShaderViewIsUnavailable) {
|
||||
DummyResourceView depthView(ResourceViewType::DepthStencil, Format::D24_UNorm_S8_UInt);
|
||||
DummyResourceView objectIdView(ResourceViewType::RenderTarget);
|
||||
|
||||
ViewportRenderTargets targets = {};
|
||||
targets.width = 800;
|
||||
targets.height = 600;
|
||||
targets.depthView = &depthView;
|
||||
targets.objectIdView = &objectIdView;
|
||||
|
||||
const auto builtinPostProcess = BuildSceneViewportBuiltinPostProcess(
|
||||
CreateValidOverlay(),
|
||||
{ 99u },
|
||||
false,
|
||||
false);
|
||||
|
||||
XCEngine::Rendering::CameraRenderRequest request = {};
|
||||
request.surface = RenderSurface(800, 600);
|
||||
|
||||
ApplySceneViewportRenderRequestSetup(
|
||||
targets,
|
||||
&builtinPostProcess.request,
|
||||
nullptr,
|
||||
request);
|
||||
|
||||
EXPECT_TRUE(request.builtinPostProcess.IsRequested());
|
||||
EXPECT_EQ(request.builtinPostProcess.objectIdTextureView, nullptr);
|
||||
EXPECT_EQ(request.builtinPostProcess.selectedObjectIds.size(), 1u);
|
||||
EXPECT_TRUE(request.objectId.IsRequested());
|
||||
}
|
||||
|
||||
TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportRenderPlanCollectsPostSceneAndOverlayPasses) {
|
||||
@@ -365,7 +293,6 @@ TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportRenderPlanCollectsPostSceneA
|
||||
},
|
||||
false);
|
||||
|
||||
EXPECT_FALSE(result.plan.builtinPostProcess.IsRequested());
|
||||
EXPECT_EQ(result.plan.postScenePasses.GetPassCount(), 2u);
|
||||
EXPECT_EQ(result.plan.overlayPasses.GetPassCount(), 1u);
|
||||
EXPECT_EQ(factoryCallCount, 1u);
|
||||
@@ -415,7 +342,6 @@ TEST(ViewportRenderFlowUtilsTest, ApplySceneViewportRenderPlanAttachesPlannedPas
|
||||
targets.objectIdShaderView = &objectIdShaderView;
|
||||
|
||||
SceneViewportRenderPlan plan = {};
|
||||
plan.builtinPostProcess.gridPassData.valid = true;
|
||||
plan.postScenePasses.AddPass(std::make_unique<NoopRenderPass>());
|
||||
plan.overlayPasses.AddPass(std::make_unique<NoopRenderPass>());
|
||||
plan.clearColorOverride = XCEngine::Math::Color(0.1f, 0.2f, 0.3f, 1.0f);
|
||||
@@ -429,7 +355,6 @@ TEST(ViewportRenderFlowUtilsTest, ApplySceneViewportRenderPlanAttachesPlannedPas
|
||||
EXPECT_EQ(request.postScenePasses, &plan.postScenePasses);
|
||||
EXPECT_EQ(request.overlayPasses, &plan.overlayPasses);
|
||||
EXPECT_TRUE(request.objectId.IsRequested());
|
||||
EXPECT_TRUE(request.builtinPostProcess.IsRequested());
|
||||
EXPECT_TRUE(request.hasClearColorOverride);
|
||||
EXPECT_FLOAT_EQ(request.clearColorOverride.r, 0.1f);
|
||||
EXPECT_FLOAT_EQ(request.clearColorOverride.g, 0.2f);
|
||||
@@ -450,7 +375,7 @@ TEST(ViewportRenderFlowUtilsTest, MarkSceneRenderSuccessMovesTargetsToShaderReso
|
||||
|
||||
XCEngine::Rendering::CameraRenderRequest request = {};
|
||||
request.surface = RenderSurface(640, 360);
|
||||
ApplySceneViewportRenderRequestSetup(targets, nullptr, nullptr, request);
|
||||
ApplySceneViewportRenderRequestSetup(targets, nullptr, request);
|
||||
|
||||
MarkSceneViewportRenderSuccess(targets, request);
|
||||
EXPECT_EQ(targets.colorState, ResourceStates::PixelShaderResource);
|
||||
|
||||
Reference in New Issue
Block a user