まず考えること
利益を得られるシナリオ
- CPU重点なグラフィクス処理がある。[Schott and Bishop 2016Schott, M. and Bishop, L. M. 2016. High-performance, Low-Overhead Rendering with OpenGL and Vulkan. Game Developers Conference. https://developer.download.nvidia.com/gameworks/events/GDC2016/mschott_lbishop_gl_vulkan.pdf.]
- CommandBufferとQueueによる処理負荷の分散が可能。
- プラットフォームの最大性能を引き出したい。[Schott and Bishop 2016Schott, M. and Bishop, L. M. 2016. High-performance, Low-Overhead Rendering with OpenGL and Vulkan. Game Developers Conference. https://developer.download.nvidia.com/gameworks/events/GDC2016/mschott_lbishop_gl_vulkan.pdf.]
- アロケーションやリソースの直接管理が可能。
- パフォーマンスを予測したり、hitchingをなくしたりしたい。[Schott and Bishop 2016Schott, M. and Bishop, L. M. 2016. High-performance, Low-Overhead Rendering with OpenGL and Vulkan. Game Developers Conference. https://developer.download.nvidia.com/gameworks/events/GDC2016/mschott_lbishop_gl_vulkan.pdf.]
- ステートを事前計算するため、実行時にシェーダのリコンパイルやステートのキャッシュ更新が発生しない。
利益を得られにくいシナリオ
- 互換性重点。[Schott and Bishop 2016Schott, M. and Bishop, L. M. 2016. High-performance, Low-Overhead Rendering with OpenGL and Vulkan. Game Developers Conference. https://developer.download.nvidia.com/gameworks/events/GDC2016/mschott_lbishop_gl_vulkan.pdf.]
- GPU偏重。[Schott and Bishop 2016Schott, M. and Bishop, L. M. 2016. High-performance, Low-Overhead Rendering with OpenGL and Vulkan. Game Developers Conference. https://developer.download.nvidia.com/gameworks/events/GDC2016/mschott_lbishop_gl_vulkan.pdf.]
- グラフィクス以外でCPU重点。[Schott and Bishop 2016Schott, M. and Bishop, L. M. 2016. High-performance, Low-Overhead Rendering with OpenGL and Vulkan. Game Developers Conference. https://developer.download.nvidia.com/gameworks/events/GDC2016/mschott_lbishop_gl_vulkan.pdf.]
- マルチスレッド化できそうにない。[Schott and Bishop 2016Schott, M. and Bishop, L. M. 2016. High-performance, Low-Overhead Rendering with OpenGL and Vulkan. Game Developers Conference. https://developer.download.nvidia.com/gameworks/events/GDC2016/mschott_lbishop_gl_vulkan.pdf.]
概要
マルチスレッディング
- オブジェクトはすべてのスレッドから見えている/アクセスできる。[Olson 2016Olson, T. 2016. Vulkan 101. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/1-Vulkan_101.pdf.]
- ほとんどの処理は外で同期を取るようになっている。[Olson 2016Olson, T. 2016. Vulkan 101. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/1-Vulkan_101.pdf.]
- 安全でない並列処理はアプリケーションの責任で無害化すること。
- 同じCommandBufferへの記録するとき。
- 同じキューへのsubmitするとき。
- 安全でない並列処理はアプリケーションの責任で無害化すること。
- 割り当て/生成は内部で同期を取っているので、多分ブロックされる。[Olson 2016Olson, T. 2016. Vulkan 101. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/1-Vulkan_101.pdf.]
- スレッド毎プールアロケータを使えば、このコストを押さえ込むことができる。
コマンドバッファ
- コマンドの種類[Worcester 2016Worcester, M. 2016. Command Buffers and Pipelines. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/2-Command_buffers_and_pipelines.pdf.]
- 転送
- (タイリング以外は)そのままコピーする。
- グラフィクス
- コンピュート
- 同期
- 転送
- コマンドバッファには、PRIMARYとSECONDARYがある。[Worcester 2016Worcester, M. 2016. Command Buffers and Pipelines. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/2-Command_buffers_and_pipelines.pdf.]
- SECONDARYはPRIMARYに渡して実行される。
パイプライン
- 動的ステート[Worcester 2016Worcester, M. 2016. Command Buffers and Pipelines. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/2-Command_buffers_and_pipelines.pdf.]
- ビューポート
- シザー
- ライン幅
- 深度バイアス
- ブレンド定数色
- 深度範囲
- ステンシル
- 比較
- 書き込み
- 参照値
パイプラインレイアウト
- 生成時に、シェーダの”関数シグネチャ”を教えてやる必要がある。[Arntzen 2016Arntzen, H.-K. 2016. Using SPIR-V in practice with SPIRV-Cross. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/4-Using-spir-v-with-spirv-cross.pdf.]
レンダパス
- render passは依存関係のある処理をグループ化する。[Garrard 2016Garrard, A. 2016. Vulkan Subpasses or The Frame Buffer is Lava. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/6-Vulkan-subpasses.pdf.]
- ひとつのレンダパスで出力されるイメージはすべて同じサイズ。
- レンダパスはいくつかのサブパスで構成される。[Garrard 2016Garrard, A. 2016. Vulkan Subpasses or The Frame Buffer is Lava. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/6-Vulkan-subpasses.pdf.]
- 例: Deferred Shadingというレンダパスには、Geom, Light, Fragの3つのサブパスがある。
- subpassはアタッチメント(出力バッファ)へのアクセスを記述する。
- subpass間には依存関係を定義できる。
- 各レンダパスのインスタンスは単一のコマンドバッファに格納しなければならない。[Garrard 2016Garrard, A. 2016. Vulkan Subpasses or The Frame Buffer is Lava. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/6-Vulkan-subpasses.pdf.]
- コマンドバッファに複数のレンダパスを流すことができる。[Garrard 2016Garrard, A. 2016. Vulkan Subpasses or The Frame Buffer is Lava. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/6-Vulkan-subpasses.pdf.]
- 例: シャドウマップのレンダパスと環境マップのレンダパスを同じコマンドバッファに入れることもできる。
- But it must be the same outputs each time you submit [Garrard 2016Garrard, A. 2016. Vulkan Subpasses or The Frame Buffer is Lava. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/6-Vulkan-subpasses.pdf.]
- A specific render pass instance has fixed vkFrameBuffers!
- 異なるレンダパスは独立した出力を持たなければならない。[Garrard 2016Garrard, A. 2016. Vulkan Subpasses or The Frame Buffer is Lava. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/6-Vulkan-subpasses.pdf.]
- 異なるレンダターゲットを持つ同じコマンドバッファは再利用できない。[Garrard 2016Garrard, A. 2016. Vulkan Subpasses or The Frame Buffer is Lava. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/6-Vulkan-subpasses.pdf.]
- 例: ダブルバッファリングやストリーミング
- プライマリからレンダパスの情報を継承させるフラグがある。[Garrard 2016Garrard, A. 2016. Vulkan Subpasses or The Frame Buffer is Lava. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/6-Vulkan-subpasses.pdf.]
- セカンダリコマンドバッファではレンダパスを開始できない。
- レンダパスでないことならセカンダリにも入れられる。
- コンピュートシェーダはレンダパスの外で実行できる。
同期プリミティブ
- パイプラインバリア[Hector 2016Hector, T. 2016. Keeping your GPU fed without getting bitten. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/7-Keeping-your-GPU-fed.pdf.]
- パイプラインステージを指定する。
- メモリバリア。
- ある1点で。
- イベント[Hector 2016Hector, T. 2016. Keeping your GPU fed without getting bitten. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/7-Keeping-your-GPU-fed.pdf.]
- パイプラインバリアと同じデータを渡す。
- ある範囲で。
- CPUで状態を受け取ることができる。
- ウェイトなし。
- メモリバリアなし。
- サブパスの依存関係[Hector 2016Hector, T. 2016. Keeping your GPU fed without getting bitten. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/7-Keeping-your-GPU-fed.pdf.]
- パイプラインバリアと似たようなデータを渡す。
- 2つサブパスの間に注目する。
- メモリバリア
- アタッチメントは暗黙的に。
- その他のリソースは明示的に指定する。
- ピクセルのリージョンを単位とすることもできる。
- 自分自身を待つこともできる。
- サブパスのパイプラインバリアみたいなもの。
- 後段のステージを待つことはできない。
- 外部の処理を待つこともできる。
- セマフォ[Hector 2016Hector, T. 2016. Keeping your GPU fed without getting bitten. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/7-Keeping-your-GPU-fed.pdf.]
- キュー同士を同期するときに使われる。
- まずまずの粗い粒度。
- サブミッションバッチごと。
- 暗黙的なメモリ保証。
- フェンス[Hector 2016Hector, T. 2016. Keeping your GPU fed without getting bitten. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/7-Keeping-your-GPU-fed.pdf.]
- キューとCPUを同期するときに使う。
- 非常に粗い粒度。
- サブミットコマンドごと。
- 暗黙的なメモリ保証。
メモリバリア
- グローバルメモリバリア[Hector 2016Hector, T. 2016. Keeping your GPU fed without getting bitten. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/7-Keeping-your-GPU-fed.pdf.]
- アクセスステージを定義する。
- 大量のリソースをトランジションするときに使う。
- ひとつひとつに使うより安い。
- ユーザが以前のアクセスを定義する。
- バッファバリア[Hector 2016Hector, T. 2016. Keeping your GPU fed without getting bitten. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/7-Keeping-your-GPU-fed.pdf.]
- 単一のバッファ範囲。
- アクセスステージを定義する。
- キューの所有権を定義する。
- ユーザが以前のアクセスを定義する。
- イメージバリア[Hector 2016Hector, T. 2016. Keeping your GPU fed without getting bitten. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/7-Keeping-your-GPU-fed.pdf.]
- 単一のイメージサブリソース範囲。
- アクセスステージを定義する。
- キューの所有権を定義する。
- イメージレイアウトを定義する。
- ユーザが以前のアクセスを定義する。
- 以前のレイアウトも定義する。
実践
CommandBuffer
- CommandBufferのsubmitもタダではないので、メインスレッドに集めてからまとめてsubmitしたほうがパフォーマンス的には良くなるかも。[Schott and Bishop 2016Schott, M. and Bishop, L. M. 2016. High-performance, Low-Overhead Rendering with OpenGL and Vulkan. Game Developers Conference. https://developer.download.nvidia.com/gameworks/events/GDC2016/mschott_lbishop_gl_vulkan.pdf.]
- セカンダリコマンドバッファは並列化を見越してスレッドのぶんだけ生成する。[Garrard 2016Garrard, A. 2016. Vulkan Subpasses or The Frame Buffer is Lava. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/6-Vulkan-subpasses.pdf.]
- 別々のCommandBufferに並列に記録する場合、それぞれのCommandBufferは異なるCommandPool由来のものを使う。[Daniell 2015Daniell, P. 2015. Vulkan on NVIDIA GPUs. ACM SIGGRAPH. https://www.youtube.com/watch?v=NqensKmmRfE.]
DescriptorSet
- 別々のDescriptorSetに並列に更新する場合、それぞれのDescriptorSetは異なるDescriptorPool由来のものを使う。[Daniell 2015Daniell, P. 2015. Vulkan on NVIDIA GPUs. ACM SIGGRAPH. https://www.youtube.com/watch?v=NqensKmmRfE.]
Render pass
- レンダパスの制御はプライマリバッファでのみ行うことができる。[Garrard 2016Garrard, A. 2016. Vulkan Subpasses or The Frame Buffer is Lava. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/6-Vulkan-subpasses.pdf.]
CommandPool
- CommandPoolはフレーム数xスレッド数をひとまとまりとして、バッファリング分を余分に用意する。CommandPoolは割り当てたCommandBufferが使い終わったあとならリセットして再利用できる。[Schott and Bishop 2016Schott, M. and Bishop, L. M. 2016. High-performance, Low-Overhead Rendering with OpenGL and Vulkan. Game Developers Conference. https://developer.download.nvidia.com/gameworks/events/GDC2016/mschott_lbishop_gl_vulkan.pdf.]
DescriptorPool
- DescriptorSetの動的な生成が必要なら、スレッドローカルなDescriptorPoolを用意したほうが良い。[Schott and Bishop 2016Schott, M. and Bishop, L. M. 2016. High-performance, Low-Overhead Rendering with OpenGL and Vulkan. Game Developers Conference. https://developer.download.nvidia.com/gameworks/events/GDC2016/mschott_lbishop_gl_vulkan.pdf.]
- 寿命に応じて管理すれば、削除処理がスムーズに行うことができる。[Schott and Bishop 2016Schott, M. and Bishop, L. M. 2016. High-performance, Low-Overhead Rendering with OpenGL and Vulkan. Game Developers Conference. https://developer.download.nvidia.com/gameworks/events/GDC2016/mschott_lbishop_gl_vulkan.pdf.]
同期プリミティブ
- 点で同期するときは、パイプラインバリアを使う。[Hector 2016Hector, T. 2016. Keeping your GPU fed without getting bitten. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/7-Keeping-your-GPU-fed.pdf.]
- 2つの処理の間に別の処理が挟まる可能性があるときは、イベントを使う。[Hector 2016Hector, T. 2016. Keeping your GPU fed without getting bitten. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/7-Keeping-your-GPU-fed.pdf.]
- CPU/GPU同期には、イベントを使う。[Hector 2016Hector, T. 2016. Keeping your GPU fed without getting bitten. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/7-Keeping-your-GPU-fed.pdf.]
- 正しい量を正確に指定する。[Hector 2016Hector, T. 2016. Keeping your GPU fed without getting bitten. Moving to Vulkan : How to make your 3D graphics more explicit. https://www.khronos.org/assets/uploads/developers/library/2016-vulkan-devday-uk/7-Keeping-your-GPU-fed.pdf.]
- 多すぎると、GPUが飢えてしまう。
- 間違えれば、GPUからしっぺ返しを食らう。
用語
- 引っ掛かり(hitching):
- 極めて短時間にのみFPSが低下する現象。
- マシンの性能不足ではなく、プログラムによる一時的な処理負荷の増加が原因。
- カクつき(stutter)とともにプレイヤーに不快感を与える一因となる。
- 参考:https://forest.watch.impress.co.jp/docs/news/1049869.html