Deduplicate the hook DLL and scrub history from its comments

Consolidate four copies of the keyed-mutex shared-texture setup
(present/opengl/d3d9/vk_capture) into one RAII SharedVideoTexture,
two copies of find_main_window into find_window.hpp, audio_hook's
hand-rolled detour guard into the shared DetourGate, the duplicated
vtable_method into vtable_hook.hpp, and the near-identical
Present/Present1 and SwapBuffers/wglSwapBuffers detour pairs into one
shared body each. The vk_layer and vk_capture_perf_test targets now
compile debug_log.cpp since the shared texture code logs.

Comments no longer narrate the past: drop stress-test/game anecdotes,
"used to"/"the old model" phrasing, plan-step labels, and pointers to
docs that do not exist; fix present_hook.hpp/opengl_hook.hpp claims
that predate the D3D12/D3D9/Vulkan backends. Net -266 lines, no
behavior change (full x64 + x86 suites pass, including the mock-game
hook/unhook storm).
This commit is contained in:
2026-07-12 08:53:58 +02:00
parent 05039ab104
commit 635ef51283
22 changed files with 358 additions and 624 deletions

View File

@@ -3,12 +3,12 @@
// how they get into the dispatch chain; the capture itself -- copy the presented image into a shared
// keyed-mutex D3D11 texture for the host to sample -- is identical, so it lives here once.
//
// Performance contract (the whole reason this is a separate component): the read-back must NOT stall
// the game's present thread. Against a real 144 FPS game the original inline version dropped it to
// ~3 FPS because it did the GPU copy + a synchronous CPU read of the mapped staging buffer + the
// swizzle + the D3D upload all on the present thread -- and the staging buffer was HOST_COHERENT (on
// a discrete GPU that's write-combined/uncached, where a scattered CPU read runs at PCIe latency:
// ~370 ms for one 1080p frame). This component fixes both halves:
// Performance contract (the whole reason this is a separate component): the read-back must NOT
// stall the game's present thread. Doing the GPU copy + a synchronous CPU read of the mapped
// staging buffer + the swizzle + the D3D upload on the present thread drops a 144 FPS game to a
// few FPS -- especially when the staging buffer is plain HOST_COHERENT (on a discrete GPU that's
// write-combined/uncached, where a scattered CPU read runs at PCIe latency: hundreds of ms for
// one 1080p frame). This component avoids both halves:
// * the present thread only records + submits the copy (sub-millisecond) and returns immediately;
// * a dedicated reaper thread waits the copy's fence, reads the staging buffer, swizzles and
// uploads -- off the critical path; and
@@ -34,6 +34,8 @@
#define VK_NO_PROTOTYPES
#include <vulkan/vulkan.h>
#include "shared_video_texture.hpp"
namespace coop::hook
{
@@ -131,8 +133,6 @@ private:
bool ensure_d3d();
void release_d3d();
bool ensure_shared_texture(UINT w, UINT h);
void release_shared();
void reaper_main();
void reap_slot(Slot& s);
@@ -150,11 +150,7 @@ private:
// --- D3D11 shared texture (reaper thread only) ---
ID3D11Device* m_d3d = nullptr;
ID3D11DeviceContext* m_d3d_ctx = nullptr;
ID3D11Texture2D* m_shared_tex = nullptr;
IDXGIKeyedMutex* m_shared_mutex = nullptr;
HANDLE m_shared_handle = nullptr;
UINT m_share_w = 0;
UINT m_share_h = 0;
SharedVideoTexture m_shared;
std::vector<unsigned char> m_rgba; // reaper scratch (swizzled frame)
unsigned long m_pid = 0;
std::function<void(std::uint32_t, std::uint32_t)> m_on_frame;