Files
CoopAllTheThings/tests/present_overhead.hpp
BlackMark 30eccf749d Apply clang-format across the whole tree
Run clang-format (the repo's .clang-format: LLVM base, 120 cols, tabs,
Allman functions) over every source file so the tree is formatter-clean.
Whitespace only -- no behavior change; full x64 + x86 suites pass.

Also set SortIncludes: false in .clang-format. Windows include order is
load-bearing (windows.h must precede tlhelp32.h / mmreg.h / xinput.h /
dinput.h; winsock2.h must precede windows.h), and the default
alphabetical sort reorders tlhelp32.h ahead of windows.h -- a build
break. Leaving order alone keeps the manual, correct grouping.
2026-07-12 11:52:53 +02:00

44 lines
1.7 KiB
C++

// Shared helper for the per-backend present-thread overhead guards.
//
// The capture path (Present / SwapBuffers hook, or the Vulkan read-back) runs on the game's present
// thread. If it stalls there, it caps the game's frame rate -- the Vulkan layer did exactly this,
// dropping a 144 FPS game to ~3 FPS by spending ~370 ms per present reading write-combined memory.
// Each GPU backend's in-process hook test measures the wall time its present spends with the hook
// live vs. removed and asserts the added cost stays under one display frame, so a future regression
// that puts a synchronous read-back / stall back on the present thread fails the test.
#pragma once
#include <windows.h>
namespace cooptest {
inline double now_ms()
{
LARGE_INTEGER f, c;
QueryPerformanceFrequency(&f);
QueryPerformanceCounter(&c);
return 1000.0 * static_cast<double>(c.QuadPart) / static_cast<double>(f.QuadPart);
}
// Average wall time of `present()` over n frames, calling `render()` (untimed) before each so a
// fresh frame is produced. Returns milliseconds per present.
template <class RenderFn, class PresentFn>
double avg_present_ms(int n, RenderFn render, PresentFn present)
{
render();
present(); // warm (first present/resource setup)
double total = 0;
for (int i = 0; i < n; ++i) {
render();
const double a = now_ms();
present();
total += now_ms() - a;
}
return n > 0 ? total / n : 0.0;
}
// One 60 Hz display frame. The capture's added present-thread cost must stay well under this or it
// throttles the game; the Vulkan bug added ~370 ms (22x over budget). Generous on purpose -- the
// guard targets the catastrophic-stall class, not micro-overhead, so it never flakes on jitter.
inline constexpr double kPresentOverheadBudgetMs = 16.7;
} // namespace cooptest