イベント
[CEDEC 2014]セガのリードプログラマーが語った,PS4ローンチタイトル「龍が如く 維新!」ができるまで。いかにして60fps化を成し遂げたのか
CEDEC 2014では,PS4版の開発にあたったリードプログラマーが,開発時に遭遇した問題点をわりと生々しく語ってくれるセッションが行われた。ちょっと込み入った話もあるが,その概要を紹介してみたい。
「龍が如く 維新!」公式サイト
4Gamer.net「CEDEC 2014」記事一覧
64ビットWindows版を開発したうえで
PS4に移植された「龍が如く 維新!」
CEDEC 2014の3日目に行われた「世代間マルチプラットフォーム平行開発」と題したセッションは,「龍が如く 維新!」の開発経験を例に複数のプラットフォーム,とくにPS3版とPS4版の並行開発を行う際の問題点を明らかにしていこうという内容だった。スピーカーを務めたのは,同作のPS4版でリードプログラマーを担当した,セガの厚 孝氏である。
厚 孝氏 株式会社セガ第一CS研究開発部 リードプログラマー |
「龍が如く 維新!」開発時に設定された実現目標。可変フレームレートはシリーズ初の試みだったという |
前述の目標を掲げてPS3版の開発を進めていた2013年春になって,PS4版の話が舞い込んだという。つまり,PS4の国内ローンチの約1年前から,PS4版開発の検討がスタートしたということだろう。
その当時,厚氏を含む開発チームでは,PS4本体は2013年中に国内発売されると思っていたそうだ。当初は「龍が如く 維新!」をPS4のローンチタイトルにするという縛りはなかったため,PS4本体の発売から2〜4か月後くらいにPS4版をリリースできればいいなという感じだったと,厚氏は振り返っている。
PS4版の話が舞い込んだのは2013年春のこと。当初はローンチタイトルという縛りがなく,PS4本体の発売に少し遅れてもいいから,というリクエストだったそうだ |
以上の経緯があり,厚氏はPS4版に着手したわけだが,その当時,PS4版の開発にあたっての不安点と有利な点をリストアップしたのが下のスライドだ。
不安点に挙げられているとおり,2013年春にはPS3版の開発が佳境に入っていて,「1日にリビジョンが100以上も更新されるほど」(厚氏)頻繁にコードやアセットが改定されていたという。そんな中で,PS4版の開発も手掛けるのは確かに大変そうだ。
一方,厚氏は有利な点として,開発用のWindows版が存在していたことを挙げている。このWindows版は,もちろん商用ではなく,開発のために作られている内部バージョンである。PS4のグラフィックスAPIなどはWindowsと半ば互換性があると言われているので,Windows版の存在はPS4版開発の助けになるのだろう。
また,龍が如くシリーズのソースコードはほとんどが内製だったため,サードパーティのPS4対応を待つ必要がないという点も,PS4版の開発における有利な点と考えたとのことだった。
PS4版の開発にあたってリストアップされた不安点と有利な点。ちなみにコンソール向けタイトルにおいて,内部的に開発用のWindows版が作られるのは珍しいことではない |
スライドにある「エンディアン」というのは,簡単に説明するならばデータの並び順のことだ。下位→上位の順に並ぶのがリトルエンディアン,上位→下位の順に並ぶのをビッグエンディアンと呼び,CPUによってリトルだったりビッグだったりする。厳密には,PowerPCやARMはリトルエンディアンとビッグエンディアンを切り替えられるマルチエンディアンのCPUだが,PS3に採用されているPowerPCコア(PPE)はビッグエンディアン固定である。
そして,x86プロセッサを採用するPS4はリトルエンディアンという違いがあるため,つまりはデータの並び順に互換性がないのだ。だが,その点はリトルエンディアンであるWindows版が存在していることで,すでにエンディアンの違いは吸収できる仕組みがあり,とくに心配はなかったという。
PS4は64ビットOSなのでポインタも64ビットだったことも,大きな不安点だったそうだ。そこで厚氏は,まず64ビットのWindowsに移植を行い,そこからPS4にインプリメントするという手順を取った。最大の懸念である64ビット化を済ませれば,あとはすんなりいくだろうというわけだ。
ここから,64ビットWindows版の開発にあたって厚氏が遭遇した具体的なトラブルが紹介された。大きく分けると,ソースコードの移植に関わる問題とグラフィックスに関わる問題があったそうだが,先に説明があったのは前者である。
厚氏によると,やはり32ビットポインタから64ビットポインタに,そのままでは切り替えられないコードが多数見つかったという。ポインタの扱いがしっかりしていれば,32ビットから64ビットへは問題なく移行できるはずだが,「龍が如く 維新!」ではコンパイラを通すソースコードが7500本以上もあるとのことで,乱暴なコードが混ざっているのは仕方がないところだろう。
32ビットポインタから64ビットポインタへ。ソースの上の行はポインタを32ビット整数に(キャスト)して整数を加算し,あらためてポインタに(キャスト)するというダメな書き方。だが,厚氏のチェックの結果,ソース内にこうした記述がかなり見つかったという |
この問題は,コンパイラの警告レベルを上げて,しらみつぶしに修正をかけることで「95%は対処できた」(厚氏)が,それでも問題箇所は残ったという。
ちょっと面白かったので,厚氏が挙げた例を紹介しておこう。まず64ビットWindows上でも,64ビットアドレスの上位32ビットが,0のアドレスに作業領域が割り当てられることが多いという点がある。仮想メモリ空間の低位アドレスにユーザープログラムが割り当てられるためだが,そうなるとポインタを32ビットの符号なし整数として扱っている限り,エラーは生じない。つまり,潜在的なエラー(不正な状態)が顕在化しない問題が起きるのだ。
64ビットポインタの上位32ビットが0なら,ポインタを32ビットの符号なし整数として扱っていても問題が顕在化しない。そこで,メモリ確保時に上位アドレスを強制的に割り当てるフラグを渡すことで,エラーをあぶり出す作戦を取ったそうだ |
もう1つの例も,なるほどといった内容の話である。インデックスの初期値として32ビットすべてがオンになっている値(0xFFFFFFFF)が使われているが,これはほかの値をインデックスに代入せずに使われることはないはずのものだった。しかし,プログラムミス(つまりバグ)により,0xFFFFFFFFがインデックスとして使われてしまっている箇所があったそうだ。
これは32ビット環境でもバグではあるが,同環境では0xFFFFFFFFが-1と等価になる。つまり,配列の1つ前のアドレスを参照するので,エラーとして顕在化しなかったらしい(ただし,たまたま今回のケースでは顕在化していなかっただけで,顕在化する環境もあるはず)。
だが,64ビット環境ではとんでもないアドレスを参照する結果になり,エラーとして顕在化したこともあったという。
明白なバグだが,32ビット環境では顕在化していなかったものが,64ビット環境で顕在化することがあったという |
グラフィックスの面では,DirectX9からDirectX11への移行が焦点となる。DirectX11では,DirectX9のフィーチャーがかなり削られていたりもするので,その対応が必要になったようだ。
DirectX9からDirectX11への切り替えで生じた課題。DirectX11では,DirectX9世代のピクセルフォーマットの一部が削られている,ステート管理が違っている,シェーダーモデルが3.0になっているといった違いがあるが,一つ一つ対処していったと厚氏は説明していた |
たとえば,テクスチャ構文の違いについてはヘッダファイルを活用して,プリプロセッサで対応したとのこと。よくある対処法の1つだが効果的だろう。
シェーダーモデル3.0のtex2D関数は,シェーダーモデル5.0で使えなくなっているが,ヘッダファイルに互換性のあるマクロを定義し,プリプロセッサで対処したという |
以上の作業の末,64ビットWindows版のテストモードの起動に成功したのが2013年7月25日とのこと。ここからPS4への移植が本格的にスタートすることになる。
さまざまな苦労の末,2013年7月25日に64ビットWindows版のテストモードが起動。スライドのスクリーンショットでは普通に見えるが,厚氏によると,初めての起動時には絵が崩れていて,実際のものとはかなり違っていたそうだ |
PS4では描画速度が大幅に低下する!?
64ビット化に成功すれば,あとはスムーズに進むと思われていたが,現実は違っていたようだ。その理由として,厚氏が最初に挙げたのが,Windows版とPS4版のコンパイラの違いだった。Windows版の開発にはMicrosoftのVisual C++が使用されているが,PS4の開発環境のコンパイラはLP64である。これには,筆者もちょっと驚いた。
64ビット環境のCコンパイラにはlong型(長整数)が64ビットのLP64と,long型は32ビットでlong long型(長長整数)が64ビットのLLP64という2種類がある。そして,WindowsやLinuxなどのポピュラーな環境のコンパイラは,ほぼLLP64となっている。筆者の経験からすると,long型のビット長が32ビット環境と変わらないLLP64のほうが互換性が取りやすい。
なぜPS4のコンパイラはLP64なのか,その理由は分からない。ゲームプログラムでは符号なしlong型(unsigned long)にポインタを代入しているケースがありえるという想定のもと,それに対応できるLP64を採用したのかもしれない。そもそも,unsigned longにポインタを代入するようなコード自体がダメなのだが,いずれにせよ,PS4ではlong型などの組み込み型を使わないようにする対応が必要になったという。
PS4のコンパイラは,32ビット環境と互換性の問題が生じやすいと思われるLP64とのこと。これは初耳だった |
いくつかのマイナーな問題が生じたものの,先に64ビットWindows版にとりかかっていただけにPS4版の起動までに要した期間は短く,2013年8月6日にはPS4版のテストモード起動に成功。その画面を社内で公開したことで,ようやくPS4版移植のためのチームを結成することができたという。……つまり,PS4版は最初の起動までを,厚氏がたった1人で担当していたそうである。
2013年8月6日にPS4上でテストモードが初めて起動。これでようやく,厚氏はたった1人での作業から解放されたとのこと |
だが,さらなる問題が生じた。意外なことに,PS4版の描画がとてつもなく遅く,「30fpsにも達していなかった」(厚氏)。PS3に比べて,CPUやGPUが数十倍にもなっているはずのPS4なのにだ。
そこで,厚氏はパフォーマンス解析を実行し,PS4では描画コマンドの作成に多くの時間がかかっていることを突き止める。描画コマンドの作成にはフレームごとに実時間で26ms(マイクロ秒)を要し,描画にかかる時間の約8割が描画コマンドの作成で占められていたという。
パフォーマンス解析の結果,PS4では描画コマンドの作成が極めて遅いことが判明した |
PS3とPS4の同じシーンにおけるアナライザの比較。上がPS4,下がPS3,横軸は時間(単位はマイクロ秒)である。青い部分が描画コマンドの作成で,描画が開始されるまでの時間はPS4が圧倒的に速いが,そこからが極めて遅いことが分かる |
描画コマンドの作成が遅い理由は,「『龍が如く 維新!』がPS3に最適化されていたことにあった」(厚氏)。PS3はメモリが小さく,ドローコールはオーバーヘッドが比較的少ないという特徴がある。そのため,PS3版は細かいカリング(分割)を優先して,大量のドローコールを発行するようなコードになっていたという。しかし,PS4でこの手法を取るとオーバーヘッドが大きくなるので,まとめて描画したほうがはるかに速いというわけだ。
PS3に最適化され,大量のドローコールを発行するコードになっていたが,PS4では大きなボトルネックになってしまった |
そこで,厚氏はドローコールの削減を敢行する。たとえば,スキンモデルはPS3の定数サイズの制限を受けて細かい単位(32ボーン)で分割されていたが,PS4は「サイズの制限が事実上無い」(厚氏)ので,まとめて読み込ませるようにスキンモデルを再構成したそうだ。
結果的に多少の高速化は実現したものの,その向上率はわずか5%。「26msが25msになった程度」(厚氏)と,その効果は限定的だったという。
ドローコールを削減したものの,効果は5%に過ぎなかった |
さらに調査を進めていくと,PS4のSDK(ソフトウェアの開発キット)はAPIが重いことが分かった。「現在のSDKはアップデートされている」(厚氏)とのことだが,開発当時はまだPS4のSDKが安定していないこともあり,APIのオーバーヘッドが大きかったようだ。
幸い,PS4のSDKはソースコードが付属していたため,さっそくAPIの最適化にも着手したという。また,ちょうどこの頃,軽量版のAPIがリリースされたこともあり,APIの改善で30fpsをクリアすることに成功したとのことだ。
APIの最適化により,30fpsをクリア。ちなみにPS3版は30fpsである |
ところが,2013年9月9日にPS4版がローンチタイトルとなることが正式発表されると,開発チームには強い期待がかけられるようになる。そこで「何かPS3版と差別化しなくてはいけないという話」(厚氏)になり,描画速度に苦しんでいるという状況だったが,PS4版の60fps化が決定してしまったのである。なお,9月時点でのPS4版のフレームレートは40fps程度だったそうだ。
PS4版の描画速度に苦しんでいる最中に60fps化が決定 |
60fps化の決定により,抜本的な高速化に迫られたものの,一方ではPS3版も開発中であり,基本的な描画構造に手を入れるわけにはいかない。これはもちろん,基本的な部分を変更するとPS3版にも影響が及ぶためだ。
そこで,基本的な描画構造を変更せずに並列レンダリングを取り入れることにしたという。とくに不透明オブジェクトのレンダリングに時間がかかっていることが分かったため,そのレンダリングパスを重点的に並列化。その結果,2013年11月7日,ついに60fpsの動作に成功したそうだ。
Opaque(不透明サーフェス)のレンダリングにとくに時間がかかっていたため,重点的に並列化を行ったそうだ |
その結果,めでたく2013年11月7日に60fpsの動作を達成 |
今回のセッションでは描画の高速化なども詳細な解説があったほか,厚氏によると,取り上げ切れなかったテーマの資料は後日公開する予定があるとのこと。興味がある人は,CEDECの公式サイトなどをチェックしてみるといいだろう。
ちなみに60fps化は大成功だったようで,厚氏は「PS3版とPS4版を並べると,PS3が壊れているんじゃないかと思えるほど」の違いがあると強調していた。このセッションで明らかにされた苦労を念頭に置いて,PS4版「龍が如く 維新!」を楽しんでみてはいかがだろうか。
「龍が如く 維新!」は両機種版のコードベースが同じなので,PS4版ではメモリが大量に余ったそうだ。そこで,なんと2.5GBものメモリをファイルキャッシュにあてており,PS4版がサクサク動くのもそのためだとか |
「龍が如く 維新!」公式サイト
4Gamer.net「CEDEC 2014」記事一覧
キーワード
(C)SEGA
(C)SEGA