Implement render graph compiler and transient fullscreen execution
This commit is contained in:
@@ -3,6 +3,9 @@
|
||||
#include "Components/CameraComponent.h"
|
||||
#include "Rendering/Caches/FullscreenPassSurfaceCache.h"
|
||||
#include "Rendering/Execution/DirectionalShadowExecutionState.h"
|
||||
#include "Rendering/Graph/RenderGraph.h"
|
||||
#include "Rendering/Graph/RenderGraphCompiler.h"
|
||||
#include "Rendering/Graph/RenderGraphExecutor.h"
|
||||
#include "Rendering/Passes/BuiltinDepthOnlyPass.h"
|
||||
#include "Rendering/Passes/BuiltinObjectIdPass.h"
|
||||
#include "Rendering/Passes/BuiltinShadowCasterPass.h"
|
||||
@@ -14,12 +17,17 @@
|
||||
#include "Scene/Scene.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Rendering {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr RHI::Format kRenderGraphImportedColorFormat = RHI::Format::R8G8B8A8_UNorm;
|
||||
constexpr RHI::Format kRenderGraphImportedDepthFormat = RHI::Format::D24_UNorm_S8_UInt;
|
||||
|
||||
std::shared_ptr<const RenderPipelineAsset> CreateDefaultPipelineAsset() {
|
||||
static const std::shared_ptr<const RenderPipelineAsset> s_defaultPipelineAsset =
|
||||
std::make_shared<Pipelines::BuiltinForwardPipelineAsset>();
|
||||
@@ -46,6 +54,229 @@ std::unique_ptr<RenderPipeline> CreatePipelineFromAsset(
|
||||
return std::make_unique<Pipelines::BuiltinForwardPipeline>();
|
||||
}
|
||||
|
||||
struct RenderGraphImportedSurface {
|
||||
std::vector<RenderGraphTextureHandle> colorTextures = {};
|
||||
RenderGraphTextureHandle depthTexture = {};
|
||||
};
|
||||
|
||||
using RenderGraphImportedTextureRegistry =
|
||||
std::unordered_map<RHI::RHIResourceView*, RenderGraphTextureHandle>;
|
||||
|
||||
enum class RenderGraphSurfaceImportUsage {
|
||||
Source = 0,
|
||||
Output = 1
|
||||
};
|
||||
|
||||
Containers::String BuildRenderGraphResourceName(
|
||||
const Containers::String& surfaceName,
|
||||
const char* slotName,
|
||||
size_t index = 0u,
|
||||
bool indexed = false) {
|
||||
std::string name = surfaceName.CStr();
|
||||
name += '.';
|
||||
name += slotName;
|
||||
if (indexed) {
|
||||
name += std::to_string(index);
|
||||
}
|
||||
|
||||
return Containers::String(name.c_str());
|
||||
}
|
||||
|
||||
RenderGraphTextureDesc BuildImportedTextureDesc(
|
||||
const RenderSurface& surface,
|
||||
RHI::Format format) {
|
||||
RenderGraphTextureDesc desc = {};
|
||||
desc.width = surface.GetWidth() > 0u ? surface.GetWidth() : surface.GetRenderAreaWidth();
|
||||
desc.height = surface.GetHeight() > 0u ? surface.GetHeight() : surface.GetRenderAreaHeight();
|
||||
desc.format = static_cast<Core::uint32>(format);
|
||||
desc.textureType = static_cast<Core::uint32>(RHI::TextureType::Texture2D);
|
||||
desc.sampleCount = std::max(surface.GetSampleCount(), 1u);
|
||||
desc.sampleQuality = surface.GetSampleQuality();
|
||||
return desc;
|
||||
}
|
||||
|
||||
RenderGraphImportedTextureOptions BuildImportedTextureOptions(
|
||||
const RenderSurface& surface,
|
||||
bool isDepth,
|
||||
RenderGraphSurfaceImportUsage usage) {
|
||||
const RHI::ResourceStates beforeState =
|
||||
isDepth ? surface.GetDepthStateBefore() : surface.GetColorStateBefore();
|
||||
const RHI::ResourceStates afterState =
|
||||
isDepth ? surface.GetDepthStateAfter() : surface.GetColorStateAfter();
|
||||
|
||||
RenderGraphImportedTextureOptions options = {};
|
||||
options.initialState =
|
||||
usage == RenderGraphSurfaceImportUsage::Output
|
||||
? beforeState
|
||||
: afterState;
|
||||
options.finalState =
|
||||
usage == RenderGraphSurfaceImportUsage::Output
|
||||
? afterState
|
||||
: options.initialState;
|
||||
options.graphOwnsTransitions = false;
|
||||
return options;
|
||||
}
|
||||
|
||||
RenderGraphTextureHandle ImportRenderGraphTexture(
|
||||
RenderGraphBuilder& builder,
|
||||
RenderGraphImportedTextureRegistry& registry,
|
||||
const Containers::String& name,
|
||||
const RenderGraphTextureDesc& desc,
|
||||
RHI::RHIResourceView* view,
|
||||
const RenderGraphImportedTextureOptions& importedOptions) {
|
||||
if (view == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto existing = registry.find(view);
|
||||
if (existing != registry.end()) {
|
||||
return existing->second;
|
||||
}
|
||||
|
||||
const RenderGraphTextureHandle handle =
|
||||
builder.ImportTexture(name, desc, view, importedOptions);
|
||||
registry.emplace(view, handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
RenderGraphImportedSurface ImportRenderGraphSurface(
|
||||
RenderGraphBuilder& builder,
|
||||
RenderGraphImportedTextureRegistry& registry,
|
||||
const Containers::String& surfaceName,
|
||||
const RenderSurface* surface,
|
||||
RenderGraphSurfaceImportUsage usage) {
|
||||
RenderGraphImportedSurface importedSurface = {};
|
||||
if (surface == nullptr) {
|
||||
return importedSurface;
|
||||
}
|
||||
|
||||
const RenderGraphTextureDesc colorDesc =
|
||||
BuildImportedTextureDesc(*surface, kRenderGraphImportedColorFormat);
|
||||
const std::vector<RHI::RHIResourceView*>& colorAttachments = surface->GetColorAttachments();
|
||||
importedSurface.colorTextures.reserve(colorAttachments.size());
|
||||
for (size_t colorIndex = 0; colorIndex < colorAttachments.size(); ++colorIndex) {
|
||||
RHI::RHIResourceView* colorAttachment = colorAttachments[colorIndex];
|
||||
if (colorAttachment == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
importedSurface.colorTextures.push_back(
|
||||
ImportRenderGraphTexture(
|
||||
builder,
|
||||
registry,
|
||||
BuildRenderGraphResourceName(surfaceName, "Color", colorIndex, true),
|
||||
colorDesc,
|
||||
colorAttachment,
|
||||
BuildImportedTextureOptions(
|
||||
*surface,
|
||||
false,
|
||||
usage)));
|
||||
}
|
||||
|
||||
if (RHI::RHIResourceView* depthAttachment = surface->GetDepthAttachment();
|
||||
depthAttachment != nullptr) {
|
||||
importedSurface.depthTexture =
|
||||
ImportRenderGraphTexture(
|
||||
builder,
|
||||
registry,
|
||||
BuildRenderGraphResourceName(surfaceName, "Depth"),
|
||||
BuildImportedTextureDesc(*surface, kRenderGraphImportedDepthFormat),
|
||||
depthAttachment,
|
||||
BuildImportedTextureOptions(
|
||||
*surface,
|
||||
true,
|
||||
usage));
|
||||
}
|
||||
|
||||
return importedSurface;
|
||||
}
|
||||
|
||||
RenderGraphTextureHandle GetPrimaryColorTexture(
|
||||
const RenderGraphImportedSurface& surface) {
|
||||
for (RenderGraphTextureHandle texture : surface.colorTextures) {
|
||||
if (texture.IsValid()) {
|
||||
return texture;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void ReadRenderGraphSurface(
|
||||
RenderGraphPassBuilder& passBuilder,
|
||||
const RenderGraphImportedSurface& surface) {
|
||||
for (RenderGraphTextureHandle texture : surface.colorTextures) {
|
||||
if (texture.IsValid()) {
|
||||
passBuilder.ReadTexture(texture);
|
||||
}
|
||||
}
|
||||
|
||||
if (surface.depthTexture.IsValid()) {
|
||||
passBuilder.ReadTexture(surface.depthTexture);
|
||||
}
|
||||
}
|
||||
|
||||
void ReadRenderGraphColorSurface(
|
||||
RenderGraphPassBuilder& passBuilder,
|
||||
const RenderGraphImportedSurface& surface) {
|
||||
for (RenderGraphTextureHandle texture : surface.colorTextures) {
|
||||
if (texture.IsValid()) {
|
||||
passBuilder.ReadTexture(texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WriteRenderGraphSurface(
|
||||
RenderGraphPassBuilder& passBuilder,
|
||||
const RenderGraphImportedSurface& surface) {
|
||||
for (RenderGraphTextureHandle texture : surface.colorTextures) {
|
||||
if (texture.IsValid()) {
|
||||
passBuilder.WriteTexture(texture);
|
||||
}
|
||||
}
|
||||
|
||||
if (surface.depthTexture.IsValid()) {
|
||||
passBuilder.WriteTexture(surface.depthTexture);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteRenderGraphColorSurface(
|
||||
RenderGraphPassBuilder& passBuilder,
|
||||
const RenderGraphImportedSurface& surface) {
|
||||
for (RenderGraphTextureHandle texture : surface.colorTextures) {
|
||||
if (texture.IsValid()) {
|
||||
passBuilder.WriteTexture(texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsFullscreenSequenceStage(
|
||||
CameraFrameStage stage) {
|
||||
return stage == CameraFrameStage::PostProcess ||
|
||||
stage == CameraFrameStage::FinalOutput;
|
||||
}
|
||||
|
||||
Containers::String BuildRenderGraphSequencePassName(
|
||||
const Containers::String& stageName,
|
||||
size_t passIndex) {
|
||||
std::string name = stageName.CStr();
|
||||
name += ".Pass";
|
||||
name += std::to_string(passIndex);
|
||||
return Containers::String(name.c_str());
|
||||
}
|
||||
|
||||
RenderGraphTextureDesc BuildFullscreenTransientTextureDesc(
|
||||
const RenderSurface& surface) {
|
||||
RenderGraphTextureDesc desc = {};
|
||||
desc.width = surface.GetWidth() > 0u ? surface.GetWidth() : surface.GetRenderAreaWidth();
|
||||
desc.height = surface.GetHeight() > 0u ? surface.GetHeight() : surface.GetRenderAreaHeight();
|
||||
desc.format = static_cast<Core::uint32>(kRenderGraphImportedColorFormat);
|
||||
desc.textureType = static_cast<Core::uint32>(RHI::TextureType::Texture2D);
|
||||
desc.sampleCount = 1u;
|
||||
desc.sampleQuality = 0u;
|
||||
return desc;
|
||||
}
|
||||
|
||||
Resources::ShaderKeywordSet BuildSceneGlobalShaderKeywords(
|
||||
const RenderSceneData& sceneData) {
|
||||
Resources::ShaderKeywordSet keywords = {};
|
||||
@@ -174,6 +405,17 @@ private:
|
||||
bool m_failed = false;
|
||||
};
|
||||
|
||||
bool EnsureInitializedPassSequence(
|
||||
std::unique_ptr<ScopedInitializedPassSequence>& activeSequence,
|
||||
RenderPassSequence* sequence,
|
||||
const RenderContext& context) {
|
||||
if (activeSequence == nullptr) {
|
||||
activeSequence = std::make_unique<ScopedInitializedPassSequence>(sequence, context);
|
||||
}
|
||||
|
||||
return activeSequence->IsReady();
|
||||
}
|
||||
|
||||
struct CameraFrameExecutionState {
|
||||
RenderPipeline* pipeline = nullptr;
|
||||
RenderPass* objectIdPass = nullptr;
|
||||
@@ -222,8 +464,13 @@ bool ExecuteFullscreenPassSequenceStage(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sequence == nullptr || sequence->GetPassCount() <= 1u) {
|
||||
return activeSequence->Execute(passContext);
|
||||
if (sequence == nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sequence->GetPassCount() <= 1u) {
|
||||
return sequence->GetPassCount() == 0u ||
|
||||
sequence->ExecutePass(0u, passContext);
|
||||
}
|
||||
|
||||
if (surfaceCache == nullptr ||
|
||||
@@ -288,6 +535,44 @@ bool ExecuteFullscreenPassSequenceStage(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryBuildRenderGraphTransientSurface(
|
||||
const RenderSurface& templateSurface,
|
||||
const RenderGraphExecutionContext& graphContext,
|
||||
RenderGraphTextureHandle textureHandle,
|
||||
RenderSurface& outSurface) {
|
||||
if (!textureHandle.IsValid() ||
|
||||
!graphContext.IsTransientTexture(textureHandle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RenderGraphTextureDesc textureDesc = {};
|
||||
RHI::RHIResourceView* renderTargetView =
|
||||
graphContext.ResolveTextureView(
|
||||
textureHandle,
|
||||
RenderGraphTextureViewType::RenderTarget);
|
||||
if (renderTargetView == nullptr ||
|
||||
!graphContext.TryGetTextureDesc(textureHandle, textureDesc)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outSurface = templateSurface;
|
||||
CopyIntermediateSurfaceLayout(templateSurface, outSurface);
|
||||
outSurface.SetColorAttachment(renderTargetView);
|
||||
outSurface.SetAutoTransitionEnabled(false);
|
||||
outSurface.SetSampleDesc(textureDesc.sampleCount, textureDesc.sampleQuality);
|
||||
outSurface.SetColorStateBefore(RHI::ResourceStates::RenderTarget);
|
||||
outSurface.SetColorStateAfter(RHI::ResourceStates::PixelShaderResource);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExecuteFullscreenPassSequencePass(
|
||||
RenderPassSequence* sequence,
|
||||
size_t passIndex,
|
||||
const RenderPassContext& passContext,
|
||||
const RenderGraphExecutionContext& graphContext,
|
||||
RenderGraphTextureHandle sourceColorHandle,
|
||||
RenderGraphTextureHandle outputColorHandle);
|
||||
|
||||
RenderPassContext BuildFrameStagePassContext(
|
||||
CameraFrameStage stage,
|
||||
const CameraFramePlan& plan,
|
||||
@@ -378,6 +663,170 @@ bool ExecuteFrameStage(
|
||||
}
|
||||
}
|
||||
|
||||
bool ExecuteRenderGraphPlan(
|
||||
const CameraFramePlan& plan,
|
||||
const DirectionalShadowExecutionState& shadowState,
|
||||
const RenderSceneData& sceneData,
|
||||
CameraFrameExecutionState& executionState) {
|
||||
RenderGraph graph = {};
|
||||
RenderGraphBuilder graphBuilder(graph);
|
||||
RenderGraphImportedTextureRegistry importedTextures = {};
|
||||
|
||||
bool stageExecutionSucceeded = true;
|
||||
for (const CameraFrameStageInfo& stageInfo : kOrderedCameraFrameStages) {
|
||||
if (!plan.HasFrameStage(stageInfo.stage) &&
|
||||
stageInfo.stage != CameraFrameStage::MainScene) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const CameraFrameStage stage = stageInfo.stage;
|
||||
const Containers::String stageName(GetCameraFrameStageName(stageInfo.stage));
|
||||
RenderPassSequence* const stageSequence = plan.GetPassSequence(stage);
|
||||
|
||||
if (IsFullscreenSequenceStage(stage) &&
|
||||
stageSequence != nullptr &&
|
||||
stageSequence->GetPassCount() > 1u) {
|
||||
const RenderPassContext stagePassContext =
|
||||
BuildFrameStagePassContext(stage, plan, sceneData);
|
||||
const RenderGraphImportedSurface sourceSurface =
|
||||
ImportRenderGraphSurface(
|
||||
graphBuilder,
|
||||
importedTextures,
|
||||
stageName + ".Source",
|
||||
stagePassContext.sourceSurface,
|
||||
RenderGraphSurfaceImportUsage::Source);
|
||||
const RenderGraphImportedSurface outputSurface =
|
||||
ImportRenderGraphSurface(
|
||||
graphBuilder,
|
||||
importedTextures,
|
||||
stageName + ".Output",
|
||||
&stagePassContext.surface,
|
||||
RenderGraphSurfaceImportUsage::Output);
|
||||
RenderGraphTextureHandle currentSourceColor = GetPrimaryColorTexture(sourceSurface);
|
||||
const RenderGraphTextureHandle finalOutputColor =
|
||||
GetPrimaryColorTexture(outputSurface);
|
||||
const RenderGraphTextureDesc transientDesc =
|
||||
BuildFullscreenTransientTextureDesc(stagePassContext.surface);
|
||||
|
||||
for (size_t passIndex = 0; passIndex < stageSequence->GetPassCount(); ++passIndex) {
|
||||
const bool isLastPass = (passIndex + 1u) == stageSequence->GetPassCount();
|
||||
const size_t sequencePassIndex = passIndex;
|
||||
const RenderGraphTextureHandle passSourceColor = currentSourceColor;
|
||||
const RenderGraphTextureHandle passOutputColor =
|
||||
isLastPass
|
||||
? finalOutputColor
|
||||
: graphBuilder.CreateTransientTexture(
|
||||
BuildRenderGraphSequencePassName(stageName, sequencePassIndex) + ".Color",
|
||||
transientDesc);
|
||||
|
||||
graphBuilder.AddRasterPass(
|
||||
BuildRenderGraphSequencePassName(stageName, sequencePassIndex),
|
||||
[&, stage, sequencePassIndex, passSourceColor, passOutputColor](
|
||||
RenderGraphPassBuilder& passBuilder) {
|
||||
if (passSourceColor.IsValid()) {
|
||||
passBuilder.ReadTexture(passSourceColor);
|
||||
}
|
||||
if (passOutputColor.IsValid()) {
|
||||
passBuilder.WriteTexture(passOutputColor);
|
||||
}
|
||||
passBuilder.SetExecuteCallback(
|
||||
[&, stage, sequencePassIndex, passSourceColor, passOutputColor](
|
||||
const RenderGraphExecutionContext& executionContext) {
|
||||
if (!stageExecutionSucceeded) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<ScopedInitializedPassSequence>& activeSequence =
|
||||
stage == CameraFrameStage::PostProcess
|
||||
? executionState.postProcessPasses
|
||||
: executionState.finalOutputPasses;
|
||||
if (!EnsureInitializedPassSequence(
|
||||
activeSequence,
|
||||
plan.GetPassSequence(stage),
|
||||
plan.request.context)) {
|
||||
stageExecutionSucceeded = false;
|
||||
return;
|
||||
}
|
||||
|
||||
stageExecutionSucceeded =
|
||||
ExecuteFullscreenPassSequencePass(
|
||||
plan.GetPassSequence(stage),
|
||||
sequencePassIndex,
|
||||
BuildFrameStagePassContext(stage, plan, sceneData),
|
||||
executionContext,
|
||||
passSourceColor,
|
||||
passOutputColor);
|
||||
});
|
||||
});
|
||||
|
||||
currentSourceColor = passOutputColor;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
const RenderGraphImportedSurface sourceSurface =
|
||||
ImportRenderGraphSurface(
|
||||
graphBuilder,
|
||||
importedTextures,
|
||||
stageName + ".Source",
|
||||
plan.GetSourceSurface(stageInfo.stage),
|
||||
RenderGraphSurfaceImportUsage::Source);
|
||||
const RenderGraphImportedSurface outputSurface =
|
||||
ImportRenderGraphSurface(
|
||||
graphBuilder,
|
||||
importedTextures,
|
||||
stageName + ".Output",
|
||||
plan.GetOutputSurface(stageInfo.stage),
|
||||
RenderGraphSurfaceImportUsage::Output);
|
||||
|
||||
graphBuilder.AddRasterPass(
|
||||
stageName,
|
||||
[&, sourceSurface, outputSurface, stage](RenderGraphPassBuilder& passBuilder) {
|
||||
if (IsFullscreenSequenceStage(stage)) {
|
||||
ReadRenderGraphColorSurface(passBuilder, sourceSurface);
|
||||
WriteRenderGraphColorSurface(passBuilder, outputSurface);
|
||||
} else {
|
||||
ReadRenderGraphSurface(passBuilder, sourceSurface);
|
||||
WriteRenderGraphSurface(passBuilder, outputSurface);
|
||||
}
|
||||
passBuilder.SetExecuteCallback(
|
||||
[&, stage](const RenderGraphExecutionContext&) {
|
||||
if (!stageExecutionSucceeded) {
|
||||
return;
|
||||
}
|
||||
|
||||
stageExecutionSucceeded = ExecuteFrameStage(
|
||||
stage,
|
||||
plan,
|
||||
shadowState,
|
||||
sceneData,
|
||||
executionState);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
CompiledRenderGraph compiledGraph = {};
|
||||
Containers::String errorMessage;
|
||||
if (!RenderGraphCompiler::Compile(graph, compiledGraph, &errorMessage)) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
Containers::String("CameraRenderer::Render failed: RenderGraph compile failed: ") +
|
||||
errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!RenderGraphExecutor::Execute(compiledGraph, plan.request.context, &errorMessage)) {
|
||||
Debug::Logger::Get().Error(
|
||||
Debug::LogCategory::Rendering,
|
||||
Containers::String("CameraRenderer::Render failed: RenderGraph execute failed: ") +
|
||||
errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
return stageExecutionSucceeded;
|
||||
}
|
||||
|
||||
RenderEnvironmentData BuildEnvironmentData(const CameraFramePlan& plan) {
|
||||
RenderEnvironmentData environment = {};
|
||||
const RenderSurface& mainSceneSurface = plan.GetMainSceneSurface();
|
||||
@@ -547,6 +996,76 @@ bool CameraRenderer::BuildSceneDataForPlan(
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool ExecuteFullscreenPassSequencePass(
|
||||
RenderPassSequence* sequence,
|
||||
size_t passIndex,
|
||||
const RenderPassContext& passContext,
|
||||
const RenderGraphExecutionContext& graphContext,
|
||||
RenderGraphTextureHandle sourceColorHandle,
|
||||
RenderGraphTextureHandle outputColorHandle) {
|
||||
if (sequence == nullptr || passIndex >= sequence->GetPassCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sequence->GetPassCount() <= 1u) {
|
||||
return sequence->ExecutePass(passIndex, passContext);
|
||||
}
|
||||
|
||||
const RenderSurface* currentSourceSurface = passContext.sourceSurface;
|
||||
RHI::RHIResourceView* currentSourceColorView = passContext.sourceColorView;
|
||||
RHI::ResourceStates currentSourceColorState = passContext.sourceColorState;
|
||||
RenderSurface transientSourceSurface = {};
|
||||
if (sourceColorHandle.IsValid() &&
|
||||
graphContext.IsTransientTexture(sourceColorHandle)) {
|
||||
if (!TryBuildRenderGraphTransientSurface(
|
||||
passContext.surface,
|
||||
graphContext,
|
||||
sourceColorHandle,
|
||||
transientSourceSurface)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
currentSourceSurface = &transientSourceSurface;
|
||||
currentSourceColorView =
|
||||
graphContext.ResolveTextureView(
|
||||
sourceColorHandle,
|
||||
RenderGraphTextureViewType::ShaderResource);
|
||||
if (currentSourceColorView == nullptr) {
|
||||
return false;
|
||||
}
|
||||
currentSourceColorState = RHI::ResourceStates::PixelShaderResource;
|
||||
}
|
||||
|
||||
const RenderSurface* outputSurface = &passContext.surface;
|
||||
RenderSurface transientOutputSurface = {};
|
||||
if (outputColorHandle.IsValid() &&
|
||||
graphContext.IsTransientTexture(outputColorHandle)) {
|
||||
if (!TryBuildRenderGraphTransientSurface(
|
||||
passContext.surface,
|
||||
graphContext,
|
||||
outputColorHandle,
|
||||
transientOutputSurface)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outputSurface = &transientOutputSurface;
|
||||
}
|
||||
|
||||
const RenderPassContext chainedContext = {
|
||||
passContext.renderContext,
|
||||
*outputSurface,
|
||||
passContext.sceneData,
|
||||
currentSourceSurface,
|
||||
currentSourceColorView,
|
||||
currentSourceColorState
|
||||
};
|
||||
return sequence->ExecutePass(passIndex, chainedContext);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool CameraRenderer::ExecuteRenderPlan(
|
||||
const CameraFramePlan& plan,
|
||||
const DirectionalShadowExecutionState& shadowState,
|
||||
@@ -558,29 +1077,7 @@ bool CameraRenderer::ExecuteRenderPlan(
|
||||
executionState.shadowCasterPass = m_shadowCasterPass.get();
|
||||
executionState.postProcessSurfaceCache = m_postProcessSurfaceCache.get();
|
||||
executionState.finalOutputSurfaceCache = m_finalOutputSurfaceCache.get();
|
||||
|
||||
for (const CameraFrameStageInfo& stageInfo : kOrderedCameraFrameStages) {
|
||||
if (!plan.HasFrameStage(stageInfo.stage) &&
|
||||
stageInfo.stage != CameraFrameStage::MainScene) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ExecuteFrameStage(
|
||||
stageInfo.stage,
|
||||
plan,
|
||||
shadowState,
|
||||
sceneData,
|
||||
executionState)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CameraRenderer::Render(
|
||||
const CameraRenderRequest& request) {
|
||||
return Render(CameraFramePlan::FromRequest(request));
|
||||
return ExecuteRenderGraphPlan(plan, shadowState, sceneData, executionState);
|
||||
}
|
||||
|
||||
bool CameraRenderer::Render(
|
||||
|
||||
Reference in New Issue
Block a user