Simple profiler scopes for wgpu using timer queries
- Easy to use profiler scopes
- Allows nesting!
- Can be disabled by runtime flag
- Additionally generates debug markers
- Thread-safe - can profile several command encoder/buffers in parallel
- Internally creates pools of timer queries automatically
- Does not need to know in advance how many queries/profiling scopes are needed
- Caches up profiler-frames until results are available
- No stalling of the device at any time!
- Many profiler instances can live side by side
- chrome trace flamegraph json export
- Tracy integration (behind
tracy
feature flag)
Create a new profiler object:
use wgpu_profiler::{wgpu_profiler, GpuProfiler, GpuProfilerSettings};
// ...
let mut profiler = GpuProfiler::new(GpuProfilerSettings::default());
Now you can start creating profiler scopes:
// You can now open profiling scopes on any encoder or pass:
let mut scope = profiler.scope("name of your scope", &mut encoder, &device);
// Scopes can be nested arbitrarily!
let mut nested_scope = scope.scope("nested!", &device);
// Scopes on encoders can be used to easily create profiled passes!
let mut compute_pass = nested_scope.scoped_compute_pass("profiled compute", &device);
// Scopes expose the underlying encoder or pass they wrap:
compute_pass.set_pipeline(&pipeline);
// ...
// Scopes created this way are automatically closed when dropped.
GpuProfiler
reads the device features on first use:
wgpu::Features::TIMESTAMP_QUERY
is required to emit any timer queries.- Alone, this allows you to use timestamp writes on pass definition as done by
Scope::scoped_compute_pass
/Scope::scoped_render_pass
- Alone, this allows you to use timestamp writes on pass definition as done by
wgpu::Features::TIMESTAMP_QUERY_INSIDE_ENCODERS
is required to issue queries at any point within encoders.wgpu::Features::TIMESTAMP_QUERY_INSIDE_PASSES
is required to issue queries at any point within passes.
Wgpu-profiler needs to insert buffer copy commands, so when you're done with an encoder and won't do any more profiling scopes on it, you need to resolve the queries:
profiler.resolve_queries(&mut encoder);
And finally, to end a profiling frame, call end_frame
. This does a few checks and will let you know if something is off!
profiler.end_frame().unwrap();
Retrieving the oldest available frame and writing it out to a chrome trace file.
if let Some(profiling_data) = profiler.process_finished_frame(queue.get_timestamp_period()) {
wgpu_profiler::chrometrace::write_chrometrace(std::path::Path::new("mytrace.json"), &profiling_data);
}
To get a look of it in action, check out the example project!
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.