Expand description
Easy to use profiler scopes for wgpu using timer queries.
wgpu_profiler
manages all the necessary wgpu::QuerySet
and wgpu::Buffer
behind the scenes
and allows you to create to create timer scopes with minimal overhead!
§How to use
use wgpu_profiler::*;
// ...
let mut profiler = GpuProfiler::new(&device, GpuProfilerSettings::default()).unwrap();
// ...
{
// You can now open profiling scopes on any encoder or pass:
let mut scope = profiler.scope("name of your scope", &mut encoder);
// Scopes can be nested arbitrarily!
let mut nested_scope = scope.scope("nested!");
// Scopes on encoders can be used to easily create profiled passes!
let mut compute_pass = nested_scope.scoped_compute_pass("profiled compute");
// Scopes expose the underlying encoder or pass they wrap:
compute_pass.set_pipeline(&pipeline);
// ...
// Scopes created this way are automatically closed when dropped.
}
// Wgpu-profiler needs to insert buffer copy commands.
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()) {
// You usually want to write to disk only under some condition, e.g. press of a key.
if button_pressed {
wgpu_profiler::chrometrace::write_chrometrace(
std::path::Path::new("mytrace.json"), &profiling_data);
}
}
Check also the Example where everything can be seen in action.
§Tracy integration
If you want to use tracy for profiling, you can enable the tracy
feature.
This adds wgpu_profiler::new_with_tracy_client
which will automatically report profiling data to tracy.
For details check the example code.
§Puffin integration
If you want to use puffin for profiling, you can enable the puffin
feature.
This adds wgpu_profiler::puffin::output_frame_to_puffin
which makes it easy to report profiling data to a puffin::GlobalProfiler
.
You can run the demo example with puffin by running cargo run --example demo --features puffin
.
All CPU profiling goes to port 8585
, all GPU profiling goes to port 8586
. You can open puffin viewers for both.
puffin_viewer --url 127.0.0.1:8585
puffin_viewer --url 127.0.0.1:8586
For details check the example code.
§Internals
For every frame that hasn’t completely finished processing yet
(i.e. hasn’t returned results via GpuProfiler::process_finished_frame
)
we keep a PendingFrame
around.
Whenever a profiling scope is opened, we allocate two queries.
This is done by either using the most recent QueryPool
or creating a new one if there’s no non-exhausted one ready.
Ideally, we only ever need a single QueryPool
per frame! In order to converge to this,
we allocate new query pools with the size of all previous query pools in a given frame, effectively doubling the size.
On GpuProfiler::end_frame
, we memorize the total size of all QueryPool
s in the current frame and make this the new minimum pool size.
QueryPool
from finished frames are re-used, unless they are deemed too small.
Modules§
Structs§
- GpuProfiler
- Profiler instance.
- GpuProfiler
Query - An inflight query for the profiler.
- GpuProfiler
Settings - Settings passed on initialization of
GpuProfiler
. - GpuTimer
Query Result - The result of a gpu timer scope.
- Manual
Owning Scope - Scope that takes ownership of the encoder/pass.
- Owning
Scope - Scope that takes ownership of the encoder/pass.
- Scope
- Scope that takes a (mutable) reference to the encoder/pass.
Enums§
- Creation
Error - Errors that can occur during profiler creation.
- EndFrame
Error - Errors that can occur during
crate::GpuProfiler::end_frame
. - Settings
Error - Errors that can occur during settings validation and change.
Traits§
- Profiler
Command Recorder - Trait for exposing the methods of
wgpu::CommandEncoder
,wgpu::RenderPass
andwgpu::ComputePass
that are used by the profiler.