Hi all,
For the past few months I have been working on improving the experimental Wayland driver (original announcement here [1], first update here [2]).
The result of this work is an update which adds several major features:
* Vulkan support * Multimonitor support * HiDPI handling * Cursor clipping/relative movement * Wayland keymap handling
To get, build and use the Wayland driver do (note that building with Wayland requires wayland-client, wayland-egl and xkbcommon development files to be present on the system):
$ git clone -b wayland https://gitlab.collabora.com/alf/wine/ $ cd wine $ ./configure --with-wayland [--with-vulkan --with-vkd3d] $ make [-jN] $ DISPLAY= WAYLAND_DISPLAY=wayland-0 ./wine ...
I have uploaded a video showcasing the new features here:
Vulkan support comes with window management handling (resizing, fullscreen etc), and can be used either directly or to implement Direct3D through either WineD3D or DXVK.
The Wayland driver now exposes multiple monitors to Wine and supports dynamic addition and removal of monitors. It also supports changing the application-perceived resolution of each monitor (through compositor scaling, see previous update [2]) to implement per-monitor mode changes.
For HiDPI handling the Wayland driver exposes a high resolution (i.e., the native monitor resolution) by default, and leaves it to the application/Wine to perform any scaling (e.g., setting LogPixels). Note that although Wayland supports per-monitor scale factors (but not mixed-scaling for the same Wayland surface) the Wine core support for this is not yet in place. At the moment, when windows are presented on multiple monitors with different (Wayland) scale factors, the part of the window in its "main" monitor is presented in high/native resolution while other parts are scaled by the compositor. The "main" monitor for a window changes only when that window moves fully to another monitor.
It's sometimes useful to let the Wayland compositor automatically perform a (naive) scaling based on the monitor scale factor. This is supported by setting the driver option HKCU\Software\Wine\Wayland Driver\HiDPIScaling (or corresponding per app option) to "Compositor" (the default being "Application").
To implement cursor clipping and provide relative mouse movement (important for first person perspective games) the driver utilizes heuristics to best map application requests to the corresponding Wayland functionality (pointer-constraints and relative-pointer protocols).
Finally, the new Wayland keymap handling allows users to transparently use the current keymap of their Wayland session in Wine applications (although it doesn't allow changing it from the Wine side).
---
I think the driver has reached a point where it has enough features to be useful for many use cases and also provide enough confidence that it is a viable option going forward. My plan now is to mainly focus on fixes/improvements and to start preparing for staging by creating a more upstream/review friendly patchset series.
I am looking forward to any feedback or questions.
Thanks, Alexandros
[1] https://www.winehq.org/pipermail/wine-devel/2020-December/178575.html [2] https://www.winehq.org/pipermail/wine-devel/2021-February/181325.html
Hey Alexandros,
On Mon, Jun 07, 2021 at 08:10:11PM +0300, Alexandros Frantzis wrote:
The Wayland driver now exposes multiple monitors to Wine and supports dynamic addition and removal of monitors. It also supports changing the application-perceived resolution of each monitor (through compositor scaling, see previous update [2]) to implement per-monitor mode changes.
FWIW there's something similar in Proton for winex11.drv - the "full screen hack"[0]. It provides much better and more consistent user experience with games than allowing them doing true modesets.
[0]: https://github.com/ValveSoftware/wine/blob/eef39a6e9c0a9b939521c7a5119225b48...
As of GPU creation:
--------------------------- dispay.c ---------------------------
/* TODO: Support multiple GPUs. Note that wayland doesn't currently expose GPU info. */ if (!wayland_init_gpu(gpu_devinfo, &gpu, gpu_index, gpu_guidW, driverW, &gpu_luid)) goto done;
----------------------------------------------------------------
Having LUIDs assigned to every GPU is important for Vulkan <-> DXGI interop and some games do depend on them just being present (e.g. Forza Horizon 4). That interop is also important for making sure that the correct GPU is being used across DX-on-Vulkan libraries (e.g. DXVK's DXGIAdapter used by VKD3D-Proton).
See VkPhysicalDeviceProperties2() and VkPhysicalDeviceIDProperties + how those are used by DXVK and VKD3D-Proton.
winex11.drv tries to use vkGetRandROutputDisplayEXT() to map outputs/providers to a vulkan device. This doesn't work particularly well when a GPU has no outputs connected (e.g. PRIME setups) or on Wayland where XRandR reports no providers.
Proton experimental improves on the situation a bit[1].
My suggestion is to do something similar to Proton in winewayland.drv:
gpus = vkEnumeratePhysicalDevices() if gpus: first one: primary, has all the outputs remaining: outputless else: create the faux one
We can also be smarter by trying to present to each wl_output from each device, but I believe we are going to be able to present from most GPUs to most outputs and I don't think it's worth spending time on yet.
[1]: https://github.com/ValveSoftware/wine/blob/50015f7e0bcd/dlls/winex11.drv/xra...
I don't expect a protocol that would help with vulkan device<->output mapping to be welcomed in Wayland. What Wine is doing is conceptually much closer to a full-blown compositor, and since we are just a client we have to resort to faking / stubbing things out and applying clever heuristics... and IMO that's okay.
It's not that X11 is perfect here either. It also requires quite a bit of wrangling in many areas, e.g. to map X11 focus behavior to Win32 concepts. X11's security holes^W^Wfeatures allow us to implement a few more things, that's true, and I'll miss them as a Wine developer, but with my "windowing" hat on I think it is a change for the better.
Personally, I am looking forward to winewayland.drv maturing :-)