FrameGraph icon indicating copy to clipboard operation
FrameGraph copied to clipboard

Side effect pass inputs not preserved

Open maxamula opened this issue 8 months ago • 2 comments

FrameGraph’s compile logic skips passes with no used outputs (which includes side-effect-only passes) when determining each resource’s last usage. Possible fix:

// -- Calculate resources lifetime:

for (auto &pass : m_passNodes) {
  if (pass.m_refCount == 0 && !pass.hasSideEffect()) continue;

  for (const auto id : pass.m_creates)
    _getResourceEntry(id).m_producer = &pass;
  for (const auto [id, _] : pass.m_writes)
    _getResourceEntry(id).m_last = &pass;
  for (const auto [id, _] : pass.m_reads)
    _getResourceEntry(id).m_last = &pass;
}

maxamula avatar Apr 24 '25 22:04 maxamula

@maxamula I haven't noticed any problems with the current code. Can you describe your use case?

skaarj1989 avatar Apr 29 '25 13:04 skaarj1989

Hello, I have found the same issue.

 frame_graph.addCallbackPass<Data>(
     "Copy to Backbuffer",
     [&]( FrameGraph::Builder& builder, Data& data )
     {
       data.RenderTarget = builder.read( rtv_data.RenderTarget, FG::CopySrc{} );
       builder.setSideEffect();
     },
     // Note, backbuffer pointer captured as value.
     [backbuffer]( Data const& data, FrameGraphPassResources& resources, void* ctx )
     {
       // RenderTarget already deleted here.
       FG::Texture const& render_target = resources.get<FG::Texture>( data.RenderTarget );

       // Copy to Backbuffer
     } );

The formally correct way of using FrameGraph here would be to declare backbuffer as an imported resource. The FrameGraph works well in that case.

However, this is still a bug, since a pass with side effects should always execute.

zombietype avatar Oct 07 '25 22:10 zombietype