Conversation
f960c13 to
99e019b
Compare
18f0f40 to
4c702b9
Compare
|
CI gfxreconstruct build queued with queue ID 656236. |
|
CI gfxreconstruct build # 8901 running. |
|
CI gfxreconstruct build # 8901 passed. |
0471206 to
fca3ffa
Compare
ed9f6ec to
fca3ffa
Compare
fca3ffa to
4cc69c6
Compare
603ed4f to
fc6ddd4
Compare
jzulauf-lunarg
left a comment
There was a problem hiding this comment.
Preload section looks good, but I'm going to have to integrate this support in PR #2783 ... @antonio-lunarg -- if frame looping is going to change significantly, we should probably carefully align the changes so nothing gets dropped.
| error_state_ = CheckFileStatus(); | ||
| return; | ||
| } | ||
| if (!advance_to_next_frame_) |
There was a problem hiding this comment.
This feels more "contractual". Thinking assert in additional to check. The frame looping support state machine only current loads a single frame and only when advance_to_next_frame_ is enabled.
There was a problem hiding this comment.
I added an assertion and integrated with more documentation on top of this function's signature.
| // Quit when frame looping has finished. | ||
| if (frame_loop_info_->GetLoopIterations() == 0) | ||
| { | ||
| running_ = false; |
There was a problem hiding this comment.
Is this because
a) we never want to continue past looping frame or
b) because we aren't confident that replay past looping is stable? (or are sure it isn't)
--quit-after-measurement-range controls this behavior for FpsInfo.. don't know if a separate --quit-after-looping would be needed.
There was a problem hiding this comment.
a) I think we don't really care about continuing after looping, at the moment.
b) But I think replay past looping should work.
I suppose --quit-after-looping might be added later if someone wants it.
There was a problem hiding this comment.
Then the someone adding --quit-after-looping would also wrap running_ = false; and break with e..g. if(frame_loop_info_->quit_after_looping)?
| // as StartBlock does it lazily, and thus the last will be present. | ||
| // NOTE: This must be done before SetBatchSinkProc, or we'll record it to preload | ||
| block_parser_->GetBlockAllocator().FlushBatch(); | ||
| block_parser_->SetOperationMode(BlockParser::OperationMode::kEnqueued); |
There was a problem hiding this comment.
This mode means that we store the minimum needed. For uncompressed block, we store the "raw block" information and have the DispatchArgs directly reference it. However for compressed block (combined with BlockParser::DecompressionPolicy::kAlways below) we only the decompressed data and not the raw block data from the file.
There was a problem hiding this comment.
For frame looping, I think we only care about being able to replay blocks. For compressed blocks, I would be happy do uncompress once and use the decompressed data later again and again.
|
|
||
| // Use kAlways decompression policy to move the maximum amount of work outside the measurement loop | ||
| auto save_decompression_policy = block_parser_->GetDecompressionPolicy(); | ||
| block_parser_->SetDecompressionPolicy(BlockParser::DecompressionPolicy::kAlways); |
There was a problem hiding this comment.
In order to support frame looping BlockParser::DecompressionPolicy::kAlways isn't just a performance optimization for accurate measurement required to prevent the the issue of having dispatch_args data members pointing at the most recently decompressed data (or stale pointers) on replay.
Probably needs some commentary about this.
There was a problem hiding this comment.
I added a comment.
505606c to
2fc373a
Compare
| preload_processor->SkipStateBlocks(); | ||
|
|
||
| GFXRECON_LOG_INFO("Looping frame (%i iterations remaining)", frame_loop_info_->GetLoopIterations()); | ||
| frame_loop_info_->DecrementLoopIterations(); |
There was a problem hiding this comment.
Are the loop iterations abstracted behind methods as a design principle or do you have an expectation here that this may be more than just -- at some point?
There was a problem hiding this comment.
I think we can already wrap a couple of these lines within a frame_loop_info->EndFrame().
Or we might even wrap all of them by passing the file_processor as a parameter of EndFrame(..).
What do you think?
| decode::FileProcessor* file_processor_; ///< The FileProcessor object responsible for decoding and processing capture file data. | ||
| bool running_; ///< Indicates that the application is actively processing system events for playback. | ||
| bool paused_; ///< Indicates that the playback has been paused. When paused the application will stop rendering, but will continue processing system events. | ||
| graphics::FrameLoopInfo* frame_loop_info_; ///< Indicates that playback wishes to loop a certain frame |
There was a problem hiding this comment.
I don't want to cause this PR to be retested, so don't change it for this PR, but for changes in the future and for a possible edit to looping in a future PR, I think this would be better (since it's just a few uint32's and there are only 1 Applications) to embed frame looping info or other Application parameters directly in Application with defaults that mean "no frame looping" to avoid a potential bug in future PRs not checking "frame_loop_info != nullptr".
There was a problem hiding this comment.
I actually have been talking with @jzulauf-lunarg about that. While FrameLoopInfo takes inspiration from FpsInfo, I noticed FpsInfo is quite useful for things related to frame-looping and I was also considering merging these two together into something like FrameInfo, focused on frames rather than the concept of frames-per-second.
bradgrantham-lunarg
left a comment
There was a problem hiding this comment.
Very cool, thank you!
| if (at_end) | ||
| bool PreloadFileProcessor::AdvanceToNextFrame(ProcessBlockState process_result) | ||
| { | ||
| if (advance_to_next_frame_) |
There was a problem hiding this comment.
It seems like "whether to advance to next frame" is an application preference, but it's reaching its fingers into PreloadFileProcessor to do it. That is to say, AdvanceToNextFrame and maybe "move replay cursor" primitive make sense, but what would it mean to call AdvanceToNextFrame but have advance_to_next_frame_ be false? Why not have advance_to_next_frame_ be in the caller, and then whether to call PreloadNextFrames and AdvanceToNextFrame and "move replay cursor" would be up to the caller of FilePreloadProcessor?
The precedent for this is that there is already a SkipStateBlocks that controls playback and the cursor that is a primitive an application may choose to call, and then whether to skip isn't tracked by FilePreloadProcessor.
There was a problem hiding this comment.
Please have a look at the last two commits: I replaced the advance_to_next_frame_ mode bit with two explicit functions: ReplayCurrentPreloadedFrame() and AdvancePreloadedFrame(). When looping, Application calls only the replay function and skips the advance, keeping the cursor on the same preloaded frame for every iteration.
4160f3c to
5777fec
Compare
5777fec to
d49e152
Compare
MarkY-LunarG
left a comment
There was a problem hiding this comment.
LGTM. Great first step!
c3f7ba2 to
4eacee5
Compare
Add experimental frame looping by not advancing the preloaded frame after replaying a target frame. - Add `--loop-frame` and `--loop-count` replay options on desktop, Android, and in the launcher script. - Add `VulkanReplayFrameLoopConsumer` to enter loop mode at frame end, idle devices, not advancing to the next frame, and replay it. - Extend `PreloadFileProcessor` with `SetAdvanceToNextFrame()` to skip advancing to the next frame. - Allow Application to keep preloading while frame looping is active. Also, default `pause_frame` to uint32_t max. This is needed to avoid pausing the replay when frame looping is enabled for the first frame. In this case the frame counter is not incremented, therefore it is still 0 when it is checked against `pause_frame` (if default is 0) effectively matching its value which pauses replay. Setting pause_frame default to uint32_t max solves this edge case. Co-authored-by: Nick Driscoll <nick@lunarg.com>
When looping a frame, some objects have already been created during the first iteration of the frame, hence the corresponding vkCreate* commands should be skipped.
Use 0 as first frame index and uint32_t max as default number of loop iterations. Co-authored-by: Antonio Caggiano <antonio@lunarg.com>
Set advance to next frame even when not at loop frame.
When looping, make sure to skip any state blocks to avoid reappling them on each loop iteration.
Rejects empty, non-numeric, and zero values so replay settings only accept meaningful frame targets. Returns success only after the parsed value passes all checks, which makes invalid input handling more predictable and avoids treating frame zero as a usable loop point.
Track the current replay frame in FrameLoopInfo and use it to drive loop-frame preload and replay handling from Application::Run(). This removes the ad hoc local loop state and keeps loop decisions attached to the frame-loop state object.
Require frame-advance mode when preloading frames and document it. Fix IsFileValid() to require both a queued preload head and replay cursor before replaying preloaded frames.
Have ReplayOneFrame report the replay result and next cursor instead of mutating replay_cursor_ directly. Keep cursor advancement and frame-number updates in AdvanceToNextFrame() so preload replay state changes stay in one place.
Replace SetAdvanceToNextFrame() mode bit with explicit ReplayCurrentPreloadedFrame() and AdvancePreloadedFrame() primitives. Whether to advance is now the caller's decision: Application calls ReplayCurrentPreloadedFrame() directly when looping, and the normal ProcessNextFrame() path calls both in sequence. Remove the IsFileValid() override that existed solely to support the advance_to_next_frame_=false mode.
Centralize the "infinite iterations" sentinel for clarity and maintainability, and prevents accidental decrement of the infinite sentinel while preserving current finite-loop behavior.
4eacee5 to
24e1eb5
Compare
This PR introduces experimental frame looping for replay, so a selected frame can be replayed repeatedly for analysis/profiling.
Changes:
--loop-frameand--loop-countto replay options on desktop and Android, plus forwarding inandroid/scripts/gfxrecon.py.graphics::FrameLoopInfoto track target frame, remaining iterations, and current looping state.-Loop orchestration lives in
Application::Run()so loop behavior follows application frame numbering (including trimmed traces).PreloadFileProcessorautomatically when looping is enabled, preload the target frame, and replay it by controlling advance (SetAdvanceToNextFrame).VulkanFrameLoopReplayConsumerto skip recreating already-created objects while looping (instance/device/swapchain/surfaces/AHB path).pause_frametouint32_t maxto avoid accidental pause at frame 0 when looping starts.Notes: