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.
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.
mv game_tmp$DLL_EXT game$DLL_EXT
@ -47,5 +47,5 @@ if pgrep -f game_hot_reload.bin > /dev/null; then
exit 1
else
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

View File

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

View File

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

View File

@ -2,12 +2,13 @@
package main
import "core:c/libc"
import "core:dynlib"
import "core:fmt"
import "core:c/libc"
import "core:os"
import "core:log"
import "core:mem"
import "core:os"
import "libs:tracy"
when ODIN_OS == .Windows {
DLL_EXT :: ".dll"
@ -17,6 +18,8 @@ when ODIN_OS == .Windows {
DLL_EXT :: ".so"
}
TRACY_ENABLE :: #config(TRACY_ENABLE, false)
// We copy the DLL because using it directly would lock it, which would prevent
// the compiler from writing to it.
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.
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
// 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() {
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
tracking_allocator: mem.Tracking_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)
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 {
// This does the normal hot reload

View File

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