dxvk icon indicating copy to clipboard operation
dxvk copied to clipboard

[d3d8] Add an option to respect DISCARD only for dynamic write-only buffers

Open WinterSnowfall opened this issue 1 year ago • 4 comments

Fixes missing textures in Rayman 3, a problem that based on online testimonies started to occur with the transition to Windows 7.

Test on Windows XP have shown that the game renders properly, so native behavior on age-accurate systems seem to differ from d3d9, as in D3DLOCK_DISCARD appears to be respected only for D3DUSAGE_DYNAMIC + D3DUSAGE_WRITEONLY.

Making it a draft for now, as it would need more testing to ensure there are no regressions in other titles.

WinterSnowfall avatar Jul 13 '24 17:07 WinterSnowfall

Turns out this isn't exactly free (performance-wise), so I've hidden it behind a config option and enabled it only for Rayman 3. I have yet to see another game relying on this type of behavior, anyway.

WinterSnowfall avatar Jul 13 '24 22:07 WinterSnowfall

i can confirm game render are fixed

rmn3fx

mrdeathjr28 avatar Jul 14 '24 02:07 mrdeathjr28

The docs only mention DYNAMIC. Does WRITEONLY make a difference for DISCARD?

K0bin avatar Jul 14 '24 04:07 K0bin

The docs only mention DYNAMIC. Does WRITEONLY make a difference for DISCARD?

For this game in particular, yes. For what it's worth d3d8to9 is already doing this globally, however handling it this way appears to add a few queue syncs and is generally slower at times, hence the config option.

As mentioned in the commit, this behavior seems to have been default on Windows XP, but modern Windows will behave inline with what D3D9 does, namely allow DISCARD for both DYNAMIC and DYNAMIC + WRITEONLY, which is why the game is also broken on native currently.

The workarounds you'll find online involve disabling HWVP entirely, using a game ini config option, specifically in order to disallow DISCARD on the affected buffers.

WinterSnowfall avatar Jul 14 '24 05:07 WinterSnowfall

It makes a difference because Rayman 3 is doing undefined behaviour, namely writing to buffers after unlocking them (off by one error in reference counting I believe). Handling that is probably the more correct fix for this issue.

RibShark avatar Oct 05 '24 16:10 RibShark

It makes a difference because Rayman 3 is doing undefined behaviour, namely writing to buffers after unlocking them (off by one error in reference counting I believe). Handling that is probably the more correct fix for this issue.

If that were indeed the only problem, it would have been fixed just by disabling direct buffer mapping. Which it was not.

WinterSnowfall avatar Oct 05 '24 16:10 WinterSnowfall

It makes a difference because Rayman 3 is doing undefined behaviour, namely writing to buffers after unlocking them (off by one error in reference counting I believe). Handling that is probably the more correct fix for this issue.

Pretty sure we already handle this on the D3D9 side, which this calls into.

If we implemented Lock/Unlock strictly as documented, we wouldn't be running a single D3D9 game because they are literally all broken in one way or another (write after unlock, writing a READONLY buffer, relying on DISCARD not actually discarding, all sorts of fun interactions depending on which pool a buffer is in and what it's used for, ...)

doitsujin avatar Oct 05 '24 16:10 doitsujin