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>
31 lines
1.4 KiB
C++
31 lines
1.4 KiB
C++
// Injected D3D9 capture path: inline-hooks IDirect3DDevice9::Present (discovered from a
|
|
// throwaway device's vtable, so it catches the game's existing device regardless of when we
|
|
// injected) in Direct3D 9 / 9Ex games, which don't present via IDXGISwapChain. It reads the
|
|
// backbuffer back with GetRenderTargetData, swizzles BGRA->RGBA, and uploads it into the same
|
|
// shared keyed-mutex texture (coop_video_<pid>) the host samples. Part of the video subsystem,
|
|
// alongside present_hook and opengl_hook.
|
|
//
|
|
// A D3D9 backbuffer isn't directly shareable with D3D11, so this is a CPU read-back
|
|
// (GetRenderTargetData -> system memory -> upload via a hook-owned D3D11 device), like the
|
|
// OpenGL path. Works for both plain D3D9 and D3D9Ex (both call Present here).
|
|
#pragma once
|
|
|
|
#include "ipc_client.hpp"
|
|
|
|
namespace coop::hook
|
|
{
|
|
|
|
// Installs the D3D9 Present hook. `ipc` must outlive the hook. Returns true if Present was
|
|
// hooked (i.e. d3d9.dll is present and a probe device came up). Safe to call repeatedly.
|
|
bool install_d3d9_hooks(IpcClient& ipc);
|
|
|
|
// Removes the D3D9 hook and releases the shared texture (best effort).
|
|
void remove_d3d9_hooks();
|
|
|
|
// --- Diagnostics -----------------------------------------------------------
|
|
|
|
std::uint64_t d3d9_presents(); // cumulative IDirect3DDevice9::Present detours
|
|
std::uint64_t d3d9_frames_shared(); // frames uploaded into the shared texture
|
|
|
|
} // namespace coop::hook
|