M2(DX9): D3D9 capture via Present read-back (covers plain D3D9 + D3D9Ex)

New d3d9_hook.cpp (own file like opengl_hook): inline-hooks
IDirect3DDevice9::Present (vtable index 17, discovered from a throwaway device;
clean prologue so inline is safe, stdcall() on x86) and read-backs the backbuffer
with GetRenderTargetData into a D3DPOOL_SYSTEMMEM surface, swizzles BGRA->RGBA,
and uploads it into the shared keyed-mutex texture on a hook-owned D3D11 device
(a D3D9 surface isn't D3D11-shareable). Both plain D3D9 and D3D9Ex call this same
Present, so one read-back path serves both -- the GPU shared-surface fast path
the plan sketched for D3D9Ex wasn't worth it. Wired into the video subsystem
(install/remove in dllmain); hook links d3d9.

mock_game_test decodes DX9 + DX9Ex frames through the hook; 15/15 ctest (incl.
the x86 sub-build). Roadmap: DX9 milestone done and removed (remaining
renumbered); architecture + lessons updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 11:55:06 +02:00
parent 5bccfd8b86
commit 67c1940d52
6 changed files with 456 additions and 34 deletions

View File

@@ -5,6 +5,7 @@ add_library(coop_hook SHARED
src/audio_hook.cpp
src/present_hook.cpp
src/opengl_hook.cpp
src/d3d9_hook.cpp
src/mkb_hook.cpp
src/debug_log.cpp
src/hook_registry.cpp)
@@ -22,6 +23,7 @@ target_link_libraries(coop_hook PRIVATE
ole32
mmdevapi
d3d11
d3d9
dxgi)
# The x86 sub-build (COOP_X86_HELPER_BUILD) stages alongside the x64 DLL in the