alandtse/open-shaders

Evaluate a common/shared D3D11 device-context hooking mechanism

Open

#272 opened on Jul 8, 2026

View on GitHub
 (1 comment) (1 reaction) (1 assignee)C++ (0 forks)github user discovery
help wanted

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.cpp owns: 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.cpp independently installs its own context/swapchain vfunc hooks (vtable 35 OMSetBlendState, vtable 8 on swapchain) directly from the feature, without going through globals::InstallD3DHooks.
  • Several other features (Skin, TerrainHelper, VolumetricShadows, VolumetricLighting, Upscaling) take an ID3D11DeviceContext* 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:

  1. 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.
  2. Should HDRDisplay.cpp's independent hook installation be unified with globals::InstallD3DHooks for consistency?
  3. What features would benefit most from this abstraction given current/likely growth (Upscaling/PerfMode, UnderwaterDepthOfField, HDRDisplay, VR stereo optimizations)?
  4. 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, and HDRDisplay.
  • If no: a short written rationale documented (e.g. in this issue or src/Globals.cpp comments) for future reference.

Requested by @alandtse.

Contributor guide