Crate wgpu_profiler

source ·
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(4, queue.get_timestamp_period(), device.features());

// ...

// Using scopes is easiest with the macro:
wgpu_profiler!("name of your scope", &mut profiler, &mut encoder, &device, {
  // wgpu commands go here

// 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!

// Retrieving the oldest available frame and writing it out to a chrome trace file.
if let Some(profiling_data) = profiler.process_finished_frame() {
    // You usually want to write to disk only under some condition, e.g. press of a key.
    if button_pressed {
            std::path::Path::new("mytrace.json"), &profiling_data);

Check also the Example where everything can be seen in action.


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 QueryPools 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.


  • Scope types that wrap a wgpu encoder/pass and start a scope on creation. In most cases, they then allow automatically ending the scope on drop.