iXit / wine-nine-standalone

Build Gallium Nine support on top of an existing WINE installation
GNU Lesser General Public License v2.1
272 stars 23 forks source link

Wine Nine Broken in Wine 5.14 #83

Closed JDGBOLT closed 3 years ago

JDGBOLT commented 3 years ago

Wine has done a fix within version 5.14 which has completely broken Wine Nine. It would be more accurate to say that it exposed a bug that exists within Wine Nine. Within commits such as https://github.com/wine-mirror/wine/commit/a599d645e33a128fae2d6fbfd7fdc07a8cefda95 and such, functions such as EnumDisplaySettingsExW and ChangeDisplaySettingsExW now refuse to accept Device ID's in the form of L"\\.\DISPLAY1\Monitor0", Wine basically spits out an error 00c4:err:system:EnumDisplaySettingsExW Invalid device name L"\\.\DISPLAY1\Monitor0". within the log when those functions are being called. It appears it's something to do with the way that EnumDisplaySettings is supposed to be called, where it will only accept the first "\DISPLAY1" or the like, and due to the way that Wine Nine is interfacing with these functions it is getting the wrong device id's which in turn is breaking it from even being able to check display resolutions and the like.

The first error occurring at https://github.com/iXit/wine-nine-standalone/blob/master/d3d9-nine/d3dadapter9.c#L771, though there are others such as at https://github.com/iXit/wine-nine-standalone/blob/master/d3d9-nine/present.c#L277 and others in those 2 files. I was able to "fix" it on my side by say forcing the string passed to be "\DISPLAY1" or passing NULL in that parameter, but these are just quick hacks that probably wouldn't work in a multihead configuration or with multiple adapters. I am unfortunately not skilled enough with either the code base or the Win32 API to fully fix it and submit a PR, but hopefully the information that I have passed along will be enough to fix whatever is going wrong. I do notice the function being used in wine at https://github.com/wine-mirror/wine/blob/master/programs/explorer/desktop.c#L893 just for an example, though there are others. Hopefully this can be fully fixed, as I believe this is the cause of the weirdness that can sometimes occur when changing resolutions or switching from a fullscreen window with the proton fshack and others. Hopefully this proves useful, have spent much of today trying to figure out the correct fix but unfortunately just not experienced enough to suggest a true fix.

JDGBOLT commented 3 years ago

Just for completeness' sake, here is a patch/hack that I applied to my wine-nine-standalone to get it working with Wine 5.14, I have no doubt broke something but at least from my limited testing does seem to work in handling resolution changes and the like, it's basically just patching the main part that has games complaining about being unable to find a screen resolution, and also patching the presenter to have a limited size to be able to force the device name to be something that EnumDisplaySettingsExW and ChangeDisplaySettingsExW will accept, but this is in no way fixing the underlying problem, just patching/hacking over it to force it to work, but others might find it useful to at least get gallium nine/wine-nine-standalone working again with the latest Wine. fix.txt

axeldavy commented 3 years ago

Thanks for the bug report. @dhewg what do you think ?

@JDGBOLT If you have time to spend on the issue it would be useful. A good place to take a look is at the wined3d equivalent (d3d9/ wined3d/ and winex11.drv/ dirs) and understand what is the difference with what they do.

iiv3 commented 3 years ago

Today I first did bisect on wine then dug up in nine-standalone. I managed to "workaround" the issue in nine-standalone by removing the second internal loop in d3dadapter9.c::fill_groups().

What's the issue. The fill_groups() first loop calls EnumDisplayDevicesW(NULL,i,...). This returns all Adapter Devices. The second loop calls EnumDisplayDevicesW(AdapterDevice[i], j, ...) . This queries all Monitors attached to the adapter.

The problem is that EnumDisplaySettingsExW no longer accepts Monitors, only Adapters.


commit 46182aa559144e141a62a86be89779b14c87d906 user32: Check invalid device names in EnumDisplaySettingsExW().


I don't know how native Windows d3d9 handles multihead setups. Have you checked if native EnumDisplaySettingsEx accepts Monitors ? I think it could be checked, even on single monitor setup.

dhewg commented 3 years ago

Thanks everyone, nice analysis. My setup is currently broken, so can't test atm, but I think the fix should look something like this: 0001-d3d9-nine-don-t-pass-display-monitors-to-EnumDisplay.patch.txt Could you guys test that patch please? Preferably on a multi adapter/monitor setup too

ZwS commented 3 years ago

Hi @dhewg . I tested your patch and it worked for me! Thank you!

dhewg commented 3 years ago

Thanks @iiv3 and @ZwS for testing, patch is now on master!