Integrate graph-managed depth surfaces into camera stages

This commit is contained in:
2026-04-14 14:27:30 +08:00
parent 31a8125fc1
commit 4ee1bcc599
2 changed files with 150 additions and 23 deletions

View File

@@ -147,7 +147,8 @@ RenderGraphImportedSurface ImportRenderGraphSurface(
const Containers::String& surfaceName,
const RenderSurface* surface,
RenderGraphSurfaceImportUsage usage,
bool graphOwnsColorTransitions = false) {
bool graphOwnsColorTransitions = false,
bool graphOwnsDepthTransitions = false) {
RenderGraphImportedSurface importedSurface = {};
if (surface == nullptr) {
return importedSurface;
@@ -190,7 +191,7 @@ RenderGraphImportedSurface ImportRenderGraphSurface(
*surface,
true,
usage,
false));
graphOwnsDepthTransitions));
}
return importedSurface;
@@ -312,7 +313,8 @@ bool ExecuteScenePassRequest(
RenderPass* pass,
const ScenePassRenderRequest& request,
const RenderContext& context,
const RenderSceneData& baseSceneData) {
const RenderSceneData& baseSceneData,
const RenderSurface* surfaceOverride = nullptr) {
if (!request.IsRequested()) {
return true;
}
@@ -326,8 +328,10 @@ bool ExecuteScenePassRequest(
sceneData.cameraData = request.cameraDataOverride;
}
sceneData.cameraData.viewportWidth = request.surface.GetRenderAreaWidth();
sceneData.cameraData.viewportHeight = request.surface.GetRenderAreaHeight();
const RenderSurface& requestSurface =
surfaceOverride != nullptr ? *surfaceOverride : request.surface;
sceneData.cameraData.viewportWidth = requestSurface.GetRenderAreaWidth();
sceneData.cameraData.viewportHeight = requestSurface.GetRenderAreaHeight();
sceneData.cameraData.clearFlags = request.clearFlags;
if (request.hasClearColorOverride) {
sceneData.cameraData.clearColor = request.clearColorOverride;
@@ -335,7 +339,7 @@ bool ExecuteScenePassRequest(
const RenderPassContext passContext = {
context,
request.surface,
requestSurface,
sceneData,
nullptr,
nullptr,
@@ -581,6 +585,73 @@ RenderSurface BuildGraphManagedImportedSurface(
return surface;
}
RenderSurface BuildGraphManagedPassSurface(
const RenderSurface& templateSurface) {
RenderSurface surface = templateSurface;
surface.SetAutoTransitionEnabled(false);
return surface;
}
const RenderSurface* ResolveFrameStageOutputSurface(
CameraFrameStage stage,
const CameraFramePlan& plan,
const DirectionalShadowExecutionState& shadowState) {
switch (stage) {
case CameraFrameStage::ShadowCaster:
return shadowState.shadowCasterRequest.IsRequested()
? &shadowState.shadowCasterRequest.surface
: nullptr;
case CameraFrameStage::DepthOnly:
return plan.request.depthOnly.IsRequested()
? &plan.request.depthOnly.surface
: nullptr;
case CameraFrameStage::ObjectId:
return plan.request.objectId.IsRequested()
? &plan.request.objectId.surface
: nullptr;
default:
return plan.GetOutputSurface(stage);
}
}
bool ShouldGraphOwnStageColorTransitions(
CameraFrameStage stage) {
return stage == CameraFrameStage::ObjectId;
}
bool ShouldGraphOwnStageDepthTransitions(
CameraFrameStage stage) {
return stage == CameraFrameStage::ShadowCaster ||
stage == CameraFrameStage::DepthOnly ||
stage == CameraFrameStage::ObjectId;
}
bool CanUseGraphManagedImportedSurface(
const RenderGraphImportedSurface& surface,
const RenderGraphExecutionContext& graphContext) {
bool hasAnyTexture = false;
for (RenderGraphTextureHandle texture : surface.colorTextures) {
if (!texture.IsValid()) {
continue;
}
hasAnyTexture = true;
if (!graphContext.OwnsTextureTransitions(texture)) {
return false;
}
}
if (surface.depthTexture.IsValid()) {
hasAnyTexture = true;
if (!graphContext.OwnsTextureTransitions(surface.depthTexture)) {
return false;
}
}
return hasAnyTexture;
}
bool ExecuteFullscreenPassSequencePass(
RenderPassSequence* sequence,
size_t passIndex,
@@ -592,8 +663,10 @@ bool ExecuteFullscreenPassSequencePass(
RenderPassContext BuildFrameStagePassContext(
CameraFrameStage stage,
const CameraFramePlan& plan,
const DirectionalShadowExecutionState& shadowState,
const RenderSceneData& sceneData) {
const RenderSurface* outputSurface = plan.GetOutputSurface(stage);
const RenderSurface* outputSurface =
ResolveFrameStageOutputSurface(stage, plan, shadowState);
return {
plan.request.context,
outputSurface != nullptr ? *outputSurface : plan.request.surface,
@@ -609,8 +682,21 @@ bool ExecuteFrameStage(
const CameraFramePlan& plan,
const DirectionalShadowExecutionState& shadowState,
const RenderSceneData& sceneData,
CameraFrameExecutionState& executionState) {
const RenderPassContext passContext = BuildFrameStagePassContext(stage, plan, sceneData);
CameraFrameExecutionState& executionState,
const RenderSurface* outputSurfaceOverride = nullptr) {
const RenderPassContext defaultPassContext =
BuildFrameStagePassContext(stage, plan, shadowState, sceneData);
const RenderPassContext overridePassContext = {
defaultPassContext.renderContext,
outputSurfaceOverride != nullptr
? *outputSurfaceOverride
: defaultPassContext.surface,
defaultPassContext.sceneData,
defaultPassContext.sourceSurface,
defaultPassContext.sourceColorView,
defaultPassContext.sourceColorState
};
const RenderPassContext& passContext = overridePassContext;
switch (stage) {
case CameraFrameStage::PreScenePasses:
@@ -624,13 +710,15 @@ bool ExecuteFrameStage(
executionState.shadowCasterPass,
shadowState.shadowCasterRequest,
plan.request.context,
sceneData);
sceneData,
outputSurfaceOverride);
case CameraFrameStage::DepthOnly:
return ExecuteScenePassRequest(
executionState.depthOnlyPass,
plan.request.depthOnly,
plan.request.context,
sceneData);
sceneData,
outputSurfaceOverride);
case CameraFrameStage::MainScene:
return executionState.pipeline != nullptr &&
executionState.pipeline->Render(
@@ -660,7 +748,9 @@ bool ExecuteFrameStage(
ExecuteStandalonePass(
executionState.objectIdPass,
plan.request.context,
plan.request.objectId.surface,
outputSurfaceOverride != nullptr
? *outputSurfaceOverride
: plan.request.objectId.surface,
sceneData);
case CameraFrameStage::PostScenePasses:
return ExecutePassSequenceStage(
@@ -703,7 +793,7 @@ bool ExecuteRenderGraphPlan(
stageSequence != nullptr &&
stageSequence->GetPassCount() > 1u) {
const RenderPassContext stagePassContext =
BuildFrameStagePassContext(stage, plan, sceneData);
BuildFrameStagePassContext(stage, plan, shadowState, sceneData);
const RenderGraphImportedSurface sourceSurface =
ImportRenderGraphSurface(
graphBuilder,
@@ -738,7 +828,7 @@ bool ExecuteRenderGraphPlan(
transientDesc);
graphBuilder.AddRasterPass(
BuildRenderGraphSequencePassName(stageName, sequencePassIndex),
BuildRenderGraphSequencePassName(stageName, sequencePassIndex),
[&, stage, sequencePassIndex, passSourceColor, passOutputColor](
RenderGraphPassBuilder& passBuilder) {
if (passSourceColor.IsValid()) {
@@ -770,7 +860,11 @@ bool ExecuteRenderGraphPlan(
ExecuteFullscreenPassSequencePass(
plan.GetPassSequence(stage),
sequencePassIndex,
BuildFrameStagePassContext(stage, plan, sceneData),
BuildFrameStagePassContext(
stage,
plan,
shadowState,
sceneData),
executionContext,
passSourceColor,
passOutputColor);
@@ -783,24 +877,30 @@ bool ExecuteRenderGraphPlan(
continue;
}
const RenderPassContext stagePassContext =
BuildFrameStagePassContext(stage, plan, shadowState, sceneData);
const RenderGraphImportedSurface sourceSurface =
ImportRenderGraphSurface(
graphBuilder,
importedTextures,
stageName + ".Source",
plan.GetSourceSurface(stageInfo.stage),
stagePassContext.sourceSurface,
RenderGraphSurfaceImportUsage::Source);
const RenderGraphImportedSurface outputSurface =
ImportRenderGraphSurface(
graphBuilder,
importedTextures,
stageName + ".Output",
plan.GetOutputSurface(stageInfo.stage),
RenderGraphSurfaceImportUsage::Output);
&stagePassContext.surface,
RenderGraphSurfaceImportUsage::Output,
ShouldGraphOwnStageColorTransitions(stage),
ShouldGraphOwnStageDepthTransitions(stage));
const RenderSurface stageSurfaceTemplate = stagePassContext.surface;
graphBuilder.AddRasterPass(
stageName,
[&, sourceSurface, outputSurface, stage](RenderGraphPassBuilder& passBuilder) {
[&, sourceSurface, outputSurface, stage, stageSurfaceTemplate](
RenderGraphPassBuilder& passBuilder) {
if (IsFullscreenSequenceStage(stage)) {
ReadRenderGraphColorSurface(passBuilder, sourceSurface);
WriteRenderGraphColorSurface(passBuilder, outputSurface);
@@ -809,17 +909,27 @@ bool ExecuteRenderGraphPlan(
WriteRenderGraphSurface(passBuilder, outputSurface);
}
passBuilder.SetExecuteCallback(
[&, stage](const RenderGraphExecutionContext&) {
[&, stage, outputSurface, stageSurfaceTemplate](
const RenderGraphExecutionContext& executionContext) {
if (!stageExecutionSucceeded) {
return;
}
const RenderSurface* outputSurfaceOverride = nullptr;
RenderSurface graphManagedOutputSurface = {};
if (CanUseGraphManagedImportedSurface(outputSurface, executionContext)) {
graphManagedOutputSurface =
BuildGraphManagedPassSurface(stageSurfaceTemplate);
outputSurfaceOverride = &graphManagedOutputSurface;
}
stageExecutionSucceeded = ExecuteFrameStage(
stage,
plan,
shadowState,
sceneData,
executionState);
executionState,
outputSurfaceOverride);
});
});
}