Evaluate a common/shared D3D11 device-context hooking mechanism
#272 opened on Jul 8, 2026
Repository metrics
- Stars
- (9 stars)
- PR merge metrics
- (Avg merge 12h 19m) (108 merged PRs in 30d)
Description
Context
Raised during review of #268 (PR discussion: https://github.com/alandtse/open-shaders/pull/268#discussion_r3541870649).
globals::InstallD3DHooks(ID3D11DeviceContext*) in src/Globals.cpp is currently the single, centralized place where D3D11 device-context vtable detours are installed. It already conditionally delegates to feature-owned installers (e.g. globals::features::upscaling.perfMode.InstallFadeOverlayHook(a_context), UnderwaterDepthOfField::InstallD3DHooks(a_context)), while also directly hosting several hooks itself (ID3D11DeviceContext::Map/Unmap for framebuffer caching, VR stereo OMSetDepthStencilState/ClearDepthStencilView).
Discussion:
- alandtse: "There's no other common hooking method for this instead of modifying global? I wonder if we should break out the d3d hooks into a feature controlled common hook."
- Dlizzio: "There is no other common hooking method for this. Up to you if we should break out the d3d hooks."
Current state (surveyed in PR #268)
src/Globals.cppowns: Map/Unmap (framebuffer cache), VR OMSetDepthStencilState/ClearDepthStencilView (vtable 36/53), and dispatches to:PerfMode::InstallFadeOverlayHook(vtable 13,src/Features/Upscaling/PerfMode/DSSwap.cpp)UnderwaterDepthOfField::InstallD3DHooks(vtable 12/13,src/Features/UnderwaterDepthOfField.cpp)
HDRDisplay.cppindependently installs its own context/swapchain vfunc hooks (vtable 35OMSetBlendState, vtable 8 on swapchain) directly from the feature, without going throughglobals::InstallD3DHooks.- Several other features (
Skin,TerrainHelper,VolumetricShadows,VolumetricLighting,Upscaling) take anID3D11DeviceContext*but only for direct resource binding/copy calls, not for installing persistent vtable detours.
This means there are already two divergent patterns for context-vfunc hooking in the codebase (centralized dispatch from Globals.cpp, and ad hoc self-installation from HDRDisplay.cpp), plus growing pressure (PerfMode's Draw hook at vtable 13, and now UnderwaterDepthOfField's Draw/DrawIndexed hooks also at vtable 12/13) to detour the same vtable slots from multiple independent features.
Ask
Evaluate whether a shared/common "D3D context hook" facility is warranted instead of continuing to add calls directly inside globals::InstallD3DHooks, specifically:
- Should there be a common registration point (e.g. a small registry/dispatcher feature) that lets features register interest in specific vtable indices (Draw/DrawIndexed/Map/Unmap/OMSetDepthStencilState/etc.), so that:
- Only one detour per vtable slot is installed regardless of how many features care about it.
- Order-of-invocation and reentrancy behavior between features hooking the same slot is well defined.
- Should
HDRDisplay.cpp's independent hook installation be unified withglobals::InstallD3DHooksfor consistency? - What features would benefit most from this abstraction given current/likely growth (Upscaling/PerfMode, UnderwaterDepthOfField, HDRDisplay, VR stereo optimizations)?
- If a common hook is not justified, document the rationale/tradeoffs (e.g. added indirection/perf cost vs. current low number of consumers) so this doesn't need re-litigating each time a new feature needs a D3D hook.
Acceptance criteria
- A decision (with rationale) on whether to introduce a common/shared D3D context hooking mechanism.
- If yes: a design sketch (or follow-up implementation PR) covering registration API, ordering/conflict handling for shared vtable slots, and migration plan for existing hooks in
Globals.cpp,PerfMode,UnderwaterDepthOfField, andHDRDisplay. - If no: a short written rationale documented (e.g. in this issue or
src/Globals.cppcomments) for future reference.
Requested by @alandtse.