środa, 15 sierpnia 2018

DXVK - wysokowydajna implementacja Direct3D11 dla Linuksa

AKTUALIZACJA 22.08.2018: Valve wprowadziło nową wersję Steam Play umożliwiającą na uruchamianie gier z Windows na Linuksie. To rozwiązanie również wykorzystuje DXVK.

Jeszcze do niedawna granie w gry z Windows na Linuksie nie było najlepszym przeżyciem, szczególnie jeśli gry te korzystały z DirectX11.
DXVK, czyli implementacja Direct3D11 na Vulkanie całkowicie zmienia postać rzeczy.

Na zachętę zrzut ekranu z Dying Light (2015), na wysokich detalach i Radeonie 580 (synchronizacja pionowa 75Hz):


Wiem, że Dying Light ta ma natywny port na Linuksa. Kierowałem się tym kupując grę. Niestety dla wielu ( w tym dla mnie) on nie działa, wysypując się przy starcie. "Szczęśliwcy", którym gra startuje narzekają znowu na marną wydajność.

Drugi zrzut ekranu pochodzi z nieco nowszej gry, czyli z Preya (2017) z grafiką ustawioną na "Ultra".


W Preyu nieco dziwnie zachowuje się zarządzanie energią mojej karty graficznej, musiałem ręcznie ustawić profil wysoki zamiast auto. Inaczej zegary były obcinane nawet o 50%, co dawało 30-40 kl./s zamiast 60-75.

Czym właściwie jest DXVK?

Readme opisuje je jako:
Bazująca na Vulkanie warstwa tłumacząca dla Direct3D10/11, która pozwala na uruchamianie aplikacji 3D na Linuksie przy użyciu Wine.
Na chwilę obecną implementacja Direct3D11 jest ukryta w plikach DLL: d3d11 i dxgi, które zastępują ich odpowiedniki z Wine. Hipotetycznie DXVK nie jest ograniczone tylko do Linuksa (bo to tylko DLL odwołujące się do Vulkana!), jednak jego użycie pod Windows (DXVK on Windows #326) nie było szerzej testowane i nie jest celem projektu.

Dlaczego DXVK jest (dużo) wydajniejsze od czystego Wine?

Standardowa implementacja Direct3D11 w Wine tłumaczy wywołania Direct3D na OpenGL. Ten ostatni został zaprojektowany, gdy rendering grafiki działał całkiem inaczej niż dzisiaj, uniemożliwia dokładną kontrolę nad sprzętem, ma problemy z wielowątkowością, a duża część walidacji stanu i kontroli błędów przeprowadzana jest w czasie pracy aplikacji. Do tego trzeba było sobie radzić z bardzo rozbieżnymi implementacjami. Podejście wydajne na AMD mogło być powolne na Nvidii lub odwrotnie.

Vulkan działając na znacznie niższym poziomie niż OpenGL daje dokładną kontrolę nad sprzętem. Zyskują na tym twórcy gier, ale jeszcze większe korzyści mają programiści emulatorów (patrz Dolphin) czy warstw translacji takich jak DXVK.

Uruchamianie gier z użyciem DXVK

Po pierwsze potrzebujemy karty graficznej obsługującej Vulkan. Lista znajduje się tutaj. W praktyce każdy Radeon od serii 7700 (GCN) i GeForce od serii 600 (Kepler) obsługuje API Vulkan, czyli mówimy to o kartach wydanych nie wcześniej niż w 2012 roku.

Drugim etapem jest zainstalowanie bibliotek (o ile nie jest on zainstalowany domyślnie). Tutaj bezczelnie przekopiuję informacje z wiki DXVK:

Ubuntu:
sudo apt-get install libvulkan1 libvulkan1:i386
Arch:  
sudo pacman -S vulkan-icd-loader lib32-vulkan-icd-loader

Dodatkowo w przypadku AMD (otwarty sterownik):
Ubuntu:  
sudo apt-get install mesa-vulkan-drivers mesa-vulkan-drivers:i386
Arch:
sudo pacman -S vulkan-radeon lib32-vulkan-radeon

Warto też zajrzeć na wiki by sprawdzić wersje sterownika, które są wymagane przez DXVK.

Najprostszym sposobem sprawdzenia czy Vulkan działa jest uruchomienie dema:
vulkan-smoketest

Kolejny etap to zainstalowanie Wine, Steam i DXVK. Zamiast robić to ręcznie, polecam wykorzystać Lutris i wszystko "wyklikać". Lutris umożliwia łatwe zarządzanie instalacjami i konfiguracjami Wine jak i gier natywnych. Instrukcje instalacji dla najpopularniejszych dystrybucji znajdują się tutaj.

Po uruchomieniu Lutris wybieramy Manage runners i instalujemy Wine Steam praz Wine w wersji nie niższej niż 3.10 (jak na zrzucie poniżej).



Następnym etapem jest zainstalowanie konfiguracji dla wybranej gry. Strona Lutris ma wyszukiwarkę dla najpopularniejszych gier. W przypadku Preya wystarczy wybrać instalację Steam w/ DXVK version.


Co jeśli danej gry nie ma w bibliotece konfiguracji? Można ją dodać ręcznie. Wybieramy z menu Lutris Game-Add i wypełniamy kolejne karty:
  •  Game info: 
  1. Name - nazwa gry (np. Prey)
  2. Runner - Wine Steam
  • Game options:
  1.  Application ID - identyfikator z Steama, najłatwiej go znaleźć otwierając stronę Sklepu Steam dla danej gry i odczytując go z paska adresu. Dla Preya jest to 480490
  2. Jeśli chcemy skopiować pliki gry z innej instalacji Steam to przydatne może być zaznaczenie Do not launch game, only open Steam, wtedy zostanie tylko otwarta biblioteka Steam


  • Runner options:
  1. Wine version - np. 3.10-86_64 
  2. Zaznaczamy Enable DXVK
  3. DXVK version - np. 0.65, nazwy wydanych wersji można znaleźć tutaj.


Dodatkowo jeśli chcemy mieć wyświetlaną wersję sterownika i liczbę klatek na sekundę w rogu ekranu, to w karcie System options dodajemy zmienną środowiskową DXVK_HUD 1.

Bonus

Na koniec dwa zrzuty ekranu z Metro 2033 Redux (ustawienie grafiki "Very High"): jeden z wersji natywnej, z drugi z windowsowej z DXVK. Największa różnica? Spójrz na kółko, w wersji natywnej jest kanciaste. Linuksowy port nie obsługuje tesselacji a pomimo tego nie ma wyraźnie wyższej wydajności.