Emulator RISC-V w postaci modułu cieniującego piksele umożliwiającego uruchomienie Linuksa w VRChat

Opublikowano wyniki eksperymentu dotyczącego zorganizowania uruchomienia Linuksa w wirtualnej przestrzeni 3D wieloosobowej gry online VRChat, która umożliwia ładowanie modeli 3D z własnymi shaderami. Aby zrealizować wymyślony pomysł, stworzono emulator architektury RISC-V, wykonywany po stronie GPU w postaci modułu cieniującego piksel (fragment) (VRChat nie obsługuje shaderów obliczeniowych i UAV). Kod emulatora jest opublikowany na licencji MIT.

Emulator oparty jest na implementacji w języku C, do stworzenia której z kolei wykorzystano rozwinięcia minimalistycznego emulatora riscv-rust, opracowanego w języku Rust. Przygotowany kod C jest tłumaczony na moduł cieniujący piksele w HLSL, odpowiedni do załadowania do VRChat. Emulator zapewnia pełną obsługę architektury zestawu instrukcji rv32imasu, jednostki zarządzającej pamięcią SV32 oraz minimalnego zestawu urządzeń peryferyjnych (UART i timer). Przygotowane możliwości wystarczą do załadowania jądra Linuksa 5.13.5 oraz podstawowego środowiska wiersza poleceń BusyBox, z którym można wchodzić w interakcję bezpośrednio z wirtualnego świata VRChat.

Emulator RISC-V w postaci modułu cieniującego piksele umożliwiającego uruchomienie Linuksa w VRChat
Emulator RISC-V w postaci modułu cieniującego piksele umożliwiającego uruchomienie Linuksa w VRChat

Emulator zaimplementowany jest w shaderze w postaci własnej dynamicznej tekstury (Unity Custom RenderTexture), uzupełnionej o skrypty Udon dostarczone dla VRChat, służące do sterowania emulatorem podczas jego wykonywania. Zawartość pamięci RAM i stan procesora emulowanego systemu zapisywane są w postaci tekstury o wymiarach 2048x2048 pikseli. Emulowany procesor pracuje z częstotliwością 250 kHz. Oprócz Linuksa na emulatorze można także uruchomić Micropython.

Emulator RISC-V w postaci modułu cieniującego piksele umożliwiającego uruchomienie Linuksa w VRChat

Aby utworzyć trwałe miejsce do przechowywania danych z obsługą odczytu i zapisu, wystarczy użyć obiektu Camera powiązanego z prostokątnym obszarem wygenerowanym przez moduł cieniujący i skierować wynik renderowanej tekstury na wejście modułu cieniującego. W ten sposób każdy piksel zapisany podczas wykonywania modułu cieniującego może zostać odczytany podczas przetwarzania następnej klatki.

Podczas stosowania modułów cieniujących pikseli dla każdego piksela tekstury uruchamiana jest równolegle osobna instancja modułu cieniującego. Cecha ta znacznie komplikuje implementację i wymaga osobnej koordynacji stanu całego emulowanego systemu i porównania położenia przetworzonego piksela z zakodowanym w nim stanem procesora lub zawartością pamięci RAM emulowanego systemu (każdy piksel może zakodować 128 strzępy informacji). Kod modułu cieniującego wymaga uwzględnienia ogromnej liczby kontroli, aby uprościć implementację, w której wykorzystano preprocesor perl perlpp.



Źródło: opennet.ru

Dodaj komentarz