#include #include "Rendering/Execution/Internal/CameraFrameGraph/SurfaceUtils.h" #include "Rendering/FrameData/RenderSceneData.h" #include "Rendering/Graph/RenderGraph.h" #include #include namespace XCEngine { namespace Rendering { namespace { bool ResolveGraphManagedSourceSurface( const RenderSurface* sourceSurfaceTemplate, RHI::RHIResourceView* sourceColorView, RHI::ResourceStates sourceColorState, RenderGraphTextureHandle sourceColorTexture, const RenderGraphExecutionContext& graphContext, const RenderPassGraphIO& io, const RenderSurface*& outSourceSurface, RHI::RHIResourceView*& outSourceColorView, RHI::ResourceStates& outSourceColorState, RenderSurface& outGraphManagedSourceSurface) { outSourceSurface = sourceSurfaceTemplate; outSourceColorView = sourceColorView; outSourceColorState = sourceColorState; if (!io.readSourceColor || !sourceColorTexture.IsValid() || !graphContext.OwnsTextureTransitions(sourceColorTexture)) { return true; } if (graphContext.IsTransientTexture(sourceColorTexture)) { if (sourceSurfaceTemplate == nullptr) { return false; } RHI::RHIResourceView* renderTargetView = graphContext.ResolveTextureView( sourceColorTexture, RenderGraphTextureViewType::RenderTarget); RHI::RHIResourceView* shaderResourceView = graphContext.ResolveTextureView( sourceColorTexture, RenderGraphTextureViewType::ShaderResource); if (renderTargetView == nullptr || shaderResourceView == nullptr) { return false; } outGraphManagedSourceSurface = *sourceSurfaceTemplate; outGraphManagedSourceSurface.SetColorAttachment(renderTargetView); outGraphManagedSourceSurface.SetAutoTransitionEnabled(false); outGraphManagedSourceSurface.SetColorStateBefore(RHI::ResourceStates::PixelShaderResource); outGraphManagedSourceSurface.SetColorStateAfter(RHI::ResourceStates::PixelShaderResource); outSourceSurface = &outGraphManagedSourceSurface; outSourceColorView = shaderResourceView; outSourceColorState = RHI::ResourceStates::PixelShaderResource; return true; } if (sourceSurfaceTemplate != nullptr) { outGraphManagedSourceSurface = BuildGraphManagedImportedSurface( *sourceSurfaceTemplate, RHI::ResourceStates::PixelShaderResource, RHI::ResourceStates::PixelShaderResource); outSourceSurface = &outGraphManagedSourceSurface; } outSourceColorState = RHI::ResourceStates::PixelShaderResource; return true; } bool ResolveGraphManagedOutputSurface( const RenderSurface& surfaceTemplate, const std::vector& colorTargets, RenderGraphTextureHandle depthTarget, const RenderGraphExecutionContext& graphContext, const RenderPassGraphIO& io, const RenderSurface*& outSurface, RenderSurface& outGraphManagedSurface) { outSurface = &surfaceTemplate; const bool ownsAnyColorTransitions = io.writeColor && std::any_of( colorTargets.begin(), colorTargets.end(), [&](RenderGraphTextureHandle texture) { return texture.IsValid() && graphContext.OwnsTextureTransitions(texture); }); const bool ownsDepthTransitions = io.writeDepth && depthTarget.IsValid() && graphContext.OwnsTextureTransitions(depthTarget); if (!ownsAnyColorTransitions && !ownsDepthTransitions) { return true; } outGraphManagedSurface = BuildGraphManagedPassSurface(surfaceTemplate); if (ownsAnyColorTransitions) { std::vector colorAttachments = surfaceTemplate.GetColorAttachments(); if (colorAttachments.size() < colorTargets.size()) { colorAttachments.resize(colorTargets.size(), nullptr); } for (size_t colorIndex = 0u; colorIndex < colorTargets.size(); ++colorIndex) { const RenderGraphTextureHandle colorTarget = colorTargets[colorIndex]; if (!colorTarget.IsValid() || !graphContext.OwnsTextureTransitions(colorTarget) || !graphContext.IsTransientTexture(colorTarget)) { continue; } colorAttachments[colorIndex] = graphContext.ResolveTextureView( colorTarget, RenderGraphTextureViewType::RenderTarget); if (colorAttachments[colorIndex] == nullptr) { return false; } } outGraphManagedSurface.SetColorAttachments(colorAttachments); } if (ownsDepthTransitions && graphContext.IsTransientTexture(depthTarget)) { RHI::RHIResourceView* depthAttachment = graphContext.ResolveTextureView( depthTarget, RenderGraphTextureViewType::DepthStencil); if (depthAttachment == nullptr) { return false; } outGraphManagedSurface.SetDepthAttachment(depthAttachment); } outSurface = &outGraphManagedSurface; return true; } } // namespace bool RecordCallbackRasterRenderPass( const RenderPassRenderGraphContext& context, const RenderPassGraphIO& io, RenderPassGraphExecutePassCallback executePassCallback, std::vector additionalReadTextures) { if (!executePassCallback) { return false; } const Containers::String passName = context.passName; const RenderContext renderContext = context.renderContext; const std::shared_ptr sceneData = std::make_shared(context.sceneData); const RenderSurface surface = context.surface; const bool hasSourceSurface = context.sourceSurface != nullptr; const RenderSurface sourceSurface = hasSourceSurface ? *context.sourceSurface : RenderSurface(); RHI::RHIResourceView* const sourceColorView = context.sourceColorView; const RHI::ResourceStates sourceColorState = context.sourceColorState; const RenderGraphTextureHandle sourceColorTexture = context.sourceColorTexture; const std::vector colorTargets = context.colorTargets; const RenderGraphTextureHandle depthTarget = context.depthTarget; bool* const executionSucceeded = context.executionSucceeded; const RenderPassGraphBeginCallback beginPassCallback = context.beginPassCallback; const RenderPassGraphEndCallback endPassCallback = context.endPassCallback; context.graphBuilder.AddRasterPass( passName, [renderContext, sceneData, surface, hasSourceSurface, sourceSurface, sourceColorView, sourceColorState, sourceColorTexture, colorTargets, depthTarget, executionSucceeded, beginPassCallback, endPassCallback, executePassCallback, additionalReadTextures, io]( RenderGraphPassBuilder& passBuilder) { if (io.readSourceColor && sourceColorTexture.IsValid()) { passBuilder.ReadTexture(sourceColorTexture); } for (RenderGraphTextureHandle readTexture : additionalReadTextures) { if (readTexture.IsValid()) { passBuilder.ReadTexture(readTexture); } } if (io.writeColor) { for (RenderGraphTextureHandle colorTarget : colorTargets) { if (colorTarget.IsValid()) { passBuilder.WriteTexture(colorTarget); } } } if (io.writeDepth && depthTarget.IsValid()) { passBuilder.WriteDepthTexture(depthTarget); } passBuilder.SetExecuteCallback( [renderContext, sceneData, surface, hasSourceSurface, sourceSurface, sourceColorView, sourceColorState, sourceColorTexture, colorTargets, depthTarget, executionSucceeded, beginPassCallback, endPassCallback, executePassCallback, io]( const RenderGraphExecutionContext& executionContext) { if (executionSucceeded != nullptr && !(*executionSucceeded)) { return; } const RenderSurface* resolvedSourceSurface = hasSourceSurface ? &sourceSurface : nullptr; RHI::RHIResourceView* resolvedSourceColorView = sourceColorView; RHI::ResourceStates resolvedSourceColorState = sourceColorState; RenderSurface graphManagedSourceSurface = {}; if (!ResolveGraphManagedSourceSurface( hasSourceSurface ? &sourceSurface : nullptr, sourceColorView, sourceColorState, sourceColorTexture, executionContext, io, resolvedSourceSurface, resolvedSourceColorView, resolvedSourceColorState, graphManagedSourceSurface)) { if (executionSucceeded != nullptr) { *executionSucceeded = false; } return; } const RenderSurface* resolvedSurface = &surface; RenderSurface graphManagedSurface = {}; if (!ResolveGraphManagedOutputSurface( surface, colorTargets, depthTarget, executionContext, io, resolvedSurface, graphManagedSurface)) { if (executionSucceeded != nullptr) { *executionSucceeded = false; } return; } const RenderPassContext passContext = { renderContext, *resolvedSurface, *sceneData, resolvedSourceSurface, resolvedSourceColorView, resolvedSourceColorState }; if (beginPassCallback && !beginPassCallback(passContext)) { if (executionSucceeded != nullptr) { *executionSucceeded = false; } return; } const bool executeResult = executePassCallback(passContext); if (endPassCallback) { endPassCallback(passContext); } if (executionSucceeded != nullptr) { *executionSucceeded = executeResult; } }); }); return true; } bool RecordRasterRenderPass( RenderPass& pass, const RenderPassRenderGraphContext& context, const RenderPassGraphIO& io) { return RecordCallbackRasterRenderPass( context, io, [&pass](const RenderPassContext& passContext) { return pass.Execute(passContext); }); } } // namespace Rendering } // namespace XCEngine