Prerequisites
Game Version
Bug Description
If you play a long match and then lock your screen (or get a UAC prompt), the game crashes right after you come back.
W3DShroud::render calls CopyRects every frame to upload the fog of war. On my NVIDIA card the driver seems to remember a little bit for every one of those calls, and it only allocates the memory for it when the device gets reset. So nothing looks wrong while playing, then the reset allocates all of it in one go.
At 120 fps that's about 30 MB per minute of match. After 20 minutes it's around 600 MB, which a 32-bit process doesn't always have. Then either Reset fails with E_OUTOFMEMORY, or it works but the next texture load fails and we crash on a null surface in TextureLoadTaskClass::Lock_Surfaces.
It builds up per frame, so lower fps just means it takes longer.
Reproduction Steps
- Start a skirmish or online match on an NVIDIA GPU, windowed
- Play for 20+ minutes
- Press Win+L, then unlock
- Game crashes a moment later
Switching the monitor refresh rate and back does the same thing if you don't want to lock.
Additional Context
I logged free address space right before and after the Reset call. Reset at 7 minutes into a match:
before Reset: free address space=926 MB, largest free block=443 MB
after Reset: free address space=721 MB, largest free block=269 MB
New allocations during Reset: 13, 205 MB in total
At 20 minutes it went from 754 MB free to 193 MB and all three clients I had running crashed.
As a test I made one client stop uploading the shroud after the first few seconds. Same match, same reset, and that client lost 0 MB, so it really is this call.
An ETW trace shows the allocations come from Reset_Device → d3d8.dll → nvd3dum.dll. I also dumped the new memory blocks and they're full of records for a 106 px wide 16-bit surface, which is the shroud.
Prerequisites
Game Version
Bug Description
If you play a long match and then lock your screen (or get a UAC prompt), the game crashes right after you come back.
W3DShroud::rendercallsCopyRectsevery frame to upload the fog of war. On my NVIDIA card the driver seems to remember a little bit for every one of those calls, and it only allocates the memory for it when the device gets reset. So nothing looks wrong while playing, then the reset allocates all of it in one go.At 120 fps that's about 30 MB per minute of match. After 20 minutes it's around 600 MB, which a 32-bit process doesn't always have. Then either
Resetfails withE_OUTOFMEMORY, or it works but the next texture load fails and we crash on a null surface inTextureLoadTaskClass::Lock_Surfaces.It builds up per frame, so lower fps just means it takes longer.
Reproduction Steps
Switching the monitor refresh rate and back does the same thing if you don't want to lock.
Additional Context
I logged free address space right before and after the
Resetcall. Reset at 7 minutes into a match:before Reset: free address space=926 MB, largest free block=443 MB
after Reset: free address space=721 MB, largest free block=269 MB
New allocations during Reset: 13, 205 MB in total
At 20 minutes it went from 754 MB free to 193 MB and all three clients I had running crashed.
As a test I made one client stop uploading the shroud after the first few seconds. Same match, same reset, and that client lost 0 MB, so it really is this call.
An ETW trace shows the allocations come from
Reset_Device→d3d8.dll→nvd3dum.dll. I also dumped the new memory blocks and they're full of records for a 106 px wide 16-bit surface, which is the shroud.