Files
codegirl-games/benchmarks/draw_sprite/main.odin
T
2026-08-09 08:26:59 +00:00

103 lines
2.4 KiB
Odin

package main
import "core:fmt"
import "core:os"
import eng "pkg:engine"
import sdl "vendor:sdl3"
PERF_ITERATIONS :: #config(PERF_ITERATIONS, 2_000_000)
PERF_WARMUP :: #config(PERF_WARMUP, 10_000)
PERF_TRIALS :: #config(PERF_TRIALS, 7)
@(private)
median :: proc(values: []f64) -> f64 {
for i in 1 ..< len(values) {
value := values[i]
j := i
for j > 0 {
if values[j - 1] <= value do break
values[j] = values[j - 1]
j -= 1
}
values[j] = value
}
middle := len(values) / 2
if len(values) & 1 == 1 do return values[middle]
return (values[middle - 1] + values[middle]) / 2
}
@(private)
run_draws :: proc(app: ^eng.App, sprite: ^eng.Sprite, iterations: int) -> u64 {
clear(&app.draw_list)
start := sdl.GetTicksNS()
for i in 0 ..< iterations {
if len(app.draw_list) >= eng.MAX_SPRITES {
clear(&app.draw_list)
}
// Vary an input so optimized builds cannot hoist the draw calculations.
sprite.position.x = f32(i & 1023)
eng.draw_sprite(app, sprite)
}
return sdl.GetTicksNS() - start
}
main :: proc() {
#assert(PERF_ITERATIONS > 0)
#assert(PERF_WARMUP > 0)
#assert(PERF_TRIALS > 0)
file_data, err := os.read_entire_file(
"assets_baked/characters/toad/toad.char.json",
context.allocator,
)
if err != nil {
fmt.eprintfln("benchmark asset read failed: %v", err)
return
}
defer delete(file_data)
def, ok := eng.parse_char_def(file_data)
if !ok do return
data := eng.Character_Data {
def = def,
texture = cast(^sdl.GPUTexture)uintptr(1),
width = 1911,
height = 1526,
}
app := eng.App {
cmd = cast(^sdl.GPUCommandBuffer)uintptr(1),
swapchain_texture = cast(^sdl.GPUTexture)uintptr(2),
swapchain_w = 800,
swapchain_h = 600,
camera = eng.camera_default(),
draw_list = make(
[dynamic]eng.Queued_Sprite,
0,
eng.MAX_SPRITES,
),
}
defer delete(app.draw_list)
sprite := eng.spawn_sprite(&data, {400, 400}, "walk", 4)
_ = run_draws(&app, &sprite, PERF_WARMUP)
samples: [PERF_TRIALS]f64
fmt.printfln(
"benchmark=draw_sprite iterations=%d warmup=%d trials=%d sprites_per_queue=%d",
PERF_ITERATIONS,
PERF_WARMUP,
PERF_TRIALS,
eng.MAX_SPRITES,
)
for trial in 0 ..< PERF_TRIALS {
elapsed := run_draws(&app, &sprite, PERF_ITERATIONS)
samples[trial] = f64(elapsed) / f64(PERF_ITERATIONS)
fmt.printfln("trial=%d ns_per_draw=%.3f", trial + 1, samples[trial])
}
fmt.printfln("median_ns_per_draw=%.3f", median(samples[:]))
}