Skip to content

dump-resources: execute each target draw once by resuming render passes - #3289

Merged
fabian-lunarg merged 14 commits into
LunarG:devfrom
fabian-lunarg:fabian_vdr_fix_secondary_accumulation
Sep 30, 2026
Merged

fabian-lunarg merged 14 commits into
LunarG:devfrom
fabian-lunarg:fabian_vdr_fix_secondary_accumulation

Conversation

@fabian-lunarg

@fabian-lunarg fabian-lunarg commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

this PR addresses the problem surfacing in #3013 :

  • Dump-resources builds a clone per target draw, replaying its render pass from vkCmdBeginRenderPass
    up to that draw, then submits it standalone.
    -> for a pass with M target draws (i.e. draws to be dumped) that is O(M²) draws, independent of secondaries.
  • OverrideCmdExecuteCommands nests it: the accumulator appends each secondary's full set (of already-cumulative clones)
    -> peak submission is O(S * M^2). e.g. (S=25 secondaries, M=1000 draws):
    ~12.5M draw re-executions in one submission, against ~25K when the targets are primary draws.
    -> those very large submissions are suspected to trigger the VK_ERROR_DEVICE_LOST detailed in VDR: VK_ERROR_DEVICE_LOST when dumping draws from secondary command buffers #3013.
    -> it explains why the failure scales with dump volume and why chunking the dump can avoid device-loss.

proposed solution:

  • "incremental LOAD-chaining" :
  • partition the command stream into windows between consecutive target draws.
    -> a clone executes exactly the work in its window, plus the state needed to do so.
    -> resumes the render pass it did not begin with LOAD_OP_LOAD.
    -> each draw runs once, and each submission is one window.

also fixes #3258 :

  • cumulative clones applied earlier dumped draws a second time whenever the attachment cannot be rebuilt from inside the command buffer.
    -> confirmed with a constructed repro-case/capture: current dev reproduces the issue
    -> fixed in this PR by construction. each draw is executed only once.

testing:

  • the PR passes all previously existing dump-resource CI tests
  • 5 new test-cases have been added, of which 4 currently fail on dev
    -> ci-suite reference got bumped

Comment thread framework/decode/vulkan_replay_dump_resources_draw_calls.h Outdated
Comment thread framework/decode/vulkan_replay_dump_resources_draw_calls.cpp
Comment thread framework/decode/vulkan_replay_dump_resources_draw_calls.cpp
@fabian-lunarg
fabian-lunarg force-pushed the fabian_vdr_fix_secondary_accumulation branch from 0d3f86b to 3e4c0ba Compare September 23, 2026 10:11
@fabian-lunarg
fabian-lunarg force-pushed the fabian_vdr_fix_secondary_accumulation branch 7 times, most recently from 4610994 to 881ee17 Compare September 29, 2026 15:22

@panos-lunarg panos-lunarg left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comments have been addressed

Comment thread framework/decode/vulkan_replay_dump_resources.cpp
- add DrawCallsDumpingContext::GetWorkCommandBuffers and a chaining_ flag, false for now
- classify generated vkCmd* into state (vkCmdBind/Set/Push, minus events, checkpoints and
  INTEL performance markers) and work.
-> state keeps the active range, work uses the new accessor
- route draws, dispatches, trace rays, copies, blits, acceleration structure ops and
  vkCmdExecuteCommands without a secondary dumping context through the work accessor
- stop recording query commands into draw-call clones. dispatch/trace-rays clone keeps them
- drop ForEachDrawCallCommandBuffer, now obsolete
- record work commands into the current clone only and resume its render pass with LOAD
- build a LOAD variant of each render pass clone, initialLayout taken from the original finalLayout
- begin, next-subpass and end go to the clones whose window overlaps the pass
- copy VkRenderingInfo with LOAD and STORE ops for a resumed dynamic-rendering instance
- widen the revert barrier to the attachment read access and stages
- override vkCmdEndRendering2KHR, vkCmdSetRenderingAttachmentLocations and vkCmdSetRenderingInputAttachmentIndices
- chain only single-subpass primaries without secondaries
- decide chaining once for a primary and all its secondaries, after the clone counts are final
- give a chaining secondary a tail clone for the work after its last target draw, closed at vkEndCommandBuffer
- execute each secondary window into one primary clone, then the tail into the window that follows
- drop the accumulator and the fan-out into the later primary clones
- run a secondary without a dumping context in the current window only
- treat an empty render pass range as a secondary that inherits the primary's pass
- key the LOAD render pass clones by the subpass a window resumes in and the one its target draw is in
- load only the attachments a subpass up to the resume subpass uses, so a later clear still happens
- take the resume subpass from the window's lower bound at begin time
- chain multi-subpass render passes, rejecting only a malformed block range
- require a RenderPass index range to hold more than one entry
- drop chaining_, IsChaining, IsChainable and every non-chaining branch
- rename SetChaining to AppendTailClones, the one thing it still did
- give every context a tail clone for work after its last target draw
- submit tail clones after windows, containing original signal semaphores
- stop submitting original for a command buffer that dumps draws, transfer included
- record queries into draw-call clones, now the only execution
- resume a render pass in its last subpass for tail clone
- record transfer dump snapshots into the clone taking work, not the original
- signal potential application fences with empty submissions
- trim/adjust comments
- replace GetWorkCommandBuffers with GetWorkCommandBuffer, return clone-CB
- drop 'one-iteration loops' at callers, generator and generated code
- stop dropping AS builds and copies while the first window records
- add GFXRECON_ASSERT for slot index in GetCloneWindow
- pick last subpass for any window reaching past the render pass, not only tail-clones
…ubpasses

- require a render pass range to hold subpass count + 1 entries
- replace warning and its dead fallback with a fatal error naming both counts
- NOTE: contains a tempory ref to test-suite repo (depends on a suite-PR)

# Conflicts:
#	test_suite.ref

# Conflicts:
#	test_suite.ref

# Conflicts:
#	test_suite.ref
- explcitly include <ranges> for std::views::values
- remove unused 'cmd_buf_idx' counters
- address replacer records an instance-address patch into dump clones that receive an AS-build
- original command buffer is no longer submitted while dumpingi
-> address-replace never ran and TLAS build faulted under -m rebind
- dumper exposes clones taking a work command
- treat debug label and marker commands as state, as on dev
- regenerate dump-resources code
- bump test-suite ref (NOTE: still tmp commit until suite-PR merges)
- route reset, begin/end, timestamps, result copies and property writes through ForEachStateCommandBuffer
- generator: fan out conditional rendering begin/end like state
-> no clone ends a query or conditional block it did not begin
@fabian-lunarg
fabian-lunarg force-pushed the fabian_vdr_fix_secondary_accumulation branch from 881ee17 to ffc5bc2 Compare September 30, 2026 10:02
@fabian-lunarg
fabian-lunarg added this pull request to the merge queue Sep 30, 2026
Merged via the queue into LunarG:dev with commit 73039fb Sep 30, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved-to-run-ci Can run CI check on internal LunarG machines bug Something isn't working Vulkan Dump Resources

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[replay] Vulkan dump resources command-buffer clones reuse mutated attachments

2 participants