ś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.





sobota, 27 sierpnia 2016

FreeCAD: TechDraw (rzuty 2D), elementy bazowe PartDesign

Ta krótka notka ma za zadanie przedstawić kilka ciekawych zmian i nowych funkcji programu FreeCAD.

Elementy bazowe i ciało (Body) modułu PartDesign

Wcześniej każdy nowy szkic musiał być umieszczony na geometrii istniejącej części. Stawało się to często bardzo niewygodne, wystarczy sobie wyobrazić dodanie segmentu do wałka przez obrót - na jednej z podstaw trzeba było wyciągnąć najpierw jakiś prostopadłościan, a dopiero potem narysować na nim docelowy szkic.

Niedawno został wprowadzony kontener Body, który likwiduje ten problem. Szkice mogą być umieszczane na dowolnych powierzchniach płaskich, a operacje z nich powstałe oddziałują na całą geometrię wewnątrz jednego kontenera.


Zadanie jeszcze bardziej ułatwiają elementy bazowe: płaszczyzny, osie i punkty. Więcej o budowie nowego PartDesign można przeczytaj na forum tutaj.

TechDraw - rzuty 2D

Wcześniej mieliśmy oficjalny moduł dokumentacji 2D tworzonej z modeli 3D nazwany Drawing i nieoficjalny Drawing Dimensioning. Pierwszy z nich nie umożliwiał łatwego wymiarowania ani tworzenia przekrojów, drugi dawał sobie radę z wymiarami, ale nie były one aktualizowane po zmianie kształtu części.

Nowy TechDraw rozwiązuje wszystkie te problemy. Wątek na forum.

 
Jak można zauważyć na powyższym zrzucie, jeszcze nie wszystko da się ustawić tak aby odpowiadało to zasadom rysunku technicznego. No, ale minęło dopiero półtora miesiąca od pierwszego wydania TechDraw - jest on cały czas dopracowywany. 

Nowości w module MES (FEM)

Moduł wspomagający obliczenia metodą elementów skończonych jest tak szybko i tak szeroko rozbudowywany, że trudno byłoby streści wszystkie zmiany.

Na pewno warto zwrócić uwagę na symulacje termomechaniczne opisane w tym wątku na forum.
 

Inną ciekawostką jest zaawansowany postprocesing z wykorzystaniem VTK - więcej tutaj.

Instalacja freecad-daily na Ubuntu

Opisane powyżej nowości (prócz postprocesingu VTK,który wymaga kompilacji ze źródeł) można znaleźć w prekompilowanych paczkach freecad-daily. 

Tematy warte uwagi w przyszłości

"Robust References" Redux - rozwiązanie problemu topologicznego nazewnictwa. Do tej pory było tak, że program do utrzymywania referencji numerował geometrię danego typu nie przejmując się jej położeniem czy znaczeniem. Przykład: płytka z kilkoma otworami, w jednym z nich robimy fazę. Potem zmniejszamy liczbę otworów, co się dzieje z fazą? Pojawia się na jednej z pozostałych krawędzi części, niekoniecznie w którymś z otworów. Ten problem powinien już niedługo być przeszłością.


update on FreeCAD + OpenFOAM fluid dynamic computation - pierwsze kroki w kierunku integracji solwera OpenFOAM i symulacji przepływu płynów.

piątek, 10 czerwca 2016

Otwarta fotogrametria: openMVG i openMVS

Fotogrametria pozwala na przeniesienie kształtu rzeczywistego do wirtualnego środowiska 3D za sprawą zaledwie kilku zdjęć i mocy obliczeniowej, której jest pod dostatkiem w w twoim czy moim domu. Specjalnie odniosłem się do naszych komputerów, bo chcę pokazać, że nie trzeba wykorzystywać oprogramowania w stylu Autodesk 123D Catch i obliczeń "w chmurze".

Nie potrzebny będzie też żaden drogi sprzęt, ani nawet wysokiej klasy aparat cyfrowy. Zdjęcia na potrzeby wygenerowania modelu rękawiczki, który powinieneś widzieć poniżej, zostały zrobione tym antykiem. Kosztował on mnie  450 zł jakieś 12 lat temu. Telefon, który masz w kieszeni, pewnie robi znacznie lepsze zdjęcia.


Uwaga: poniższy tekst nie jest tutorialem, a raczej luźnymi notatkami, które mają tak samo służyć mi za kilka miesięcy lub lat, jak i innym czytelnikom. Może przestawiać nieoptymalny przebieg procesu.

Jeśli nie widzisz obracalnego modelu 3D (bo przeglądarka nie obsługuje WebGL lub serwis ShareMy3D padł), to poniżej znajduje się statyczny zrzut ekranu.


Oprogramowanie - kompilacja

Opis bazuje na założeniu, że użytkownik korzysta z jakiejś współczesnej dystrybucji Linuksa. W moim przypadku jest to Kubuntu 16.04 64-bit.

Utworzyłem jeden katalog dla całego oprogramowania do fotogrametrii. W tym katalogu skompilowałem dwa pakiety:
  1. openMVG, zgodnie z oficjalnymi instrukcjami,
  2. openMVS, zgodnie z oficjalnymi instrukcjami,
  3. dodatkowo zainstalowałem MeshLab - wygodną przeglądarkę i edytor chmur punktów oraz modeli 3D, znajdziesz go w swoim ulubionym menedżerze pakietów.
O ile openMVG nie powinno sprawić problemów, to openMVS może zrobić niemiłą niespodziankę.
Pierwszym problemem w Ubuntu 16.04 jest niestabilna wersja (3.3-beta) pakietu libeigen-dev. Obszedłem ten problem pożyczając od Debiana paczkę deb w wersji 3.2.
Drugim okazało się vcglib i błąd związany z przestrzenią nazw:
error: ‘isinf’ was not declared in this scope
error: ‘isnan’ was not declared in this scope
Wystarczyło odszukać plik vcglib/vcg/math/base.h i zamienić
template int IsNAN(T t) { return isnan(t) || isinf(t); }
na
template int IsNAN(T t) { return std::isnan(t) || std::isinf(t); }

Ogólny model postępowania

Pakiet oprogramowania openMVG będzie karmiony wykonanymi przez nas zdjęciami, próbując znaleźć położenie punktów składających się na obiekt i stworzyć rzadką chmurę. Etap ten opisany jest w dokumentacji SfM: Structure from Motion. Chmura punktów będzie podstawą do pracy openMVS, które kolejno zagęści chmurę, utworzy siatkę wielokątów i w końcu oteksturuje ją.

Na początek potrzebujemy kilku zdjęć przy dobrym oświetleniu, bez użycia flesza, najlepiej z niezbyt dużym przesunięciem między nimi.

Sprytnym trikiem jest podłożenie pod obiekt czegoś o charakterystycznym wzorze, jak gazeta, czy (w moim przypadku) mapa. To znacznie poprawia skuteczność algorytmów SfM. Problematyczne okazują się za to obiekty o znacznych powierzchniach w jednolitym kolorze, odbijających światło lub częściowo przezroczystych.

Proces krok po kroku

Zakładam że openMVS i openMVG zostały skompilowane w wspólnym katalogu:
ls -l
razem 28
drwxrwxr-x  7 adi adi 4096 cze 10 20:49 ceres_build
drwxrwxr-x 12 adi adi 4096 cze  9 18:54 ceres-solver
drwxrwxr-x  6 adi adi 4096 cze  9 19:44 openMVG
drwxrwxr-x 12 adi adi 4096 cze  9 21:07 openMVG_Build
drwxrwxr-x  8 adi adi 4096 cze  9 18:42 openMVS
drwxrwxr-x  8 adi adi 4096 cze  9 19:41 openMVS_build
drwxrwxr-x  9 adi adi 4096 cze  9 18:34 vcglib
Wykonałem 10 zdjęć rękawiczki położonej na mapie Polski i wrzuciłem je (niezbyt elegancko) do katalogu openMVG_Build/software/SfM/lapka_in

Kolejny krok to uruchomienie skryptu Pythona:
python SfM_GlobalPipeline.py lapka_in lapka_global_out
I już tutaj pojawił się pierwszy zgrzyt. OpenMVG poinformowało o braku modelu aparatu cyfrowego w bazie:
Warning & Error messages:
IM000217" model "Photosmart M407" doesn't exist in the database
Wystarczyło otworzyć plik openMVG/src/openMVG/exif/sensor_width_database/sensor_width_camera_database.txt i dodać odpowiednią pozycję.

W konsoli powinniśmy zobaczyć m.in.:
Structure estimation took (s): 1.861.
#landmark found: 12600
...Generating SfM_Report.html
Found a sfm_data scene with:
 #views: 10
 #poses: 10
 #intrinsics: 1
 #tracks: 12600
10 zdjęć i 10 rozpoznanych pozycji, to dobry znak. Otwierając chmurę punktów lapka_global_out/reconstruction_global/colorized.ply w programie MeshLab zobaczymy coś takiego:

To chmura rzadka, stąd nie przypomina jeszcze naszego fotografowanego obiektu, ale warto zwrócić uwagę na zielone punkty. To pozycje aparatu podczas robienia zdjęć.

Musimy wyeksportować wyniki z openMVG do formatu przyjaznego openMVS (dokumentacja):
../../Linux-x86_64-RELEASE/openMVG_main_openMVG2openMVS -i \
lapka_global_out/reconstruction_global/sfm_data.bin -d lapka_out -o lapka_out/scene.mvs
Teraz, już używając openMVS, zagęszczamy chmurę:
../../../openMVS_build/bin/DensifyPointCloud lapka_out/scene.mvs
Tak wygląda chmura gęsta otwarta w MeshLab (plik lapka_out/scene_dense.ply):

Pozostało tylko wygenerować siatkę wielokątów i oteksturować ją:
../../../openMVS_build/bin/ReconstructMesh lapka_out/scene_dense.mvs
../../../openMVS_build/bin/TextureMesh lapka_out/scene_dense_mesh.mvs
Efekt końcowy powinien być taki jak na początku wpisu.

 

Q&A:

Q: Ile trwa cały proces?
A: Kilkanaście sekund do kilku minut, dla zadań jak w powyższym opisie.

Q: Nie masz ładniejszego przykładu niż zmiętoszona rękawiczka?
A: 30-letni misiu może być?

 
Q: W czym jest to lepsze od popularnych rozwiązań "w chmurze"?
A: Nie ma ograniczenia co do liczby zdjęć (np. Autodesk 123D Catch pozwala tylko na 70 zdjęć), nie trzeba czekać na wysłanie zdjęć na serwer, łatwiej zdiagnozować problem w razie niepowodzenie i nie trzeba zaptaszać żadnych cyrografów podczas instalacji. Bardziej zaawansowani użytkownicy mogą usprawnić proces pisząc skrypty czy przyjazne GUI (pewnie już ktoś to zrobił).

Q: Czy opisywane oprogramowanie działa na Windows?
A: Oczywiście, że tak.

Q: Coś jeszcze?
A: Obracaj modelem rękawiczki lub misia od patrząc na niego od wewnątrz a ulegniesz złudzeniu optycznemu.