protonscr

[D3D9] Leaked surface resources prevent the swapchain from recreating

dxvkopen d3d9
doitsujin/dxvk#5496 · opened 2026-02-06 by CookiePLMonster · updated 2026-02-06 · 7 comments · github
CCookiePLMonster 2026-02-06 github

Negligent D3D9 games may release their D3D9 device while also failing to properly release all their resources/surfaces/textures. This happens to Hard Truck 2 failing to release some of its system memory surfaces, before tearing down the D3D9 device and re-creating it shortly after on the same window.

With native D3D9, this works without observable issues. With DXVK, the second D3D9 device creation succeeds, but Present fails quietly (i.e. still returns S_OK to the game, but fails in practice) with a log spam of VK_ERROR_NATIVE_WINDOW_IN_USE_KHR swapchain creation failures.

Software information

Hard Truck 2: King of the Road, using a development version of D2GI that wraps the game from D3D7 to D3D9, with additional fixes.

System information

  • GPU: NVIDIA GeForce RTX 5070 Ti
  • Driver: 580.88
  • Wine version: N/A, on Windows
  • DXVK version: 2.7.1

Apitrace file(s)

N/A

Log files

When the issue happens, a spam of swapchain creation calls is logged:

info:  Presenter: Actual swapchain properties:
info:    Format:       VK_FORMAT_B8G8R8A8_UNORM
info:    Color space:  VK_COLOR_SPACE_SRGB_NONLINEAR_KHR
info:    Present mode: VK_PRESENT_MODE_IMMEDIATE_KHR (dynamic: yes)
info:    Buffer size:  1920x1080
info:    Image count:  3
err:   Presenter: Failed to create Vulkan swapchain: VK_ERROR_NATIVE_WINDOW_IN_USE_KHR
KK0bin maintainer 2026-02-06 github

We have an option for this case:

d3d9.countLosableResources = False

But maybe I need to look into how Windows behaves. I thought Windows denies Reset in this case too and IIRC some games also rely on this.

WWinterSnowfall 2026-02-06 github

# d3d9.countLosableResources = True

I don't think it hits that situation in this particular case, it appears to be more of a backend derp. If the failures were due to losable resources, you'd get an entirely different set of errors.

Also, if I understood it correctly, there's no Reset() calls at play here.

CCookiePLMonster 2026-02-06 github

d3d9.countLosableResources = False

No change sadly.

KK0bin maintainer 2026-02-06 github

I guess Winter is right then and I misunderstood you.

Does the game create multiple D3D9Swapchains?

CCookiePLMonster 2026-02-06 github

Does the game create multiple D3D9Swapchains?

No, however it does create multiple D3D9 devices on the same window: as in, creates a device for the intro FMV, then tears it down (and leaks the system memory surface in question), then creates another D3D9 device.

Ddoitsujin maintainer 2026-02-06 github

It's not really possible to support that. On Proton it probably works because wine will paper over us creating multiple swapchains, but on Windows that simply won't work.

Not sure what to do here, ideally games just wouldn't do that. We can't just randomly nuke D3D objecs out of existence that the app is still using either, and destroying the Vulkan presenter on Reset even if device reset fails is probably causing all sorts of other issues. No chance at all if the game keeps using that device afterwards anyway.

CCookiePLMonster 2026-02-06 github

Not sure what to do here, ideally games just wouldn't do that. We can't just randomly nuke D3D objecs out of existence that the app is still using either, and destroying the Vulkan presenter on Reset even if device reset fails is probably causing all sorts of other issues. No chance at all if the game keeps using that device afterwards anyway.

It's worth noting that the game does attempt to release the D3D9 device and even the entire D3D9, but I guess in practice the leaked surface keeps a reference to the device and thus won't let it destruct even in native D3D9?

Nothing extracted yet.