From ebe28e5669beae95b34adcca241d9abb1407d255 Mon Sep 17 00:00:00 2001 From: Jared Miller Date: Tue, 16 Dec 2025 16:32:47 -0500 Subject: [PATCH] Add tracy profiling --- build.zig | 13 +++++++++++++ build.zig.zon | 4 ++++ justfile | 7 ++++++- src/sandbox_main.zig | 8 ++++++++ src/ssbo_renderer.zig | 35 ++++++++++++++++++++++++----------- 5 files changed, 55 insertions(+), 12 deletions(-) diff --git a/build.zig b/build.zig index dd0e8b9..61bdee0 100644 --- a/build.zig +++ b/build.zig @@ -4,6 +4,9 @@ pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); + // tracy profiling (run with -Dtracy=true) + const enable_tracy = b.option(bool, "tracy", "Enable Tracy profiler") orelse false; + const raylib_dep = b.dependency("raylib_zig", .{ .target = target, .optimize = optimize, @@ -24,6 +27,16 @@ pub fn build(b: *std.Build) void { sandbox_exe.root_module.addImport("raylib", raylib_dep.module("raylib")); sandbox_exe.linkLibrary(raylib_dep.artifact("raylib")); + // tracy integration (optional) + const ztracy = b.dependency("ztracy", .{ + .enable_ztracy = enable_tracy, + .on_demand = true, // allow connecting after app starts + }); + sandbox_exe.root_module.addImport("ztracy", ztracy.module("root")); + if (enable_tracy) { + sandbox_exe.linkLibrary(ztracy.artifact("tracy")); + } + b.installArtifact(sandbox_exe); const sandbox_run_cmd = b.addRunArtifact(sandbox_exe); diff --git a/build.zig.zon b/build.zig.zon index c418959..ffa581a 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -7,6 +7,10 @@ .url = "git+https://github.com/raylib-zig/raylib-zig#a4d18b2d1cf8fdddec68b5b084535fca0475f466", .hash = "raylib_zig-5.6.0-dev-KE8REL5MBQAf3p497t52Xw9P7ojndIkVOWPXnLiLLw2P", }, + .ztracy = .{ + .url = "git+https://github.com/zig-gamedev/ztracy?ref=main#e7b401dea9ce006f8b236e3a2ca1a9f3d5c3e896", + .hash = "ztracy-0.14.0-dev-zHJSq78GGQC904aYvBPn6OOvRVOq_opAwDfeHZdvQyej", + }, }, .paths = .{ "build.zig", diff --git a/justfile b/justfile index 82f2983..bd30a32 100644 --- a/justfile +++ b/justfile @@ -42,7 +42,7 @@ check: test: zig build test -# auto-benchmark (ramps entities until performance degrades, works on linux/windows) +# auto-benchmark (ramps entities until performance degrades) bench: zig build -Doptimize=ReleaseFast run -- --bench cat benchmark.log @@ -58,3 +58,8 @@ bench-sw: bench-sw: @echo "bench-sw: windows doesn't have xvfb equivalent" @echo "use 'just bench' if you have a GPU, or run in WSL/linux CI" + +[linux] +profile port="9876": + # start Tracy: tracy-profiler -a 127.0.0.1 -p {{port}} + zig build -Dtracy=true -Doptimize=ReleaseFast && TRACY_PORT={{port}} ./zig-out/bin/sandbox diff --git a/src/sandbox_main.zig b/src/sandbox_main.zig index 941530c..03b8263 100644 --- a/src/sandbox_main.zig +++ b/src/sandbox_main.zig @@ -3,6 +3,7 @@ const std = @import("std"); const rl = @import("raylib"); +const ztracy = @import("ztracy"); const sandbox = @import("sandbox.zig"); const ui = @import("ui.zig"); const SsboRenderer = @import("ssbo_renderer.zig").SsboRenderer; @@ -331,12 +332,16 @@ pub fn main() !void { // update if (!paused) { + const tracy_update = ztracy.ZoneN(@src(), "update"); + defer tracy_update.End(); const update_start = std.time.microTimestamp(); sandbox.update(&entities, &rng); update_time_us = std.time.microTimestamp() - update_start; } // render + const tracy_render = ztracy.ZoneN(@src(), "render"); + defer tracy_render.End(); const render_start = std.time.microTimestamp(); rl.beginDrawing(); @@ -407,6 +412,9 @@ pub fn main() !void { const update_ms = @as(f32, @floatFromInt(update_time_us)) / 1000.0; const render_ms = @as(f32, @floatFromInt(render_time_us)) / 1000.0; logger.log(elapsed, entities.count, frame_ms, update_ms, render_ms); + + // tracy frame mark + ztracy.FrameMark(); } } diff --git a/src/ssbo_renderer.zig b/src/ssbo_renderer.zig index 7a75bb7..49c697e 100644 --- a/src/ssbo_renderer.zig +++ b/src/ssbo_renderer.zig @@ -3,6 +3,7 @@ const std = @import("std"); const rl = @import("raylib"); +const ztracy = @import("ztracy"); const sandbox = @import("sandbox.zig"); const SCREEN_WIDTH = sandbox.SCREEN_WIDTH; @@ -142,17 +143,25 @@ pub const SsboRenderer = struct { rl.gl.rlDrawRenderBatchActive(); // copy entity data to GPU buffer (position + color only) - for (entities.items[0..entities.count], 0..) |entity, i| { - self.gpu_buffer[i] = .{ - .x = entity.x, - .y = entity.y, - .color = entity.color, - }; + { + const zone = ztracy.ZoneN(@src(), "ssbo_copy"); + defer zone.End(); + for (entities.items[0..entities.count], 0..) |entity, i| { + self.gpu_buffer[i] = .{ + .x = entity.x, + .y = entity.y, + .color = entity.color, + }; + } } // upload to SSBO - const data_size: u32 = @intCast(entities.count * @sizeOf(sandbox.GpuEntity)); - rl.gl.rlUpdateShaderBuffer(self.ssbo_id, self.gpu_buffer.ptr, data_size, 0); + { + const zone = ztracy.ZoneN(@src(), "ssbo_upload"); + defer zone.End(); + const data_size: u32 = @intCast(entities.count * @sizeOf(sandbox.GpuEntity)); + rl.gl.rlUpdateShaderBuffer(self.ssbo_id, self.gpu_buffer.ptr, data_size, 0); + } // bind shader rl.gl.rlEnableShader(self.shader_id); @@ -183,9 +192,13 @@ pub const SsboRenderer = struct { rl.gl.rlSetBlendMode(@intFromEnum(rl.gl.rlBlendMode.rl_blend_alpha)); // bind VAO and draw - _ = rl.gl.rlEnableVertexArray(self.vao_id); - rl.gl.rlEnableVertexBuffer(self.vbo_id); - rl.gl.rlDrawVertexArrayInstanced(0, 6, @intCast(entities.count)); + { + const zone = ztracy.ZoneN(@src(), "ssbo_draw"); + defer zone.End(); + _ = rl.gl.rlEnableVertexArray(self.vao_id); + rl.gl.rlEnableVertexBuffer(self.vbo_id); + rl.gl.rlDrawVertexArrayInstanced(0, 6, @intCast(entities.count)); + } // cleanup - restore raylib's expected state rl.gl.rlDisableVertexArray();