· kaynak Hacker News – Front Page (native)
Statik olarak WebAssembly'e yeniden derlenen PS2 oyunları tarayıcıda tam hızda çalışıyor
Bir Hacker News projesi, PlayStation 2 oyunlarını önceden WebAssembly'e ve bir WebGPU donanım yeniden uygulamasına derliyor; Gran Turismo 4 ve God of War II, emülatör olmadan Chrome'da tam hızda çalışıyor.
Hacker News'te ortaya çıkan ps2-web-recomp adlı proje, PlayStation 2 oyunlarını, emülatör olmadan Chrome'da tam hızda çalışan bağımsız web sayfalarına dönüştürüyor. Araç zinciri, konsolun CPU'sunu runtime sırasında yorumlamak yerine, bir oyunun Emotion Engine makine kodunu önceden C++'a çeviriyor, bunu WebAssembly'e derliyor ve WebGPU üzerinden render yapan PS2 işletim sistemi ile donanımının bir yeniden uygulamasına bağlıyor. Aynı yöntemi kullanan daha önceki bir PSP projesinin kardeşi olan araç, hiçbir oyun verisi içermiyor: kendi oyununuzun disk imajını sağlıyorsunuz ve deponun betikleri sayfayı yerel olarak derliyor.
İki oyun, oyuna özgü kod yok
Projenin GitHub deposuna göre bu şekilde çalışan ilk oyun, sistemdeki en zorlayıcı oyunlardan biri olarak seçilen Gran Turismo 4'tü: her iki vector unit'e de bel bağlıyor, tekrar oynatmaları ve ehliyet sınavları için kesin kayan nokta davranışına dayanıyor ve render edilmiş görüntüleri palet olarak kullanmak üzere geri okuyor. Açılış filminden menülere ve yarışlara kadar başlangıçtan itibaren müzik ve ses efektleriyle oynanıyor ve tarayıcıda tutulan bir hafıza kartına kaydediyor. Bir PAL yarışı, bir dizüstü bilgisayarın entegre GPU'sunda PS2'nin çözünürlüğünün iki katında saniyede tam 50 kareyle çalışıyor.
God of War II ise yalnızca genel değişikliklerle bir sayfaya derlendi. Savaş sahnelerine ulaştı ve yoğun dövüşlerde yerel çözünürlükte 60 fps, entegre GPU'nun darboğaz haline geldiği çift çözünürlükte 48 ile 60 fps arasında tutuyor. Buraya ulaşmak, yarış oyununun hiç tetiklemediği iki hatayı ortaya çıkardı: 16 KiB'lik bir birimin son talimatındaki bir dallanmanın gecikme yuvasından, onun ardından değil, oradan devam etmesine yol açan bir yeniden derleyici hatası ve clip bayraklarını bu oyunun microcode'u için bir talimat geç görünmesine neden olan vector unit zamanlaması. Giriş/çıkış işlemcisindeki uygulanmamış bir donanım sayacı da oyunu sessiz bırakmıştı.
Yeniden derleme nasıl çalışıyor
Temel araç olan eerecomp, çalıştırılabilir dosyanın kontrol akışını izler ve guest kodun 16 KiB'lik birimleri halinde C++ üretir. Çıktı, R5900 CPU'sunun tuhaflıklarını korur — 128 bitlik register'lar ve çoklu ortam talimatları, dallanma gecikme yuvaları ve sonsuz ya da denormal değerleri olmayan, IEEE'den farklı yuvarlayan bir kayan nokta birimi. Birimler arasındaki atlamalar tail call olur, bir thread geçişi host stack'i geri sarar ve guest adresinde devam eder; böylece üretilen kodun thread başına yığına ihtiyacı kalmaz.
PS2 çekirdeğinin ana CPU tarafı yüksek seviye emülasyonla karşılanır: thread'ler, semaforlar, DMA ve dikey boşluk kesme işleyicileri, alarmlar ve I/O işlemcisine giden SIF kanalı. I/O işlemcisi, ses, disk akışı, kontrolcü ve hafıza kartları için oyunun kendi IRX sürücülerini bir R3000 yorumlayıcısında çalıştırır; IOP çekirdeği ve kütüphaneleri ise C++ ile yeniden uygulanmıştır. Disk, HTTP Range istekleri üzerinden akıtılır; böylece baştan yalnızca çalıştırılabilir dosya indirilir.
Vector unit'ler ve Graphics Synthesizer
3D işlerin çoğu, vector unit 1'e yüklenen microprogram'lar olarak gelir; bu birim onları bit düzeyinde doğru PS2 kayan noktasıyla ve MAC, durum ve clip bayrakları için modellenmiş boru hattı gecikmeleriyle çalıştırır, çünkü oyunlar kodlarını bu gecikmelere göre zamanlar. Bir test çalışması sırasında görülen microprogram'lar önceden SIMD C++'a derlenir; yeni görülenler birkaç milisaniyede anında bir WebAssembly modülüne çevrilir.
Graphics Synthesizer'ın 4 MB'lık video belleği, GPU'da kendi doğal swizzled düzenlerinde tutulur; WebGPU compute shader'ları üçgenleri kutulara ayırır ve onları GS'nin kendi doku, palet, alpha blending, derinlik ve hedef alpha testi kurallarıyla rasterize eder. Her şey GS belleğinin içinde kaldığından, bir dokuya render eden veya bir framebuffer'ı palet olarak yeniden yorumlayan efektler gerçek donanımdaki gibi davranır. İç çözünürlük 1x'ten 3x'e kadar ölçeklenir ve bir yazılım rasterizer'ı, GPU çıktısının karşılaştırıldığı referans olarak kalır.
Performans çalışması tarayıcı tarafındaydı
İlk yarışın yazılım rasterizer ve bir VU1 yorumlayıcısıyla yerel olarak saniyede 3 karede çalıştığı bildiriliyor; WebGPU renderer ve derlenmiş microprogram'lar bunu kabaca 70'e çıkardı. Kalan kazanımlar tarayıcıya özgü ayarlamalardan geldi. İlk GPU renderer'ı kare başına yaklaşık 650 compute dispatch çıkarıyordu; doku yüklemelerini onlara bağlı olmayan üçgenlerden önce yapmak bunu yaklaşık 80'e indirdi. Gran Turismo 4 her karede aynı 3 MB dokuyu yüklüyor ve son yüklemelerin 16 MB'lık GPU tarafı önbelleği, kare başına veriyi yaklaşık yüzde 60 azalttı. Kare başına ayrışan kurulum yüklerini düzeltmek ve her karenin verisini tek parça halinde yazmak, 3x çözünürlüğü 23 fps'ten 48-50'ye taşıdı; emülasyonu bir worker'a taşımak ve clamped setTimeout çağrıları yerine bir MessageChannel üzerinden yield etmek ise yarışları sabit 50'de tuttu.
Neden önemli
Statik yeniden derleme, konsol oyunlarına herhangi bir eski ikili dosya gibi davranır: bir kez çevir, sonra yapıtı WebAssembly ve WebGPU'nun çalıştığı her yerde çalıştır — burada sıradan bir tarayıcı sekmesi. God of War II port'u, iki temel hata bulunduktan sonra yalnızca genel düzeltmelere ihtiyaç duydu; bu da yöntemin tek bir elle ayarlanmış oyunun ötesine genelleştiğini düşündürüyor. Yazı ayrıca WebGPU performansı üzerine daha ayrıntılı kamuya açık vaka çalışmalarından biri — toplu işlem azaltma, yükleme önbelleğe alma, shader divergence ve worker zamanlaması — yalnızca emülasyona değil, her zorlu web uygulamasına uygulanabilecek dersler.
- #webassembly
- #webgpu
- #emulation
- #playstation-2
- #static-recompilation