Split render-graph main scene into forward segments

This commit is contained in:
2026-04-14 16:31:32 +08:00
parent 0060a348f6
commit a91df8b4cd
4 changed files with 246 additions and 26 deletions

View File

@@ -6,6 +6,9 @@
#include "Rendering/Internal/RenderSurfacePipelineUtils.h"
#include "Rendering/RenderSurface.h"
#include <memory>
#include <string>
namespace XCEngine {
namespace Rendering {
namespace Pipelines {
@@ -57,6 +60,36 @@ RenderSurface BuildGraphManagedForwardSceneSurface(const RenderSurface& template
return surface;
}
struct ForwardSceneGraphSegmentDesc {
const char* suffix = "";
size_t beginStepIndex = 0u;
size_t endStepIndex = 0u;
bool clearAttachments = false;
bool samplesMainDirectionalShadow = false;
};
struct ForwardSceneGraphExecutionState {
bool initialized = false;
};
const std::array<ForwardSceneGraphSegmentDesc, 3>& GetForwardSceneGraphSegments() {
static constexpr std::array<ForwardSceneGraphSegmentDesc, 3> kSegments = {{
{ "Opaque", 0u, 3u, true, true },
{ "Skybox", 3u, 6u, false, false },
{ "Transparent", 6u, 9u, false, true }
}};
return kSegments;
}
Containers::String BuildForwardSceneSegmentPassName(
const Containers::String& baseName,
const char* suffix) {
std::string name = baseName.CStr();
name += '.';
name += suffix != nullptr ? suffix : "Segment";
return Containers::String(name.c_str());
}
} // namespace
bool BuiltinForwardPipeline::ShouldSampleMainDirectionalShadowMap(const RenderSceneData& sceneData) {
@@ -84,21 +117,28 @@ bool BuiltinForwardPipeline::RecordMainSceneRenderGraph(
const RenderGraphTextureHandle mainDirectionalShadowTexture =
context.mainDirectionalShadowTexture;
bool* const executionSucceeded = context.executionSucceeded;
const std::shared_ptr<ForwardSceneGraphExecutionState> graphExecutionState =
std::make_shared<ForwardSceneGraphExecutionState>();
context.graphBuilder.AddRasterPass(
passName,
[this,
surfaceTemplate,
renderContext,
sceneData,
sourceSurface,
sourceColorView,
sourceColorState,
colorTargets,
depthTarget,
mainDirectionalShadowTexture,
executionSucceeded](
RenderGraphPassBuilder& passBuilder) {
for (const ForwardSceneGraphSegmentDesc& segment : GetForwardSceneGraphSegments()) {
const Containers::String segmentPassName =
BuildForwardSceneSegmentPassName(passName, segment.suffix);
context.graphBuilder.AddRasterPass(
segmentPassName,
[this,
graphExecutionState,
surfaceTemplate,
renderContext,
sceneData,
sourceSurface,
sourceColorView,
sourceColorState,
colorTargets,
depthTarget,
mainDirectionalShadowTexture,
executionSucceeded,
segment](
RenderGraphPassBuilder& passBuilder) {
for (RenderGraphTextureHandle colorTarget : colorTargets) {
if (colorTarget.IsValid()) {
passBuilder.WriteTexture(colorTarget);
@@ -108,20 +148,22 @@ bool BuiltinForwardPipeline::RecordMainSceneRenderGraph(
if (depthTarget.IsValid()) {
passBuilder.WriteDepthTexture(depthTarget);
}
if (mainDirectionalShadowTexture.IsValid()) {
if (segment.samplesMainDirectionalShadow &&
mainDirectionalShadowTexture.IsValid()) {
passBuilder.ReadTexture(mainDirectionalShadowTexture);
}
passBuilder.SetExecuteCallback(
[this,
graphExecutionState,
surfaceTemplate,
renderContext,
sceneData,
sourceSurface,
sourceColorView,
sourceColorState,
mainDirectionalShadowTexture,
executionSucceeded](
executionSucceeded,
segment](
const RenderGraphExecutionContext&) {
if (executionSucceeded != nullptr && !(*executionSucceeded)) {
return;
@@ -134,15 +176,40 @@ bool BuiltinForwardPipeline::RecordMainSceneRenderGraph(
sourceSurface,
sourceColorView,
sourceColorState);
if (!graphExecutionState->initialized) {
if (!Initialize(*renderContext)) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
"BuiltinForwardPipeline::RecordMainSceneRenderGraph failed during execution: Initialize returned false");
if (executionSucceeded != nullptr) {
*executionSucceeded = false;
}
return;
}
if (!m_forwardSceneFeatureHost.Prepare(executionContext)) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
"BuiltinForwardPipeline::RecordMainSceneRenderGraph failed during execution: SceneRenderFeatureHost::Prepare returned false");
if (executionSucceeded != nullptr) {
*executionSucceeded = false;
}
return;
}
graphExecutionState->initialized = true;
}
const bool renderResult =
ExecuteForwardSceneFrame(
ExecuteForwardSceneSegmentPass(
executionContext,
!mainDirectionalShadowTexture.IsValid());
segment.beginStepIndex,
segment.endStepIndex,
segment.clearAttachments);
if (executionSucceeded != nullptr) {
*executionSucceeded = renderResult;
}
});
});
});
}
return true;
}
@@ -199,7 +266,9 @@ bool BuiltinForwardPipeline::ExecuteForwardSceneFrame(
return renderResult;
}
bool BuiltinForwardPipeline::BeginForwardScenePass(const RenderPassContext& passContext) {
bool BuiltinForwardPipeline::BeginForwardScenePass(
const RenderPassContext& passContext,
bool clearAttachments) {
const RenderContext& context = passContext.renderContext;
const RenderSurface& surface = passContext.surface;
const RenderSceneData& sceneData = passContext.sceneData;
@@ -261,7 +330,8 @@ bool BuiltinForwardPipeline::BeginForwardScenePass(const RenderPassContext& pass
? surface.GetClearColorOverride()
: sceneData.cameraData.clearColor;
const float clearValues[4] = { clearColor.r, clearColor.g, clearColor.b, clearColor.a };
if (HasRenderClearFlag(sceneData.cameraData.clearFlags, RenderClearFlags::Color) &&
if (clearAttachments &&
HasRenderClearFlag(sceneData.cameraData.clearFlags, RenderClearFlags::Color) &&
!HasSkybox(sceneData)) {
for (RHI::RHIResourceView* renderTarget : renderTargets) {
if (renderTarget != nullptr) {
@@ -269,7 +339,8 @@ bool BuiltinForwardPipeline::BeginForwardScenePass(const RenderPassContext& pass
}
}
}
if (depthAttachment != nullptr &&
if (clearAttachments &&
depthAttachment != nullptr &&
HasRenderClearFlag(sceneData.cameraData.clearFlags, RenderClearFlags::Depth)) {
commandList->ClearDepthStencil(depthAttachment, 1.0f, 0, 1, clearRects);
}