Add profiling to the game

This commit is contained in:
sergeypdev 2025-01-10 01:46:13 +04:00
parent 0f951b831b
commit 21545b1c9d
5 changed files with 66 additions and 18 deletions

View File

@ -35,7 +35,7 @@ esac
# Build the game. # Build the game.
echo "Building game$DLL_EXT" echo "Building game$DLL_EXT"
odin build game -extra-linker-flags:"$EXTRA_LINKER_FLAGS" -define:RAYLIB_SHARED=true -collection:common=./common -collection:game=./game -build-mode:dll -out:game_tmp$DLL_EXT -strict-style -vet -debug odin build game -extra-linker-flags:"$EXTRA_LINKER_FLAGS" -define:RAYLIB_SHARED=true -define:TRACY_ENABLE=true -collection:libs=./libs -collection:common=./common -collection:game=./game -build-mode:dll -out:game_tmp$DLL_EXT -strict-style -vet -debug
# Need to use a temp file on Linux because it first writes an empty `game.so`, which the game will load before it is actually fully written. # Need to use a temp file on Linux because it first writes an empty `game.so`, which the game will load before it is actually fully written.
mv game_tmp$DLL_EXT game$DLL_EXT mv game_tmp$DLL_EXT game$DLL_EXT
@ -47,5 +47,5 @@ if pgrep -f game_hot_reload.bin > /dev/null; then
exit 1 exit 1
else else
echo "Building game_hot_reload.bin" echo "Building game_hot_reload.bin"
odin build main_hot_reload -out:game_hot_reload.bin -strict-style -vet -debug odin build main_hot_reload -define:TRACY_ENABLE=true -collection:libs=./libs -out:game_hot_reload.bin -strict-style -vet -debug
fi fi

View File

@ -5,6 +5,7 @@ import "core:log"
import "core:math" import "core:math"
import lg "core:math/linalg" import lg "core:math/linalg"
import "game:physics/bvh" import "game:physics/bvh"
import "libs:tracy"
import rl "vendor:raylib" import rl "vendor:raylib"
Loaded_Texture :: struct { Loaded_Texture :: struct {
@ -26,6 +27,8 @@ Loaded_BVH :: struct {
} }
destroy_loaded_bvh :: proc(loaded_bvh: Loaded_BVH) { destroy_loaded_bvh :: proc(loaded_bvh: Loaded_BVH) {
tracy.Zone()
for &mesh_bvh in loaded_bvh.bvhs { for &mesh_bvh in loaded_bvh.bvhs {
bvh.destroy_bvh(&mesh_bvh) bvh.destroy_bvh(&mesh_bvh)
} }
@ -39,6 +42,8 @@ Asset_Manager :: struct {
} }
get_texture :: proc(assetman: ^Asset_Manager, path: cstring) -> rl.Texture2D { get_texture :: proc(assetman: ^Asset_Manager, path: cstring) -> rl.Texture2D {
tracy.Zone()
modtime := rl.GetFileModTime(path) modtime := rl.GetFileModTime(path)
existing, ok := assetman.textures[path] existing, ok := assetman.textures[path]
@ -73,6 +78,8 @@ get_model_ex :: proc(
modtime: c.long, modtime: c.long,
reloaded: bool, reloaded: bool,
) { ) {
tracy.Zone()
new_modtime := rl.GetFileModTime(path) new_modtime := rl.GetFileModTime(path)
existing, ok := assetman.models[path] existing, ok := assetman.models[path]
@ -109,11 +116,23 @@ get_model :: proc(assetman: ^Asset_Manager, path: cstring) -> rl.Model {
null_bvhs: []bvh.BVH null_bvhs: []bvh.BVH
get_bvh :: proc(assetman: ^Asset_Manager, path: cstring) -> Loaded_BVH { get_bvh :: proc(assetman: ^Asset_Manager, path: cstring) -> Loaded_BVH {
tracy.Zone()
loaded_bvh, ok := assetman.bvhs[path] loaded_bvh, ok := assetman.bvhs[path]
model, modtime, reloaded := get_model_ex(assetman, path, loaded_bvh.modtime) model, modtime, reloaded := get_model_ex(assetman, path, loaded_bvh.modtime)
should_recreate := reloaded || !ok should_recreate := reloaded || !ok
log.debugf(
"model %v\nmodtime %v\nreloaded %v\nok %v\nshould_recreate %v\nref_modtime %v",
model,
modtime,
reloaded,
ok,
should_recreate,
loaded_bvh.modtime,
)
if ok && should_recreate { if ok && should_recreate {
destroy_loaded_bvh(loaded_bvh) destroy_loaded_bvh(loaded_bvh)
delete_key(&assetman.bvhs, path) delete_key(&assetman.bvhs, path)
@ -155,6 +174,8 @@ get_bvh :: proc(assetman: ^Asset_Manager, path: cstring) -> Loaded_BVH {
} }
shutdown :: proc(assetman: ^Asset_Manager) { shutdown :: proc(assetman: ^Asset_Manager) {
tracy.Zone()
for _, texture in assetman.textures { for _, texture in assetman.textures {
rl.UnloadTexture(texture.texture) rl.UnloadTexture(texture.texture)
} }

View File

@ -22,6 +22,7 @@ import "core:math"
import "core:math/linalg" import "core:math/linalg"
import "game:physics" import "game:physics"
import "game:physics/bvh" import "game:physics/bvh"
import "libs:tracy"
import rl "vendor:raylib" import rl "vendor:raylib"
import "vendor:raylib/rlgl" import "vendor:raylib/rlgl"
@ -371,6 +372,8 @@ update_runtime_world :: proc(runtime_world: ^Runtime_World, dt: f32) {
} }
update :: proc() { update :: proc() {
tracy.Zone()
if rl.IsKeyPressed(.TAB) { if rl.IsKeyPressed(.TAB) {
g_mem.editor = !g_mem.editor g_mem.editor = !g_mem.editor
} }
@ -446,6 +449,8 @@ catmull_rom :: proc(a, b, c, d: rl.Vector3, t: f32) -> rl.Vector3 {
} }
draw :: proc() { draw :: proc() {
tracy.Zone()
rl.BeginDrawing() rl.BeginDrawing()
defer rl.EndDrawing() defer rl.EndDrawing()
rl.ClearBackground(rl.BLACK) rl.ClearBackground(rl.BLACK)
@ -778,6 +783,9 @@ spline_handle :: proc(
@(export) @(export)
game_update :: proc() -> bool { game_update :: proc() -> bool {
tracy.Zone()
defer tracy.FrameMark()
update() update()
draw() draw()
return !rl.WindowShouldClose() return !rl.WindowShouldClose()
@ -785,6 +793,8 @@ game_update :: proc() -> bool {
@(export) @(export)
game_init_window :: proc() { game_init_window :: proc() {
tracy.SetThreadName("Main")
rl.SetConfigFlags({.WINDOW_RESIZABLE, .VSYNC_HINT}) rl.SetConfigFlags({.WINDOW_RESIZABLE, .VSYNC_HINT})
rl.InitWindow(1280, 720, "Odin + Raylib + Hot Reload template!") rl.InitWindow(1280, 720, "Odin + Raylib + Hot Reload template!")
rl.SetExitKey(.KEY_NULL) rl.SetExitKey(.KEY_NULL)

View File

@ -2,12 +2,13 @@
package main package main
import "core:c/libc"
import "core:dynlib" import "core:dynlib"
import "core:fmt" import "core:fmt"
import "core:c/libc"
import "core:os"
import "core:log" import "core:log"
import "core:mem" import "core:mem"
import "core:os"
import "libs:tracy"
when ODIN_OS == .Windows { when ODIN_OS == .Windows {
DLL_EXT :: ".dll" DLL_EXT :: ".dll"
@ -17,6 +18,8 @@ when ODIN_OS == .Windows {
DLL_EXT :: ".so" DLL_EXT :: ".so"
} }
TRACY_ENABLE :: #config(TRACY_ENABLE, false)
// We copy the DLL because using it directly would lock it, which would prevent // We copy the DLL because using it directly would lock it, which would prevent
// the compiler from writing to it. // the compiler from writing to it.
copy_dll :: proc(to: string) -> bool { copy_dll :: proc(to: string) -> bool {
@ -62,7 +65,11 @@ load_game_api :: proc(api_version: int) -> (api: Game_API, ok: bool) {
} }
// NOTE: this needs to be a relative path for Linux to work. // NOTE: this needs to be a relative path for Linux to work.
game_dll_name := fmt.tprintf("{0}game_{1}" + DLL_EXT, "./" when ODIN_OS != .Windows else "", api_version) game_dll_name := fmt.tprintf(
"{0}game_{1}" + DLL_EXT,
"./" when ODIN_OS != .Windows else "",
api_version,
)
copy_dll(game_dll_name) or_return copy_dll(game_dll_name) or_return
// This proc matches the names of the fields in Game_API to symbols in the // This proc matches the names of the fields in Game_API to symbols in the
@ -95,6 +102,14 @@ unload_game_api :: proc(api: ^Game_API) {
main :: proc() { main :: proc() {
context.logger = log.create_console_logger() context.logger = log.create_console_logger()
when TRACY_ENABLE {
context.allocator = tracy.MakeProfiledAllocator(
self = &tracy.ProfiledAllocatorData{},
callstack_size = 5,
backing_allocator = context.allocator,
secure = true,
)
}
default_allocator := context.allocator default_allocator := context.allocator
tracking_allocator: mem.Tracking_Allocator tracking_allocator: mem.Tracking_Allocator
mem.tracking_allocator_init(&tracking_allocator, default_allocator) mem.tracking_allocator_init(&tracking_allocator, default_allocator)
@ -142,7 +157,8 @@ main :: proc() {
new_game_api, new_game_api_ok := load_game_api(game_api_version) new_game_api, new_game_api_ok := load_game_api(game_api_version)
if new_game_api_ok { if new_game_api_ok {
force_restart = force_restart || game_api.memory_size() != new_game_api.memory_size() force_restart =
force_restart || game_api.memory_size() != new_game_api.memory_size()
if !force_restart { if !force_restart {
// This does the normal hot reload // This does the normal hot reload

View File

@ -3,6 +3,7 @@
"collections": [ "collections": [
{ "name": "common", "path": "./common" }, { "name": "common", "path": "./common" },
{ "name": "game", "path": "./game" }, { "name": "game", "path": "./game" },
{ "name": "libs", "path": "./libs" }
], ],
"enable_semantic_tokens": false, "enable_semantic_tokens": false,
"enable_document_symbols": true, "enable_document_symbols": true,