Playstation2の初期のゲームには入力遅延があったという話
PS3の話を書いていてふと思い出した話です。
PS2の初期のゲームには入力遅延があったというのは割と有名な話で、当時インタビュー記事とかでも複数の人が話をしていました。もちろん、当時はゲームエンジンもインハウスなのが普通だったので、構造によっては遅延が発生しないものもあったでしょうし、完成前に遅延の事実に気付いて修正できたところもあったとは思うんですが、どのゲームがどうだったかというのは、今では闇の中です。
入力遅延といっても約1フレームだったのでオリジナルのゲームでは特に気にされることもなかったはずですが、問題はアーケードゲームからの移植作で、当時話題になったのも基本的にはすべてアーケードからの移植でした。
ところが、遅延の存在は話題になっていたのですが、何故遅延が発生していたのかという話については、自分の知る限りでは全く表に出てこなかったです。今回はその辺の話を書こうと思っています。
まずは、かなり大雑把な予備知識から。
ゲームの処理は基本的にVSyncを時間の基準として動きます。現代的なシステムだと、flipすると自動的にVSyncまで待ってくれます。大抵の場合VSyncは約1/60秒ごとに来るので、ゲームは1/60秒ごとに処理を行います(VSyncを2回待つ2INTもあったけど、略)。VSyncの後にVBlank期間というのがあって、大昔(SFC以前)のキャラクタジェネレータの時代にはこの期間にいろいろとやらねばならないことがあったのですが、PS以降のビットマップのフレームバッファの時代ではバッファの交換くらいしかすることがないので、フレームの先頭は必然的にVSyncの直後ということになります。
フレームの最初ではいろいろとやることがありますが、そのうちの1つが入力のバッファリングです。パッドの入力やキーボードの入力を取得して、バッファに入れておきます。フレーム内では、このバッファの内容を使います。
バッファリングしておく理由は様々ですが、一番は処理の前後でパッドの内容が違うと、いらんバグを誘発するというのが大きいです。処理落ちが発生するような状況になると特に顕著です。もっとも、自分がゲームを作り始めた頃には既にセオリーとなっていたので、何か他の理由が大きいのかもしれません。現在使われているゲームエンジンでも、基本的にはこの形です。
そんなわけで、フレームの先頭、すなわちVSyncの直後にフレームで使うパッドの入力が取得されているわけです。
ところが、PS2の場合、OS側でも同じようなことが実行されていました。理由はよくわからないですが、PS2はPSから引き継いだ遅いシリアル通信をパッドに使っていて、かつパッドの機能がPSの時代よりも増えてしまったからだと推測されます。低レベルなところでパッドの取得にかなりの時間がかかるということです。
PS2のCPUはMIPS IVのEEとMIPS IIのIOPという非対称マルチコアで、入力に関してはIOPが管理していました。問題はその更新タイミングで、VSyncの「ちょっと」後でした。だいたい、VSyncの200マイクロ秒くらい後だったと記憶しています。(接続するパッドの数でも違ってたと思うが、略)
結果として、フレームの先頭で入力をバッファリングしていた場合、ほぼ1フレームの入力遅延が発生していたわけです。
これはほとんど表沙汰になってなかったので、入力遅延に気付いた所はそれぞれが苦労して原因を探していました。(実際、自分がいたメーカー以外でも起きていたのを知っています)
そんなわけで、原因がわかったらバッファリングするタイミングを後ろにずらすことになるわけですが、200マイクロ秒というのは意外と微妙な時間で、ちょうどいい処理がなかなか見つかりませんでした。そのため無駄も多かったです。実際、単純なウエイトをかけていたチームがあったのを知っています。
ところが、PS2も中期になるとちょうどうまい具合の処理が見つかりました。(もちろん、自分の周囲では、ということですが)
長くなってきたので記事をわけたくなりましたが、そのまま書きます(汗)
PS2のGPU(GS)の特徴として、当時としては圧倒的な48GBytes/秒(諸説あり)という莫大な転送レートと、当時としても少なすぎた4MByteというVRAM容量があります。4MByteというと現代でいえば1,024x1,024のRGBAテクスチャ1枚分です。これでいろいろとやりくりしていたのです。
通常、フレームバッファは同じものを2つ持っていて(ダブルバッファ)、flipの時に描画用と表示用を交換するというのが普通で、PS2でも最初の頃は大抵のチームではこの方法を採用していたと思います。ところが、小さなVRAMを最大限活用するために描画用と表示用をそれぞれシングルで持っていてVBlank期間に描画用から表示用に転送するというのが主流になっていきました。
なんでそうなったの?というのは、その説明だけで長文になってしまうので避けますが、少なくとも表示用ではアルファは必要ないので、それだけでもVRAMの節約になるというのは解るかと思います。PS2は転送も速いので成立できたとも言えます。レートが異常に遅いPS3だったら同じことはできませんでした。実際にはアルファだけじゃなくてもっと攻めた節約をしていましたが。
そんなわけで、VSyncの直後に描画バッファ→表示バッファの転送という作業が入ったので、フレームの先頭は「VSyncのちょっと後」になりました。PS2も中期以降に開発に参加した人は入力遅延の問題を特に気にしなくても良くなったのです。
こうして入力遅延が上手に回避されていくようになりました。いろんな人がいろんな知恵を絞っていたのですね。