Skip to content

fix(dx8): Unbind device resources before Reset - #634

Open
tintinhamans wants to merge 1 commit into
GeneralsOnlineDevelopmentTeam:mainfrom
tintinhamans:arctic/go/fix/reset-device-after-failed-reset
Open

tintinhamans wants to merge 1 commit into
GeneralsOnlineDevelopmentTeam:mainfrom
tintinhamans:arctic/go/fix/reset-device-after-failed-reset

Conversation

@tintinhamans

@tintinhamans tintinhamans commented Oct 9, 2026 •

Copy link
Copy Markdown

DX8Wrapper::Reset_Device can crash inside the driver (DestroyResource during Reset) when the device still holds a bound vertex buffer, index buffer, texture or render target. Set_Vertex_Buffer / Set_Index_Buffer are deferred and only drop the wrapper's references, so the device keeps its bindings into Reset, which D3D8 forbids.

This replaces the unbind in Reset_Device, which ran before TestCooperativeLevel and so also touched a lost device, with a new Unbind_Device_Buffers that only runs once the device can be reset. Before Reset() it also invalidates the cached render states and resets the render target, and a failed Reset() no longer asserts in debug. Release_Device uses the same helper.

Until a Reset() succeeds the device is not touched, because it crashes in SetStreamSource after a failed Reset() even when TestCooperativeLevel reports it as resettable (CLIENT-55X). Everything else is still released on every attempt, so the device recovers once the blocking resource is gone.

Reproduced and verified on the upstream retail build on two GPUs. Binding a custom render target and forcing a device loss made Reset fail on every frame forever (2000+ failures, an endless reset storm) on both an Intel UHD 770 (igd9trinity32.dll) and an NVIDIA RTX 4070 Ti. With this change both reset cleanly and the game continues. A Reset() that keeps failing, with new default pool textures created between attempts, recovers after the blocking resource is released. In the field this maps to the DestroyResource crash group (CLIENT-55Y and related); the release that had only the render-target release still hit it ~17% of the time.

Same change as TheSuperHackers#3450.

@tintinhamans
tintinhamans force-pushed the arctic/go/fix/reset-device-after-failed-reset branch 3 times, most recently from 9f36faf to d4ed1dd Compare October 9, 2026 12:56
@tintinhamans
tintinhamans force-pushed the arctic/go/fix/reset-device-after-failed-reset branch from d4ed1dd to a9be7f5 Compare October 16, 2026 23:52
@tintinhamans tintinhamans changed the title fix(dx8): Unbind device resources before Reset and guard against a failed reset fix(dx8): Unbind device resources before Reset Oct 16, 2026
@tintinhamans
tintinhamans force-pushed the arctic/go/fix/reset-device-after-failed-reset branch 4 times, most recently from 2c74903 to 3a049b4 Compare October 17, 2026 22:34
@tintinhamans
tintinhamans force-pushed the arctic/go/fix/reset-device-after-failed-reset branch from 3a049b4 to 89e98b5 Compare October 18, 2026 00:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant