Skip to content

Commit

Permalink
Add profiling to example code
Browse files Browse the repository at this point in the history
  • Loading branch information
attackgoat committed Feb 20, 2024
1 parent 0e52baa commit c022779
Show file tree
Hide file tree
Showing 22 changed files with 121 additions and 5 deletions.
Binary file modified .github/img/profile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ log = "0.4"
meshopt = "0.2"
polyhedron-ops = ">=0.2, <=0.2.4"
pretty_env_logger = "0.5"
puffin = "0.19"
puffin_http = "0.16"
rand = "0.8"
reqwest = { version = "0.11", features = ["blocking"] }
screen-13-fx = { path = "contrib/screen-13-fx" }
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,10 @@ providers. When not in use profiling has zero cost.
To enable profiling, compile with one of the `profile-with-*` features enabled and initialize the
profiling provider of your choice.

_For example, [JW-Basic](https://github.com/attackgoat/jw-basic) uses
[puffin](https://crates.io/crates/puffin):_
_Example code uses [puffin](https://crates.io/crates/puffin):_

```bash
cargo run --features profile-with-puffin -- examples/raycast.bas
cargo run --features profile-with-puffin --release --example vsm_omni
```

<img src=".github/img/profile.png" alt="Flamegraph of performance data" width=30%>
Expand Down
3 changes: 3 additions & 0 deletions examples/bindless.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod profile_with_puffin;

use {
bytemuck::{cast_slice, Pod, Zeroable},
inline_spirv::inline_spirv,
Expand All @@ -7,6 +9,7 @@ use {

fn main() -> Result<(), DisplayError> {
pretty_env_logger::init();
profile_with_puffin::init();

let event_loop = EventLoop::new()
.window(|window| window.with_inner_size(LogicalSize::new(512, 512)))
Expand Down
3 changes: 3 additions & 0 deletions examples/egui.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
mod profile_with_puffin;

use {screen_13::prelude::*, screen_13_egui::prelude::*};

fn main() -> Result<(), DisplayError> {
pretty_env_logger::init();
profile_with_puffin::init();

let event_loop = EventLoop::new()
.desired_swapchain_image_count(2)
Expand Down
3 changes: 3 additions & 0 deletions examples/font_bmp.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod profile_with_puffin;

use {
bmfont::{BMFont, OrdinateOrientation},
image::io::Reader,
Expand All @@ -9,6 +11,7 @@ use {

fn main() -> anyhow::Result<()> {
pretty_env_logger::init();
profile_with_puffin::init();

// Standard Screen 13 stuff
let event_loop = EventLoop::new().build()?;
Expand Down
3 changes: 3 additions & 0 deletions examples/fuzzer.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod profile_with_puffin;

/*
Kind of an example, kind of a test - not good looking
Expand Down Expand Up @@ -46,6 +48,7 @@ static OPERATIONS: &[Operation] = &[

fn main() -> Result<(), DisplayError> {
pretty_env_logger::init();
profile_with_puffin::init();

let mut rng = thread_rng();

Expand Down
18 changes: 17 additions & 1 deletion examples/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,25 @@ cargo doc --open
Stay informed of recent changes to _Screen 13_ using the
[change log](https://github.com/attackgoat/screen-13/blob/master/CHANGELOG.md) file.

## Performance Profiling

Most of the example code (_the ones which use an `EventLoop`_) support profiling using `puffin`. To
use it, first install and run `puffin_viewer` and then run the example with the
`--features profile-with-puffin` and `--release` flags.

You may need to disable CPU thermal throttling in order to get consistent results on some platforms.
The inconsistent results are certainly valid, but they do not help in accurately measuring potential
changes. This may be done on Intel Linux machines by modifying the Intel P-State driver:

```bash
echo 100 | sudo tee /sys/devices/system/cpu/intel_pstate/min_perf_pct
```

(_[Source](https://www.kernel.org/doc/Documentation/cpu-freq/intel-pstate.txt)_)

## Helpful tools

- [VulkanSDK](https://vulkan.lunarg.com/sdk/home) _(Required when calling `EventLoop::debug(true)`)_
- NVIDIA: [nvidia-smi](https://developer.nvidia.com/nvidia-system-management-interface)
- AMD: [RadeonTop](https://github.com/clbr/radeontop)
- [RenderDoc](https://renderdoc.org/)
- [RenderDoc](https://renderdoc.org/)
5 changes: 5 additions & 0 deletions examples/hello_world.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
mod profile_with_puffin;

use screen_13::{DisplayError, EventLoop};

/// This example requires a color graphics adapter.
fn main() -> Result<(), DisplayError> {
pretty_env_logger::init();
profile_with_puffin::init();

EventLoop::new().build()?.run(|frame| {
frame
.render_graph
Expand Down
5 changes: 5 additions & 0 deletions examples/image_sampler.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod profile_with_puffin;

use {
inline_spirv::inline_spirv,
screen_13::prelude::*,
Expand All @@ -16,6 +18,9 @@ use {
///
/// See min_max.rs for more advanced image sampler usage.
fn main() -> anyhow::Result<()> {
pretty_env_logger::init();
profile_with_puffin::init();

let event_loop = EventLoop::new().build()?;
let gulf_image = read_image(&event_loop.device, "examples/res/image/gulf.jpg")?;

Expand Down
4 changes: 3 additions & 1 deletion examples/imgui.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
mod profile_with_puffin;

use {
screen_13::prelude::*,
screen_13_fx::*,
screen_13_imgui::{Condition, ImGui},
};

fn main() -> Result<(), DisplayError> {
// Set RUST_LOG=trace in your environment variables to see log output
pretty_env_logger::init();
profile_with_puffin::init();

// Screen 13 things we need for this demo
let event_loop = EventLoop::new()
Expand Down
3 changes: 3 additions & 0 deletions examples/msaa.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod profile_with_puffin;

use {
bytemuck::{bytes_of, cast_slice, NoUninit},
glam::{Mat4, Vec3},
Expand All @@ -17,6 +19,7 @@ const WHITE: ClearColorValue = ClearColorValue([1.0, 1.0, 1.0, 1.0]);
/// NOTE: The effect may be hard to see on high-DPI displays.
fn main() -> anyhow::Result<()> {
pretty_env_logger::init();
profile_with_puffin::init();

let mut input = WinitInputHelper::default();
let event_loop = EventLoop::new().build()?;
Expand Down
3 changes: 3 additions & 0 deletions examples/multipass.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod profile_with_puffin;

use {
bytemuck::cast_slice,
glam::{vec3, Mat4, Vec3, Vec4},
Expand Down Expand Up @@ -41,6 +43,7 @@ const GOLD: Material = Material {
/// - Multiple rendering passes with a transient image
fn main() -> Result<(), DisplayError> {
pretty_env_logger::init();
profile_with_puffin::init();

let event_loop = EventLoop::new().build().unwrap();
let depth_stencil_format = best_depth_stencil_format(&event_loop.device);
Expand Down
3 changes: 3 additions & 0 deletions examples/multithread.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod profile_with_puffin;

use {
bmfont::{BMFont, OrdinateOrientation},
image::io::Reader,
Expand Down Expand Up @@ -27,6 +29,7 @@ const COLOR_SUBRESOURCE_LAYER: vk::ImageSubresourceLayers = vk::ImageSubresource
// threads
fn main() -> anyhow::Result<()> {
pretty_env_logger::init();
profile_with_puffin::init();

let started_at = Instant::now();

Expand Down
45 changes: 45 additions & 0 deletions examples/profile_with_puffin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//! Initializer for puffin profiling of example code.
//!
//! This module is not required or recommended for production code! It is just safe "enough" to
//! be used for example purposes when an example is run like this:
//!
//! ```bash
//! cargo run --example hello_world --release --features profile-with-puffin
//! ```
//!
//! For more information see:
//! https://github.com/attackgoat/screen-13/blob/master/examples/getting-started.md
#[cfg(feature = "profile-with-puffin")]
use {
log::{info, log_enabled, Level::Info},
std::mem::ManuallyDrop,
};

/// Initializes the `puffin_http` profiling crate.
///
/// Note that you will need to enable the `profile-with-puffin` feature and install `puffin_viewer`:
///
/// ```bash
/// cargo install puffin_viewer
/// ```
pub fn init() {
#[cfg(feature = "profile-with-puffin")]
{
let server_addr = format!("127.0.0.1:{}", puffin_http::DEFAULT_PORT);
let puffin_server = puffin_http::Server::new(&server_addr).unwrap();

// // We don't want to ever drop this server
let _ = ManuallyDrop::new(puffin_server);

const MESSAGE: &str = "Run this to view profiling data: puffin_viewer";

if log_enabled!(Info) {
info!("{}", MESSAGE);
} else {
eprintln!("{}", MESSAGE);
}

puffin::set_scopes_on(true);
}
}
3 changes: 3 additions & 0 deletions examples/ray_omni.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod profile_with_puffin;

use {
bytemuck::{bytes_of, cast_slice, Pod, Zeroable},
glam::{vec3, vec4, Mat4, Vec3, Vec4},
Expand All @@ -16,6 +18,7 @@ use {

fn main() -> anyhow::Result<()> {
pretty_env_logger::init();
profile_with_puffin::init();

let event_loop = EventLoop::new().debug(true).build()?;
let mut pool = LazyPool::new(&event_loop.device);
Expand Down
3 changes: 3 additions & 0 deletions examples/ray_trace.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod profile_with_puffin;

use {
bytemuck::cast_slice,
inline_spirv::inline_spirv,
Expand Down Expand Up @@ -483,6 +485,7 @@ fn load_scene_buffers(
/// Adapted from http://williamlewww.com/showcase_website/vk_khr_ray_tracing_tutorial/index.html
fn main() -> anyhow::Result<()> {
pretty_env_logger::init();
profile_with_puffin::init();

let event_loop = EventLoop::new().build()?;
let mut cache = HashPool::new(&event_loop.device);
Expand Down
3 changes: 3 additions & 0 deletions examples/rt_triangle.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod profile_with_puffin;

use {bytemuck::cast_slice, inline_spirv::inline_spirv, screen_13::prelude::*, std::sync::Arc};

static SHADER_RAY_GEN: &[u32] = inline_spirv!(
Expand Down Expand Up @@ -91,6 +93,7 @@ fn create_ray_trace_pipeline(device: &Arc<Device>) -> Result<Arc<RayTracePipelin
/// Adapted from https://iorange.github.io/p01/HappyTriangle.html
fn main() -> anyhow::Result<()> {
pretty_env_logger::init();
profile_with_puffin::init();

let event_loop = EventLoop::new()
.desired_surface_format(Surface::linear_or_default)
Expand Down
3 changes: 3 additions & 0 deletions examples/transitions.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod profile_with_puffin;

use {
image::io::Reader,
screen_13::prelude::*,
Expand All @@ -8,6 +10,7 @@ use {

fn main() -> anyhow::Result<()> {
pretty_env_logger::init();
profile_with_puffin::init();

// Create Screen 13 things any similar program might need
let event_loop = EventLoop::new()
Expand Down
3 changes: 3 additions & 0 deletions examples/triangle.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
mod profile_with_puffin;

use {bytemuck::cast_slice, inline_spirv::inline_spirv, screen_13::prelude::*, std::sync::Arc};

// A Vulkan triangle using a graphic pipeline, vertex/fragment shaders, and index/vertex buffers.
fn main() -> Result<(), DisplayError> {
pretty_env_logger::init();
profile_with_puffin::init();

let event_loop = EventLoop::new().build()?;
let triangle_pipeline = Arc::new(GraphicPipeline::create(
Expand Down
3 changes: 3 additions & 0 deletions examples/vertex_layout.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod profile_with_puffin;

use {
bytemuck::{cast_slice, Pod, Zeroable},
half::f16,
Expand All @@ -14,6 +16,7 @@ use {
/// we fall back to 16 bit values.
fn main() -> Result<(), DisplayError> {
pretty_env_logger::init();
profile_with_puffin::init();

// NOTE: This example uses the 64-bit rules defined in the Vulkan spec, they're not obvious:
// https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#fxvertex-attrib
Expand Down
3 changes: 3 additions & 0 deletions examples/vsm_omni.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod profile_with_puffin;

use {
bytemuck::{bytes_of, cast_slice, NoUninit, Pod, Zeroable},
glam::{vec3, Mat4, Quat, Vec3},
Expand Down Expand Up @@ -30,6 +32,7 @@ const USE_GEOMETRY_SHADER: bool = true;
/// https://github.com/SaschaWillems/Vulkan/pull/783
fn main() -> anyhow::Result<()> {
pretty_env_logger::init();
profile_with_puffin::init();

let model_path = download_model_from_github("nefertiti.obj")?;
let model_transform = Mat4::from_scale_rotation_translation(
Expand Down

0 comments on commit c022779

Please sign in to comment.