Safe, fully-featured bindings to the Tracy profiler

Overview

Complete Rust bindings for the Tracy profiler.

Getting Started

Just add the following to your Cargo.toml:

[dependencies.tracy]
package = "tracy_full"
version = "1.3.0"

To enable profiling for a build, add the enable feature:

[dependencies.tracy]
...
features = ["enable"]

Features

Allocation Tracking

#[global_allocator]
static ALLOC: tracy::GlobalAllocator = tracy::GlobalAllocator::new();

This tracks all allocations, using the default System allocator for allocations.

For a custom allocator:

#[global_allocator]
static ALLOC: tracy::GlobalAllocator<MyAlloc> = tracy::GlobalAllocator::new_with(MyAlloc::new());

Tracy also supports tracking custom allocators using the allocator_api feature:

[dependencies.tracy]
...
features = ["allocator_api"]
let alloc = TrackedAllocator::new(alloc, tracy::c_str!("TrackedAllocator"));

This creates a memory pool named TrackedAllocator in Tracy.

All the allocators have a *Sampled variant that samples the callstack on each allocation.

Frame Marks

Mark the end of the main frame using:

use tracy::frame;

frame!();

Mark the end of a sub-frame using:

frame!("Name");

Mark the scope of a discontinuous frame using:

frame!(discontinuous "Name");

The difference between frame types

The main frame what is usually thought of as a 'frame'. It is usually placed after the swapchain present call on the main thread.

Sub-frames are parts of the main frame, for example, input gathering, physics, and rendering:

loop {
    // Gather input
    frame!("Input");
    // Process input
    frame!("Processing");
    // Render
    frame!("Render");

    swapchain.present();
    frame!();
}

Discontinuous frames are frames that are not in sync with the frame on the main thread. This can be things like async asset loading on different threads.

Plotting

You can plot graphs in Tracy:

use tracy::plotter;

let plotter = plotter!("MyGraph");
plotter.value(1.0);
plotter.value(2.0);

Zones

use tracy::zone;

zone!(); // Zone with no name
zone!("MyZone"); // Zone with name "MyZone"
zone!(tracy::color::RED); // Zone with color red
zone!("MyZone", true); // Zone with name "MyZone", and enabled with a runtime expression.
zone!(tracy::color::RED, true); // Zone with color red, and enabled with a runtime expression.
zone!("MyZone", tracy::color::RED, true); // Zone with name "MyZone", color red, and enabled with a runtime expression.

All zones profile from creation to the end of the enclosed scope.

Extra features

Future support

Futures can be represented as fibers in Tracy. The futures feature must be enabled.

[dependencies.tracy]
...
features = ["enable", "futures"]
use tracy::future;

trace_future!(async_function(), "Async Function").await;

Unstable

The unstable feature allows for optimizations that require a nightly compiler.

[dependencies.tracy]
...
features = ["enable", "unstable"]

External Library Integration

bevy

Enable the bevy feature to be able to profile Bevy systems.

[dependencies.tracy]
...
features = ["enable", "bevy"]
use tracy::bevy::timeline;

App::new().add_system(timeline(my_system)).run();

This creates a separate fiber for the system in the tracy timeline.

tracing

Enable the tracing feature to be able to profile tracing spans.

[dependencies.tracy]
...
features = ["enable", "tracing"]
use tracy::tracing::TracyLayer;

tracing::subscriber::set_global_default(
    tracing_subscriber::registry().with(TracyLayer)
);

wgpu

Enable the wgpu feature to be able to profile wgpu command encoders and render/compute passes.

[dependencies.tracy]
...
features = ["enable", "wgpu"]
use tracy::wgpu::ProfileContext;

let mut profile_context = ProfileContext::with_name("Name", &adapter, &device, &queue, buffered_frames);

buffered_frames: the number of frames of profiling data you want the profiler to buffer. Note that you must synchronize the host and device accordingly, or else the call to end_frame will panic.

You also need to have one ProfileContext per host thread.

You can create a profiled command encoder:

use tracy::{wgpu_command_encoder, wgpu_render_pass, wgpu_compute_pass};

let mut command_encoder = wgpu_command_encoder!(device, profile_context, desc);
{
    let render_pass = wgpu_render_pass!(command_encoder, desc)
}

{
    let compute_pass = wgpu_compute_pass!(command_encoder, desc)
}

At the end of each frame, you must call end_frame:

profile_context.end_frame(&device, &queue);

This uploads the profiling data to the Tracy.

You might also like...
Rust bindings for GDNative

GDNative bindings for Rust Rust bindings to the Godot game engine. Website | User Guide | API Documentation Stability The bindings cover most of the e

SDL bindings for Rust

Rust-SDL Bindings for SDL in Rust Overview Rust-SDL is a library for talking to SDL from Rust. Low-level C components are wrapped in Rust code to make

SDL2 bindings for Rust

Rust-SDL2 Bindings for SDL2 in Rust Changelog for 0.34.2 Overview Rust-SDL2 is a library for talking to the new SDL2.0 libraries from Rust. Low-level

SFML bindings for Rust

rust-sfml Rust bindings for SFML, the Simple and Fast Multimedia Library. Requirements Linux, Windows, or OS X Rust 1.42 or later SFML 2.5 CSFML 2.5 D

Rust bindings for libtcod 1.6.3 (the Doryen library/roguelike toolkit)

Warning: Not Maintained This project is no longer actively developed or maintained. Please accept our apologies. Open pull requests may still get merg

Some Rust bindings for Binary Ninja

Binary Ninja Rust Bindings Work in progress Rust bindings geared towards analysis. Features added as they come up. No promises anything works at this

Pure and simple Vulkan bindings generated from Vulkan-Headers!
Pure and simple Vulkan bindings generated from Vulkan-Headers!

mira Pure and simple Vulkan bindings generated from Vulkan-Headers! Mira provides a simple and straightforward way to interact with Vulkan. Everything

Python bindings for egg

Python bindings for egg Installing Install maturin, a cool Rust/Python builder thingy. Download from their site or just pip install maturin. Type make

Qt Quick / QML bindings for Rust

qmlrsng Qt Quick bindings for Rust, based on libqmlbind. The crate libqmlbind-sys wraps libqmlbind C library in Rust and exposes an unsafe API. The go

Comments
  • Add fields to tracing name

    Add fields to tracing name

    Hi!

    This PR adds span fields to the name passed to tracy. For my usecase it'll go from all names being "system" to "system{name=<system_name>}".

    The implementation is heavily inspired from tracing-tracy.

    opened by leudz 1
Releases(v1.3.0)
Owner
Shaye Garg
Potato enjoyer, light bouncer, and GPU fryer deep in the compiler rabbit hole.
Shaye Garg
Show puffin profiler flamegraph in-game using egui

Show puffin profiler flamegraph in-game using egui puffin is an instrumentation profiler where you opt-in to profile parts of your code: fn my_functio

Emil Ernerfeldt 44 Jun 3, 2022
A simple implementation of Conway's Game of Life using Fully homomorphic Encryption

Game of life using Fully homomorphic encryption A simple implementation of Conway's Game of Life built using Zama's concrete-boolean library. Build Ju

Florent Michel 4 Oct 3, 2022
Blackmarlin is a chess engine fully written in Rust.

Blackmarlin WIP UCI Chess Engine Blackmarlin is a chess engine fully written in Rust. Make sure to compile the chess engine with cargo build --release

null 50 Oct 31, 2022
A simple space shooter game. Runs in the terminal using characters-based UI. Fully written in Rust, using the "ruscii" library.

Thrust - a terminal shooter game Originally created as a project for the "Missing Semester" course at JKU Linz (338.006). The game is entirely written

Mathias Wöß 3 Jan 16, 2023
Experimental type-safe geometric algebra for Rust

Projective Geometric Algebra This library is a Rust code generator, generating the mathematics you need for a geometric algebra library. I made it mos

Emil Ernerfeldt 33 Dec 4, 2022
A safe, fast and cross-platform 2D component-based game framework written in rust

shura shura is a safe, fast and cross-platform 2D component-based game framework written in rust. shura helps you to manage big games with a component

Andri 28 Jan 17, 2023
Rollback-safe implementations and utilities for Bevy Engine

bevy_roll_safe Rollback-safe implementations and utilities for Bevy Engine. Motivation Some of Bevy's features can't be used in a rollback context (wi

Johan Klokkhammer Helsing 3 Sep 17, 2023
Zero-cost and safe interface to UEFI firmware

ZFI – Zero-cost and safe interface to UEFI firmware ZFI is a Rust crate for writing a UEFI application with the following goals: Provides base APIs th

Ultima Microsystems 22 Sep 14, 2023
A Rust wrapper and bindings of Allegro 5 game programming library

RustAllegro A thin Rust wrapper of Allegro 5. Game loop example extern crate allegro; extern crate allegro_font; use allegro::*; use allegro_font::*;

null 80 Dec 31, 2022
corange-rs CorangeCorange lucidscape/corange-rs — Corange bindings

CORANGE-RS This crate provides an interface to the Corange game engine, written in Pure C, SDL and OpenGL by Daniel Holden. Features include: deferred

null 43 Jul 22, 2022