Performance: measure the D3D9/OpenGL readback; it is not a present stall

Doing the "failing perf test first": measured the OpenGL capture's present-thread
overhead at a real resolution instead of the test's 64x64 toy. It is ~0.68 ms at
1280x720 (and ~0.06 ms when it overlaps a busy present at 1080p) -- well under one
frame, even at 144 Hz. No budget makes it fail, so the off-thread / async-PBO
refactor is NOT warranted.

The Vulkan 144->3 FPS stall was catastrophic specifically because it read
WRITE-COMBINED staging memory (~370 ms/frame), not because read-back is
synchronous. D3D9 GetRenderTargetData (a D3DPOOL_SYSTEMMEM surface) and glReadPixels
(normal CPU memory) read CACHED memory, so there is no comparable stall.

What changed instead:
- opengl_hook_test now runs the present-overhead guard at 1280x720 (not 64x64), so
  it is meaningful -- a future write-combined-class regression trips the budget.
- README Lessons learned records the cached-vs-write-combined distinction so nobody
  needlessly off-threads the other backends.

The matching D3D9 present-overhead guard ships with the new d3d9_hook_test (test
coverage). Drops both Performance items from the roadmap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-24 01:35:42 +02:00
parent 66dd003c4c
commit abbc16aa4d
2 changed files with 13 additions and 10 deletions

View File

@@ -48,8 +48,12 @@ void release(T*& p)
p = nullptr;
}
}
constexpr int kW = 64;
constexpr int kH = 64;
// A realistic capture resolution (not a 64x64 toy) so the present-thread overhead guard below is
// meaningful: a future regression that puts a catastrophic synchronous stall back on the present
// thread (the Vulkan write-combined-memory class) shows up here. Measured capture overhead of the
// current cached-memory glReadPixels path stays ~0.06 ms even at 1080p, far under one frame.
constexpr int kW = 1280;
constexpr int kH = 720;
bool near_byte(std::uint8_t got, int expected)
{
return std::abs(static_cast<int>(got) - expected) <= 3;