Introduce a Tracy/UE-Insights-style scoped-zone profiler that instruments the
engine's core per-frame systems and reports per-module/per-zone self vs total
time plus GPU frame timing.
- common/Profile.* : core zone collector (eve::prof). EV_PROFILE_* RAII macros
push {name,module,thread,parent,depth,start,end} into per-thread buffers;
frameMark() aggregates the frame into a call tree with self/total per module
and zone, sorted by self time. Cheap single-branch no-op when disabled.
Lives in common/ so any module can instrument without layering violations.
- profiler module (SLOT profiler): script API setEnabled()/beginFrame()/
endFrame()/begin()/end()/capture()/textReport()/frameMs()/gpuFrameMs().
Installs itself as the IRenderTracer so render passes become graphics zones.
- Instrument core hot systems: physics (World/World3D), animation, particles,
audio pump, ui render, scene transforms, map tiles, crowd, event pump.
- GPU timing: Vulkan timestamp queries around the present command buffer
(whole-frame), exposed via common/GpuTimer.h IGpuTimer capability provided by
graphics; read after the synchronous submit waits the in-flight fence.
- load.nut drives frameBegin()/endFrame() + section markers, no-op when absent.
- Tests: C++ unit (core aggregation self<total, render-pass zones) + script API.
Verified: all changed TUs compile against real VKBuilder/ECS/zeroerr headers;
module_depgraph.py --check / --check-layers pass. Full-link build blocked in
this env by a prebuilt third-party Squirrel version mismatch (unrelated).
24 lines
750 B
Plaintext
24 lines
750 B
Plaintext
// Built-in profiler script API smoke test.
|
|
function captureWorks() {
|
|
local p = eve.Profiler();
|
|
p.setEnabled(true);
|
|
p.beginFrame();
|
|
p.begin("scriptScope");
|
|
for (local i = 0; i < 1000; ++i) { /* busy */ }
|
|
p.end();
|
|
p.endFrame();
|
|
local rows = p.capture();
|
|
if (typeof rows != "array") return false;
|
|
local found = false;
|
|
foreach (r in rows) {
|
|
if (typeof r != "table") return false;
|
|
if (!("name" in r) || !("selfMs" in r) || !("totalMs" in r)) return false;
|
|
if (r.name == "scriptScope") found = true;
|
|
}
|
|
if (!found) return false;
|
|
if (p.frameMs() < 0.0) return false;
|
|
if (p.textReport().find("scriptScope") == null) return false;
|
|
p.setEnabled(false);
|
|
return true;
|
|
}
|