dxgi: serialize D3D11 immediate context access during swap chain creation - #437
Open
elzuzu wants to merge 1 commit into
Open
dxgi: serialize D3D11 immediate context access during swap chain creation#437elzuzu wants to merge 1 commit into
elzuzu wants to merge 1 commit into
Conversation
…tion
Some applications keep driving the D3D11 immediate context from a worker thread
(e.g. polling queries via ID3D11DeviceContext::GetData) while the main thread is
still inside IDXGIFactory::CreateSwapChain. The D3D11 debug layer reports this as
a CORRUPTION severity message ("Two threads were found to be executing functions
associated with the same Device[Context] at the same time"). Without ReShade this
stays harmless in practice, but ReShade initializes its effect runtime on that same
immediate context during swap chain creation, and the NVIDIA driver then removes
the device intermittently (DXGI_ERROR_DEVICE_REMOVED or
DXGI_ERROR_DRIVER_INTERNAL_ERROR, roughly one launch in four).
Turn on ID3D11Multithread protection only for the duration of the swap chain
creation (the DXGI call plus the runtime initialization it triggers) and restore
the previous state afterwards, so applications that never enable it see no
behavior change once the swap chain exists.
Reproduced and measured on Mass Effect: Andromeda (Frostbite, D3D11) with an
RTX 5070 on driver 616.64: 8 device removals in 36 launches before, 0 in 24
launches with the early protection, 0 in 24 launches with this scoped variant.
Analysis, instrumentation and fix by Claude Fable 5.1 (Anthropic), operated by
the submitter.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PRy9ojuHXSA2UDupjrY7by
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Disclosure up front: the investigation, the instrumentation and this patch were done by an AI assistant (Claude Fable 5.1, through Claude Code) running on my machine; I provided the game, the hardware and the decisions, and I ran all the measurements below myself, so I can reproduce anything on request. If AI-assisted contributions are not wanted here, feel free to close this, no hard feelings.
Mass Effect: Andromeda (Frostbite, D3D11) loses its D3D11 device in roughly one launch out of four as soon as ReShade is loaded, showing the game's own "DirectX Error … DXGI_ERROR_DEVICE_REMOVED" dialog a few seconds after start. Without ReShade it never fails. The failure does not depend on add-ons (ReShade alone reproduces it), on the proxy name (
dxgi.dllord3d11.dll), on NVIDIA Smooth Motion, on Windows Auto HDR, on the windowed swap effect upgrade, and it survives a reboot.An instrumented build (
GetDeviceRemovedReasonlogged after creation and on failure, a 1 ms watchdog, and optionallyD3D11_CREATE_DEVICE_DEBUGwith the info queue streamed to the log) shows the device is alive right afterD3D11CreateDeviceand gets removed insideIDXGIFactory::CreateSwapChain(6 ms into the call in one capture) or on the first resource the effect runtime creates right after it, withDXGI_ERROR_DEVICE_REMOVEDorDXGI_ERROR_DRIVER_INTERNAL_ERROR. With the debug layer on, the runtime emits a CORRUPTION message about 450 ms after device creation:ID3D11DeviceContext::GetData: Two threads were found to be executing functions associated with the same Device[Context] at the same time.The game polls queries on the immediate context from a worker thread while its main thread is still creating the swap chain; on its own that stays harmless in practice, but ReShade initializes its runtime on the same immediate context during swap chain creation, and the NVIDIA driver then corrupts and removes the device.This change turns on
ID3D11Multithreadprotection on the immediate context only for the duration of the swap chain creation (the DXGI call plus the runtime initialization it triggers) and restores the previous state afterwards, on the four creation paths. Applications that already enable the protection are untouched, the others pay the critical section for one call only. A variant that enabled the protection permanently at device creation fixed the crash as well, but this scoped version keeps the per-call cost unchanged after start-up for games that never enable it.Measured on the same machine, back-to-back launches: 8 device removals in 36 launches without the patch (across all the configurations listed above), 0 in 24 launches with the permanent variant, 0 in 24 launches with this scoped version. Windows 11 26200, GeForce RTX 5070, driver 616.64, ReShade 6.8.0.2155 add-on build, Mass Effect: Andromeda 1.10 (EA app), 3440x1440 borderless. Logs from the instrumented runs are available if useful.
🤖 Generated with Claude Code