展示HN:PS2游戏静态重新编译为WebAssembly
在浏览器中运行PlayStation 2游戏,无需模拟器。游戏的Emotion Engine机器代码被提前转换为C++,编译为WebAssembly,并链接到PS2操作系统和硬件的重实现,后者使用WebGPU进行绘制。观看完整录制(1:24)这是psp-web-recomp的兄弟项目,遵循相同的方法。通过这种方式引入的第一个游戏是《Gran Turismo 4》,选择它是因为它是系统上最具挑战性的游戏之一:它依赖于两个向量单元,对重播和执照测试的精确浮点行为,以及以调色板形式读取渲染图像的图形技巧。它从启动播放到开场动画、菜单和比赛,配有音乐和音效,并保存到保存在浏览器中的内存卡。比赛以全速运行,该PAL版的速度为每秒50帧,在笔记本的集成GPU上的分辨率是PS2的两倍,这就是上述视频录制的方式。《God of War II》同样通过相同的脚本跟进。它不需要特定于游戏的代码,但发现了两个《Gran Turismo 4》从未触发的bug,一个在重新编译器中,另一个在向量单元定时中,还有一些PS2输入/输出处理器缺失的部分。现在它从菜单播放到过场动画再到战斗,在Chrome浏览器中,在重型战斗下以PS2的分辨率保持每秒60帧。在双重分辨率下,它以48到60帧运行,受限于笔记本的集成GPU。这里不包含任何游戏数据。您带来您拥有的游戏的光盘映像,这个库中的脚本会将其转换为您机器上的网页。它是如何工作的重新编译。eerecomp读取游戏的可执行文件,跟随其控制流查找函数,并以16 KiB的客代码单位发出C++代码。输出保留了R5900的怪癖:128位寄存器和在其上运行的多媒体指令,分支延迟槽,PS2的浮点单元,没有无穷大或非标准数值,并且与IEEE有不同的舍入方式,还有用作协处理器的向量单元0。单元之间的跳转变成尾调用,线程切换展开主机堆栈并在客地址处恢复,因此生成的代码不需要每个客线程一个堆栈。一个小型PS2内核。操作系统的EE部分由高级仿真来回应:线程、信号量、DMA控制器和垂直空白的中断处理程序、警报,以及将主CPU与I/O处理器连接的SIF通道。I/O处理器在其R3000 CPU的解释器上运行游戏自己开发的IRX模块、声音驱动程序、光盘流媒体代码以及随光盘提供的控制器和内存卡驱动程序,而IOP内核及其调用的库在C++中重新实现。光盘通过HTTP Range请求读取,仅在前者下载可执行文件。向量单元。大多数PS2游戏的3D工作发生在游戏上传到向量单元1的微程序中。它们以精确的PS2浮点数学和MAC的管道延迟运行,状态和剪辑标志建模,因为游戏围绕它们调度代码。在测试运行期间看到的微程序提前编译成SIMD C++;任何首次遇到的程序都将现场转化为WebAssembly模块,这需要每个程序几毫秒。图形。图形合成器的4MB视频内存驻留在GPU中,以其原生螺旋布局存放,绘制通过WebGPU计算着色器完成:三角形被分箱到瓦片中,并根据GS的纹理、调色板、透明度混合、深度和目标透明度测试的规则进行光栅化。由于所有内容保留在GS内存中,因此渲染到纹理或重新解释帧缓冲区为调色板的效果工作方式与控制台相同。内部分辨率可以是本机的1、2或3倍。同样的GS软件光栅化器仍然存在,作为与GPU输出进行比较的参考。线程。仿真运行在一个工作线程上,向量单元1有一个自己的工作线程,它以与控制台上并行相同的方式运行,GS命令通过环形缓冲区传递给拥有WebGPU设备的页面线程。声音和电影。SPU2以其48个ADPCM音轨、ADSR包络和流式DMA游戏使用的音乐进行了重新实现,输出通过共享内存传输到AudioWorklet。电影由PS2的MPEG-2解码器IPU的实现解码。从让其快速的经验教训开始,第一次比赛在本地仅以3帧每秒运行,使用的是软件光栅化器和向量单元1的解释器。将GS移到WebGPU计算着色器并编译向量单元程序将其速度提升到本机的约70,剩余的大部分工作是关于浏览器的时间消耗,而不是仿真。GPU渲染器的第一个版本每帧提交约650个计算调度,因为每次纹理上传和调色板加载都会分割其周围的三角形批处理。提升
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡