Запускаем игры под Wine c поддержкой Native Wayland

Wine Wayland

Иллюстрации к статье подготовлены нейросетью freepik.com.

Многие люди на планете играют в видео игры. Игры помогают улучшить когнитивные способности, провести приятно свободное время. Данная статья посвящена тому, как запустить Windows игры под Linux в Wayland.

Эта статья могла бы быть: ставим Wine (Proton) и XWayland, запускаем игры, успех, но нет. В данной статье мы будем сами собирать Wine, решать проблемы, а так же наш Wine будет работать напрямую с Wayland композитором без прослойки в виде XWayland. Плюсы такого метода лучшая производительность и меньше инпут лаг. Благодаря Wine 9.0 это стало возможно, но не все так просто, как может показаться читателю с первого взгляда. Для примера мы запустим игры: Overwatch 2 через Battle.net клиент и Aimbeast, KovaaK’s, Apex Legends через Steam.

Если вас заинтересовала статья, то добро пожаловать под cut.


Подготовка окружения

Первым делом нам нужно установить все необходимые зависимости для сборки Wine. В Fedora Linux это можно сделать командой:

sudo dnf builddep wine

Если у вас другой дистрибутив Linux, то вы можете найти соответствующую информацию по ссылке: https://wiki.winehq.org/Building_Wine

После установки сборочных зависимостей нам необходимо скачать исходный код проектов Wine, Wine-Staging, Proton.

Создадим рабочую директорию, где будем хранить исходные коды, скачаем необходимые патчи, которые мы будем применять к нашей сборке Wine.

mkdir ~/code && cd ~/code
git clone https://github.com/h0tc0d3/wine-wayland

Список и описание патчей:


  • 0001-winewayland.drv-Advertise-common-display-modes.patch,
    0002-winewayland.drv-Advertise-display-modes-for-8-bpp-an.patch,
    0003-winewayland.drv-Dissociate-current-display-mode-from.patch,
    0004-winewayland.drv-Respect-current-device-mode-on-displ.patch,
    0005-winewayland.drv-Associate-each-GDI-adapter-with-its-.patch,
    0006-winewayland.drv-Adjust-window-scaling-based-on-the-m.patch,
    0007-winewayland.drv-Refresh-surfaces-after-display-confi.patch Позволяет менять разрешение и частоту экрана в Wayland драйвере Wine. Т.е. в играх появляется возможность изменять разрешение и частоту экрана. Подробнее: https://gitlab.winehq.org/wine/wine/-/merge_requests/4947, https://gitlab.winehq.org/wine/wine/-/merge_requests/5057.


  • 0008-user32-tests-Test-that-display-settings-are-restored.patch,
    0009-winex11.drv-Call-X11DRV_DisplayDevices_RegisterEvent.patch,
    0010-winex11.drv-Process-events-in-X11DRV_GetCurrentDispl.patch,
    0011-win32u-explorer-Restore-display-settings-on-process-.patch Патчи восстанавливают разрешение экрана при выходе из приложения. Проблема вызывала зависание и падение некоторых приложений, при закрытии их. Проблема не связана с Wayland и проблема в user32.dll. Важный патч т.к. некоторые игры при выходе зависали с черным экраном. Чтобы решить зависание нужно было переключить на отдельный рабочий стол или терминал, и принудительность завершить процессы Wine, что не очень удобно. Подробнее: https://bugs.winehq.org/show_bug.cgi? id=49674, https://gitlab.winehq.org/wine/wine/-/merge_requests/5060.


  • 0012-ntdll-Better-track-thread-pool-wait-s-wait_pending-s.patch,
    0013-ntdll-Make-sure-wakeups-from-already-unset-events-ar.patch Решает проблему с thread pool races condition, которая могла приводить к зависанию некоторых приложений. Подробнее: https://gitlab.winehq.org/wine/wine/-/merge_requests/5044.


  • 0014-wined3d-Merge-shader_load_constants-into-shader_sele.patch,
    0015-wined3d-Introduce-a-separate-vp_disable-method.patch,
    0016-wined3d-Introduce-a-separate-fp_disable-method.patch,
    0017-wined3d-Pass-a-wined3d_state-pointer-to-the-vp_enabl.patch,
    0018-wined3d-Pass-a-non-const-wined3d_context-pointer-to-.patch,
    0019-wined3d-arb-Move-fragment-program-compilation-from-f.patch Рефакторинг и оптимизации wined3d. Подробнее: https://gitlab.winehq.org/wine/wine/-/merge_requests/5053.


  • 0020-ntdll-Avoid-sending-context-in-wait_suspend-when-not.patch Оптимизация в ntdll. Подробнее: https://gitlab.winehq.org/wine/wine/-/merge_requests/4914.


  • 0021-winewayland.drv-Add-unaccelerated-pointer-support.patch Добавляет Raw Input мыши в Wayland, что полезно в шутерах. Патч разработан мной. Не совместим с Raw Input патчем из Wine-Staging для X11 т.к. сам по себе этот патч из Wine-Staging кривой и ломает ввод в Wayland, и это не ошибка моего патча. Merge Request: https://gitlab.winehq.org/wine/wine/-/merge_requests/4698.


  • 0022-Replace-CLOCK_MONOTONIC_RAW-with-CLOCK_MONOTONIC.patch Заменяет CLOCK_MONOTONIC_RAW на CLOCK_MONOTONIC т.к. запрос времени у ядра с CLOCK_MONOTONIC_RAW занимает больше времени. Теоретически это должно чуть улучшить производительность.


  • 0023-Add-Fsync-support.patch Добавляет поддержку Fsync, что позволяет добиться лучшей производительности в играх. Стоит отметить, что мы не будем добавлять патч для поддержки Esync т.к. он является устаревшим, имеет хуже производительность, плюс добавляет лишние вызовы функций в коде Wine.


  • 0024-Add-Steam-support.patch Добавляет код загрузки библиотеки lsteamclient.dll.so необходимой для авторизации игр. В оригинале этот патч загружает еще gameoverlayrenderer, необходимый для Steam Overlay. Но оверлей может чуть снижать производительность и не известно, как он будет работать под Wayland (у меня не было времени протестировать). Судя по коду многие вещи в Steam прибиты гвоздями к X11. Поэтому код загрузки gameoverlayrenderer был удален и если кто-то хочет проверить, включить поддержку игрового оверлея обратитесь к оригинальному патчу и добавьте эти две строчки кода.


!RtlCompareUnicodeStrings(basename, basename_len, L"gameoverlayrenderer", 19, TRUE) ||
!RtlCompareUnicodeStrings(basename, basename_len, L"gameoverlayrenderer64", 21, TRUE)) &&


Если ваша игра, например Apex Legends, просит авторизировать игру в другом сервисе и для этого использует Steam Overlay, то я рекомендую вам временно воспользоваться другой версией Proton, авторизировать игру, и переключиться обратно на нашу версию Proton — Wine. Про то, как превратить Wine из этой статьи в Proton будет написано во второй части статьи.


  • 0025-Add-EasyAnticheat.patch Добавляет код загрузки Easy Anticheat необходимого для игры Apex Legends.
  • 0026-Fix-Battle.net-client.patch Решает проблему, что последние версии Battle.net падают при запуске.
  • 0027-Update-configure-files.patch Не обязательный патч, меняет чуть конфигурационные файлы и меняет некоторые флаги сборки. Включает патч из исходников Fedora Linux и некоторые мои правки.

Клонируем код проекта Wine. Создадим рабочую ветку git с названием dev и применим к ней наши патчи.

git clone https://gitlab.winehq.org/wine/wine.git
cd wine
git checkout tags/wine-9.2 -b dev
git am ../wine-wayland/0001-winewayland.drv-Advertise-common-display-modes.patch
git am ../wine-wayland/0002-winewayland.drv-Advertise-display-modes-for-8-bpp-an.patch
git am ../wine-wayland/0003-winewayland.drv-Dissociate-current-display-mode-from.patch
git am ../wine-wayland/0004-winewayland.drv-Respect-current-device-mode-on-displ.patch
git am ../wine-wayland/0005-winewayland.drv-Associate-each-GDI-adapter-with-its-.patch
git am ../wine-wayland/0006-winewayland.drv-Adjust-window-scaling-based-on-the-m.patch
git am ../wine-wayland/0007-winewayland.drv-Refresh-surfaces-after-display-confi.patch
git am ../wine-wayland/0008-user32-tests-Test-that-display-settings-are-restored.patch
git am ../wine-wayland/0009-winex11.drv-Call-X11DRV_DisplayDevices_RegisterEvent.patch
git am ../wine-wayland/0010-winex11.drv-Process-events-in-X11DRV_GetCurrentDispl.patch
git am ../wine-wayland/0011-win32u-explorer-Restore-display-settings-on-process-.patch
git am ../wine-wayland/0012-ntdll-Better-track-thread-pool-wait-s-wait_pending-s.patch
git am ../wine-wayland/0013-ntdll-Make-sure-wakeups-from-already-unset-events-ar.patch
git am ../wine-wayland/0014-wined3d-Merge-shader_load_constants-into-shader_sele.patch
git am ../wine-wayland/0015-wined3d-Introduce-a-separate-vp_disable-method.patch
git am ../wine-wayland/0016-wined3d-Introduce-a-separate-fp_disable-method.patch
git am ../wine-wayland/0017-wined3d-Pass-a-wined3d_state-pointer-to-the-vp_enabl.patch
git am ../wine-wayland/0018-wined3d-Pass-a-non-const-wined3d_context-pointer-to-.patch
git am ../wine-wayland/0019-wined3d-arb-Move-fragment-program-compilation-from-f.patch
git am ../wine-wayland/0020-ntdll-Avoid-sending-context-in-wait_suspend-when-not.patch
git am ../wine-wayland/0021-winewayland.drv-Add-unaccelerated-pointer-support.patch
git am ../wine-wayland/0022-Replace-CLOCK_MONOTONIC_RAW-with-CLOCK_MONOTONIC.patch
git am ../wine-wayland/0023-Add-Fsync-support.patch
git am ../wine-wayland/0024-Add-Steam-support.patch
git am ../wine-wayland/0025-Add-EasyAnticheat.patch
git am ../wine-wayland/0026-Fix-Battle.net-client.patch
git am ../wine-wayland/0027-Update-configure-files.patch
cd ..

Клонируем код проекта Wine-Staging. Wine-Staging патчи нам необходимы для того, чтобы решить проблемы запуска некоторых игр и проблемы с низкой производительностью в играх. Так как мы применили к нашему Wine свои патчи, и код немного отличается, то необходимо перебазировать некоторые патчи Wine-Staging. Это мы сделаем с помощью патча wine-staging.patch.

git clone https://gitlab.winehq.org/wine/wine-staging.git
cd wine-staging
git checkout tags/v9.2 -b dev
git am ../wine-wayland/wine-staging.patch
cd ..

Клонируем код проекта Proton. Из проекта Proton нам понадобятся компоненты: lsteamclient, steam_helper, которые необходимы для запуска и авторизации игр
Steam. Иначе наши игры не будут находить лицензию и не будут работать нормально. Так же проект содержит библиотеки vrclient_x64 и wineopenxr для систем виртуальной реальности, но мы их не будем собирать т.к. они многим не нужны, и как мне известно vrclient_x64 прибит гвоздями к X11.

git clone https://github.com/ValveSoftware/Proton proton
cd proton
git checkout proton_8.0
git clone https://github.com/liberationfonts/liberation-fonts fonts/liberation-fonts
git submodule update --init fonts/liberation-fonts
git clone https://github.com/ValveSoftware/openvr
git submodule update --init openvr
cd ..

Если во время клонирования репозитория у вас возникает ошибка:

error: RPC failed; curl 16 HTTP/2 send again with decreased length
fatal: expected 'packfile'

То перед клонированием репозитория временно включите принудительно протокол HTTP/1.1:

git config --global http.version HTTP/1.1

И после того, как склонировали репозиторий, обратно включите поддержку HTTP/2:

git config --global http.version HTTP/2

Это должно решить проблему.


Сборка Wine

5rgusi09cmwhcowud_yowfb5k24.jpeg

Для сборки мы будем использовать bash код ниже, он снабжен комментариями, но нужно сделать несколько пояснений. Я собираю исходный код в директории /tmp, чтобы ускорить сборку и не тратить ресурс NVME диска. Во многих современных системах /tmp смонтирован в ОЗУ, и очищается при перезагрузке. У меня 32 гб, но если у вас 16 гб ОЗУ, то и этого вероятно будет достаточно для сборки в /tmp. Вы можете указать любую другую директорию для сборки.


Не указывайте пути типа / т.к. в скрипте есть не безопасный вызов rm -fr "${BUILD_DIR:?}" и вы можете удалить нужные вам файлы.

Для лучшей производительности это будет сборка под железо нашего компьютера. Она не рассчитана для распространения через сеть т.к. мы применим оптимизации кода компилятором под наш процессор. Флаг компилятора -march=native автоматически определит оптимальные параметры сборки. В 32 битных флагах компилятора мы не можем указать -march= для оптимизации т.к. 32 битные системы не поддерживают некоторые современные инструкции процессоров, и даже если мы соберем программу, не редко она упадет при запуске. Вместо этого мы можем использовать -mtune для лучшей оптимизации 32 битной версии под наш процессор. Вы можете заменить native на вашу архитектуру процессора, например znver3. Подробнее узнать о существующих архитектурах и флагах оптимизации, вы можете по ссылке: https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html. Так же в Fedora Linux мне понадобилось прописать дополнительные пути к заголовочным файлам, необходимым для сборки 32 битной версии Wine т.к. конфигуратор сборки отказывался их находить.


Для полноценной работы программ, нам необходимо иметь 32 и 64 битный Wine. Если мы соберем только 64 битную версию и запустим, программы могут отказаться работать! Связанно это с тем, что некоторые современные программы используют 32 битные исполняемые файлы и библиотеки.

Из Wine-Staging мы не будем применять все патчи, т.к. некоторые патчи при работе были не стабильны, вызывали проблемы или зависание Wine, и так же не будем добавлять патчи для поддержки старых версий Windows. Были добавлены только патчи, которые на мой взгляд имеет смысл применять к нашей сборке Wine.

Список патчей Wine-Staging:

dsound-Fast_Mixer
gdiplus-Performance-Improvements
loader-KeyboardLayouts
ntdll-APC_Performance
ntdll-HashLinks
ntdll-Hide_Wine_Exports
ntdll-Serial_Port_Detection
ntdll-Junction_Points
ntdll-NtDevicePath
ntdll-ProcessQuotaLimits
ntdll-RtlQueryPackageIdentity
ntdll_reg_flush
programs-where
server-File_Permissions
server-Stored_ACLs
server-default_integrity
setupapi-DiskSpaceList
setupapi-DriverStoreFindDriverPackageW
kernel32-CopyFileEx
shell32-SHFileOperation_Move
shell32-Progress_Dialog
shell32-ACE_Viewer
shell32-Context_Menu
shell32-IconCache
shell32-NewMenu_Interface
shell32-SFGAO_HASSUBFOLDER
shell32-SHGetStockIconInfo
shell32-registry-lookup-app
shlwapi-AssocGetPerceivedType
shlwapi-UrlCanonicalize
shlwapi-UrlCombine
user32-DM_SETDEFID
user32-Dialog_Paint_Event
user32-DrawTextExW
user32-FlashWindowEx
user32-Implement-CascadeWindows
user32-ListBox_Size
user32-LoadKeyboardLayoutEx
user32-Refresh_MDI_Menus
user32-ScrollWindowEx
user32-message-order
user32-msgbox-Support-WM_COPY-mesg
vcomp_for_dynamic_init_i8
windows.networking.connectivity-new-dll
windowscodecs-GIF_Encoder
windowscodecs-TIFF_Support
wined3d-Accounting
wined3d-atomic_minmax_merge
wined3d-bindless-texture
wined3d-mesa_texture_download
wined3d-rotate-WINED3D_SWAP_EFFECT_DISCARD
wined3d-unset-flip-gdi
wined3d-WINED3DFMT_B8G8R8X8_UNORM
wined3d-wined3d_guess_gl_vendor
wined3d-zero-inf-shaders
winedevice-Default_Drivers
winepulse-PulseAudio_Support
winepulse-aux_channels
wintrust-WTHelperGetProvCertFromChain

Устанавливать Wine мы будем в домашней директории пользователя ${HOME:?}/wine, т.к. для установки это не требует повышение прав пользователя до root, и мы сможем иметь несколько разных версией Wine. Например, нашу самосборную, и Wine из поставки нашего дистрибутива Linux. В случае каких-то проблем, можно легко и без переустановки переключиться на другую версию. Удалить наш Wine так же легко, достаточно выполнить удаление соответствующей директории, сделать это можно командой rm -fr "${HOME:?}/wine".

Собираем Wine.

#!/usr/bin/bash

# Директория в которой хранятся исходные коды.
SOURCE_DIR="${HOME:?}/code"
# Директория в которой будет происходить сборка Wine.
BUILD_DIR="/tmp/build-wine"
# Директория в которую установится Wine.
INSTALL_DIR="${HOME:?}/wine"
# Флаги компиляции 64 битной версии Wine.
BUILD_CFLAGS="-march=native -mtune=native"
# Флаги компиляции 32 битной версии Wine.
BUILD_CFLAGS_32="-mtune=native -I/usr/include/freetype2 -I/usr/include/gstreamer-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include"
# Параметры сборки Wine.
BUILD_OPTIONS=(
    --x-includes=/usr/include
    --with-x
    --with-wayland
    --with-vulkan
    --with-dbus
    --with-gstreamer
    --without-cups
    --without-sane
    --without-capi
    --without-gphoto
    --without-unwind
    --without-pcap
    --without-v4l2
    --without-xinputwinebuild   
    --without-xinerama
    --disable-tests
    --disable-win16
)

# Если возникает ошибка, то прекращаем выполнение дальнейших команд.
set -euo pipefail

# Создаем директорию в которой будет проходить сборка, если существует удаляем и создаем заново.
rm -fr "${BUILD_DIR:?}"
mkdir -p "${BUILD_DIR:?}"

# Сбрасываем все флаги сборки, если наши переменные окружения установлены.
unset CPPFLAGS
unset CFLAGS
unset CXXFLAGS
unset LDFLAGS

# Очищаем исходный код Wine перед сборкой.
cd "${SOURCE_DIR:?}/wine"
git reset --hard
git clean -fd

# Устанавливаем флаги сборки 64 битной версии Wine.
export CPPFLAGS="${BUILD_CFLAGS:?}"
export CFLAGS="${BUILD_CFLAGS:?}"
export CXXFLAGS="${BUILD_CFLAGS:?}"
export LDFLAGS="-Wl,-O1 -Wl,--as-needed -Wl,--no-copy-dt-needed-entries -Wl,--sort-common -Wl,--hash-style=gnu"

# Применяем Wine-Staging патчи к нашему исходному коду Wine.
python "${SOURCE_DIR:?}/wine-staging/staging/patchinstall.py" DESTDIR="${SOURCE_DIR:?}/wine" \
    dsound-Fast_Mixer \
    gdiplus-Performance-Improvements \
    loader-KeyboardLayouts \
    ntdll-APC_Performance \
    ntdll-HashLinks \
    ntdll-Hide_Wine_Exports \
    ntdll-Serial_Port_Detection \
    ntdll-Junction_Points \
    ntdll-NtDevicePath \
    ntdll-ProcessQuotaLimits \
    ntdll-RtlQueryPackageIdentity \
    ntdll_reg_flush \
    programs-where \
    server-File_Permissions \
    server-Stored_ACLs \
    server-default_integrity \
    setupapi-DiskSpaceList \
    setupapi-DriverStoreFindDriverPackageW \
    kernel32-CopyFileEx \
    shell32-SHFileOperation_Move \
    shell32-Progress_Dialog \
    shell32-ACE_Viewer \
    shell32-Context_Menu \
    shell32-IconCache \
    shell32-NewMenu_Interface \
    shell32-SFGAO_HASSUBFOLDER \
    shell32-SHGetStockIconInfo \
    shell32-registry-lookup-app \
    shlwapi-AssocGetPerceivedType \
    shlwapi-UrlCanonicalize \
    shlwapi-UrlCombine \
    user32-DM_SETDEFID \
    user32-Dialog_Paint_Event \
    user32-DrawTextExW \
    user32-FlashWindowEx \
    user32-Implement-CascadeWindows \
    user32-ListBox_Size \
    user32-LoadKeyboardLayoutEx \
    user32-Refresh_MDI_Menus \
    user32-ScrollWindowEx \
    user32-message-order \
    user32-msgbox-Support-WM_COPY-mesg \
    vcomp_for_dynamic_init_i8 \
    windows.networking.connectivity-new-dll \
    windowscodecs-GIF_Encoder \
    windowscodecs-TIFF_Support \
    wined3d-Accounting \
    wined3d-atomic_minmax_merge \
    wined3d-bindless-texture \
    wined3d-mesa_texture_download \
    wined3d-rotate-WINED3D_SWAP_EFFECT_DISCARD \
    wined3d-unset-flip-gdi \
    wined3d-WINED3DFMT_B8G8R8X8_UNORM \
    wined3d-wined3d_guess_gl_vendor \
    wined3d-zero-inf-shaders \
    winedevice-Default_Drivers \
    winepulse-PulseAudio_Support \
    winepulse-aux_channels \
    wintrust-WTHelperGetProvCertFromChain

# Создаем директорию сборки 64 битной версии Wine и переходим в нее.
rm -fr "${BUILD_DIR:?}/wine-64"
mkdir "${BUILD_DIR:?}/wine-64"
cd "${BUILD_DIR:?}/wine-64"

# Конфигурируем 64 битную версию Wine.
"${SOURCE_DIR:?}/wine/configure" \
    --prefix="${INSTALL_DIR:?}" \
    --libdir="${INSTALL_DIR:?}/lib64" \
    --x-libraries=/usr/lib64 \
    --with-system-dllpath=/usr/i686-w64-mingw32 \
    --enable-win64 \
    ${BUILD_OPTIONS[@]}

# Собираем Wine и задействуем все ядра процессора.
make -j$(nproc)

# Устанавливаем флаги сборки 32 битной версии Wine.
export CPPFLAGS="${BUILD_CFLAGS_32:?}"
export CFLAGS="${BUILD_CFLAGS_32:?}"
export CXXFLAGS="${BUILD_CFLAGS_32:?}"

# Создаем директорию сборки 32 битной версии Wine и переходим в нее.
rm -fr "${BUILD_DIR:?}/wine-32"
mkdir "${BUILD_DIR:?}/wine-32"
cd "${BUILD_DIR:?}/wine-32"

# Конфигурируем 32 битную версию Wine.
"${SOURCE_DIR:?}/wine/configure" \
    --prefix="${INSTALL_DIR:?}" \
    --libdir="${INSTALL_DIR:?}/lib" \
    --x-libraries=/usr/lib \
    --with-system-dllpath=/usr/x86_64-w64-mingw32 \
    --with-wine64="${BUILD_DIR:?}/wine-64" \
    ${BUILD_OPTIONS[@]}

# Собираем Wine и задействуем все ядра процессора.
make -j$(nproc)

# Удаляем директорию установки Wine и создаем ее.
rm -fr "${INSTALL_DIR:?}"
mkdir -p "${INSTALL_DIR:?}"

# Устанавливаем 32 битную версию Wine.
cd "${BUILD_DIR:?}/wine-32"
make -j$(nproc) prefix="${INSTALL_DIR:?}" \
    libdir="${INSTALL_DIR:?}/lib" \
    dlldir="${INSTALL_DIR:?}/lib/wine" install

# Устанавливаем 64 битную версию Wine.
cd "${BUILD_DIR:?}/wine-64"
make -j$(nproc) prefix="${INSTALL_DIR:?}" \
    libdir="${INSTALL_DIR:?}/lib64" \
    dlldir="${INSTALL_DIR:?}/lib64/wine" install

# Удаляем директории сборки.
rm -fr "${BUILD_DIR:?}/wine-32"
rm -fr "${BUILD_DIR:?}/wine-64"
rm -fr "${BUILD_DIR:?}"

Поздравляю, вы успешно собрали Wine. Это будет наша отправная точка для продвижения вперед.

Запустим наш Wine и проведем первоначальную настройку. Для первичной настройки и установки Battle.net нам нужен будет XWayland т.к. не все приложения работают нормально в Wine Wayland. Например, приложения использующие Chromium Embedded Framework (сокращено CEF) не отображают окно т.к. используют многопоточный рендеринг. Так же все плавающие окна не правильно отображаются в Wine Wayland. Но это не проблема для игр т.к. они запускаются в полноэкранном режиме и рисуют все сами. Поэтому мы будем изначально устанавливать и запускать Battle.net через XWayland, а саму игру Overwatch 2 уже напрямую.


Префикс в терминологии Wine это директория где наш Wine будет хранить файлы виртуальной ОС — Windows. Для безопасности у нас может быть множество изолированных от друг-друга префиксов, с разной версией Windows, разными библиотеками, программами и т.д.
# Путь к директории куда был установлен наш Wine.
export WINE_DIR="${HOME:?}/wine"
# Директория где будет храниться наш префикс и куда установим Battle.net с игрой Overwatch 2.
export GAME_DIR="${HOME:?}/Games/overwatch"
export WINEPREFIX="${GAME_DIR:?}"
# Будем хранить кэш `dxvk` и `vkd3d` в директории нашего префикс.
export DXVK_STATE_CACHE_PATH="${GAME_DIR:?}"
export VKD3D_SHADER_CACHE_PATH="${GAME_DIR:?}"
# Путь к файлу настроек `dxvk`
export DXVK_CONFIG_FILE="${GAME_DIR:?}/dxvk.conf"
# Отключаем логирование в dxvk и vkd3d-proton.
export DXVK_LOG_LEVEL=none
export VKD3D_DEBUG=none
export VKD3D_SHADER_DEBUG=none

# Укажем, что это будет 64 битный префикс
export WINEARCH=win64
# Включим Fsync
export WINEFSYNC=1
# Укажем путь к JSON файлам нашего драйвера для загрузки vulkan. Не обязательно указывать, но в некоторых системах бывает полезно игнорировать, какие-то драйвера, например для встроенной видеокарты и использовать дискретную.
export VK_DRIVER_FILES="/usr/share/vulkan/icd.d/radeon_icd.i686.json:/usr/share/vulkan/icd.d/radeon_icd.x86_64.json"
export VK_ICD_FILENAMES="/usr/share/vulkan/icd.d/radeon_icd.i686.json:/usr/share/vulkan/icd.d/radeon_icd.x86_64.json"

Файл ${GAME_DIR:?}/dxvk.conf хранит в себе настройки dxvk — библиотеки реализующей API Direct X 9 — 11, который нужен программам и играм. Этот файл можно создать пустым, или прописать в него необходимые настройки. Расшифровку всех параметров dxvk вы можете найти по ссылке: dxvk.conf

Инициализируем наш префикс. Wine создаст необходимые директории и скопирует необходимые для работы файлы.

mkdir -p "${GAME_DIR:?}"
"${WINE_DIR:?}/bin/wineboot" -i

Следующим нашим шагом необходимо скопировать или установить с помощью winеtricks необходимые шрифты в директорию drive_c/windows/Fonts нашего префикса. Самый простой способ просто скопировать содержимое директории windows/Fonts с вашей установленной Windows системы, но если у вас нет установленной Windows, то это не проблема. Тогда вы можете скачать proton-ge-custom и скопировать шрифты из директории files/share/fonts. Это значительно проще и быстрее чем воспользоваться winetricks.

Для работы игр и для поддержки Direct X 9 — 11, нам необходимо скачать и установить dxvk, а для Direct X 12 — vkd3d-proton. Если у вас видеокарта Nvidia, то дополнительно вам необходимо скачать и установить dxvk-nvapi. Для видеокарт AMD нет необходимости ставить dxvk-nvapi.

Установим dxvk, vkd3d-proton, dxvk-nvapi в наш префикс.

# Скачаем dxvk, vkd3d-proton, dxvk-nvapi.
wget https://github.com/doitsujin/dxvk/releases/download/v2.3/dxvk-2.3.tar.gz
wget https://github.com/HansKristian-Work/vkd3d-proton/releases/download/v2.11.1/vkd3d-proton-2.11.1.tar.zst
wget https://github.com/jp7677/dxvk-nvapi/releases/download/v0.6.4/dxvk-nvapi-v0.6.4.tar.gz
# Распакуем dxvk, vkd3d-proton, dxvk-nvapi.
tar -xf dxvk-2.3.tar.gz
tar -xf vkd3d-proton-2.11.1.tar.zst
mkdir dxvk-nvapi-v0.6.4
tar -xf dxvk-nvapi-v0.6.4.tar.gz -C dxvk-nvapi-v0.6.4
# Установим dxvk.
cp -vf dxvk-2.3/x64/*.dll "${WINEPREFIX:?}/drive_c/windows/system32/"
cp -vf dxvk-2.3/x32/*.dll "${WINEPREFIX:?}/drive_c/windows/syswow64/"
# Установим vkd3d-proton.
cp -vf vkd3d-proton-2.11.1/x64/*.dll "${WINEPREFIX:?}/drive_c/windows/system32/"
cp -vf vkd3d-proton-2.11.1/x86/*.dll "${WINEPREFIX:?}/drive_c/windows/syswow64/"
# Установим dxvk-nvapi.
cp -vf dxvk-nvapi-v0.6.4/x64/*.dll "${WINEPREFIX:?}/drive_c/windows/system32/"
cp -vf dxvk-nvapi-v0.6.4/x32/*.dll "${WINEPREFIX:?}/drive_c/windows/syswow64/"

Следующим шагом нам необходим настроить наш префикс. Для этого запустим программу winecfg поставляемую вместе с Wine.

"${WINE_DIR:?}/bin/wine" winecfg

После запуска winecfg, устанавливаем версия Windows: Windows 10. Жмем Применить.

vhncpeltbflykichc6ip3uxb5pq.png

rsm5kstsrfu8va23rk7eluswv8e.png

Переходим на вкладку Библиотеки. Вводим dxgi в поле Новое замещение для библиотеки и жмем добавить. Повторяем операцию и добавляем остальные библиотеки Direct X:

d3d9
d3d10core
d3d11
d3d12

Eсли у вас видеокарта Nvidia, и вы ранее установили dxvk-nvapi, вам так же необходимо добавить замещение библиотек:

nvapi
nvapi64

Не забываем нажать Применить. При следующем запуске наш Wine будет использовать эти библиотеки.

Так как многие приложения используют библиотеки Microsoft Visual C++ Redistributable, то скачаем их с сайта Майкрософт и установим.

wget https://aka.ms/vs/17/release/vc_redist.x64.exe
wget https://aka.ms/vs/17/release/vc_redist.x86.exe
"${WINE_DIR:?}/bin/wine" vc_redist.x64.exe
"${WINE_DIR:?}/bin/wine" vc_redist.x86.exe

Добавим в реестр Windows запись, что наш Wine поддерживает Wayland драйвер. По умолчанию Wine будет запускаться в режиме X11. Так же включаем поддержку не ускоренного указателя, который удобно использовать в шутерах.

"${WINE_DIR:?}/bin/wine" reg.exe add HKCU\\Software\\Wine\\Drivers /v Graphics /d x11,wayland
"${WINE_DIR:?}/bin/wine" reg.exe add HKCU\\Software\\Wine\\Wayland\ Driver /v unaccelerated_pointer /t REG_DWORD /d 1

Проверить внесенные изменения в реестр вы можете запустив regedit.

"${WINE_DIR:?}/bin/wine" regedit

Скачаем Battle.net и установим.

"${WINE_DIR:?}/bin/wine" Battle.net-Setup.exe

После установки, запускаем Battle.net командой:

"${WINE_DIR:?}/bin/wine" "C:/Program Files (x86)/Battle.net/Battle.net.exe" --exec="launch Pro" > /dev/null 2>&1

Далее в Battle.net устанавливаем Overwatch 2. Закрываем Battle.net.

Чтобы игра запустилась в Native Wayland необходимо сбросить переменную DISPLAY, это можно сделать с помощью команды unset DISPLAY или export DISPLAY="". Если нам необходимо запустить Battle.net для обновления игры, то добавляем # перед unset DISPLAY, и удаляем # перед соответствующей строкой запуска в скрипте ниже. chrt -rr 1 запускает игру с приоритетом реального времени, это необходимо для снижения инпут лага в играх, что критично в шутерах для лучшей стрельбы. Например, Proton сам меняет приоритет с помощью патча кода Wine, но мне не нравится такое решение. Чтобы понять запустилась ли игра в Wayland или XWayland достаточно посмотреть на курсор. В Wine поддержка Wayland частично ограниченная, и курсор при запуске будет стандартный (у меня он черного цвета), а в XWayland будет курсор установленный вашим Desktop Environment, например Breeze_Snow.

Создадим скрипт для запуска Overwatch 2.

#!/usr/bin/bash

# Путь к директории куда был установлен наш Wine.
export WINE_DIR="${HOME:?}/wine"
# Директория где храниться наш префикс и куда установлен Battle.net с игрой Overwatch 2.
export GAME_DIR="${HOME:?}/Games/overwatch"
export WINEPREFIX="${GAME_DIR:?}"
# Будем хранить кэш `dxvk` и `vkd3d` в директории нашего префикс.
export DXVK_STATE_CACHE_PATH="${GAME_DIR:?}"
export VKD3D_SHADER_CACHE_PATH="${GAME_DIR:?}"
# Путь к файлу настроек `dxvk`
export DXVK_CONFIG_FILE="${GAME_DIR:?}/dxvk.conf"
# Отключаем логирование в dxvk и vkd3d-proton.
export DXVK_LOG_LEVEL=none
export VKD3D_DEBUG=none
export VKD3D_SHADER_DEBUG=none

# Укажем, что это будет 64 битный префикс.
export WINEARCH=win64
# Включим Fsync.
export WINEFSYNC=1
# Укажем путь к JSON файлам нашего драйвера для загрузки vulkan. Не обязательно указывать, но в некоторых системах например бывает полезно игнорировать, какие-то драйвера, например для встроенной видеокарты и использовать дискретную.
export VK_DRIVER_FILES="/usr/share/vulkan/icd.d/radeon_icd.i686.json:/usr/share/vulkan/icd.d/radeon_icd.x86_64.json"
export VK_ICD_FILENAMES="/usr/share/vulkan/icd.d/radeon_icd.i686.json:/usr/share/vulkan/icd.d/radeon_icd.x86_64.json"

unset DISPLAY

#"${WINE_DIR}/bin/wine64" "C:/Program Files (x86)/Battle.net/Battle.net.exe" --exec="launch Pro" > /dev/null 2>&1
chrt -rr 1 "${WINE_DIR}/bin/wine64" "C:/Program Files (x86)/Overwatch/_retail_/Overwatch.exe" > /dev/null 2>&1

# После закрытия игры завершаем Wine Server, и убиваем все процессы с расширением .exe
"${WINE_DIR}/bin/wineserver" -k > /dev/null 2>&1
pkill -9 .exe > /dev/null 2>&1

hlaskansbvaahrb4my7rtntek_m.jpeg

После несложных операций, мы научились собирать Wine, делать первоначальную настройку, запускать приложения и игры. Теперь наш Wine работает напрямую с Wayland и имеет производительность сравнимую с Proton. Так же для особо любознательных, мною был подготовлен бонус, вместо Fsync вы патчей можете использовать более производительные патчи NtSync, но нужно еще собрать ядро Linux. Все необходимые патчи вы можете найти в директории wine-wayland/ntsync. А в следующей же части, мы продолжим наш путь, изучим как работает Proton и запустим игры Steam. До встречи в следующей части.

b5pjofdoxth14ro-rjsrn7sbmiy.png

© Habrahabr.ru