各社のVulkan推奨事項調査メモ
ひとまずWebGL1実装用のシェーダコンパイラが作成できたので次はVulkanを使ってGPUとの繋ぎこみをやっていく。ただ、Vulkanは各社共通のAPIといっても実装ごとにある種のクセがあり、どのVulkan機能を使うかという選択に影響してくる。
同じWebGLというかOpenGL ESのVulkan実装であるANGLEは比較的この辺を真面目に考察していて可能な限りVulkanにやさしい処理になる(= 人間がVulkanで直接書いたのと同じような処理になる)ように実装されている。C-WebGLでは逆にVulkanがレガシー機能として公開している部分を使うように(= 人間がOpenGL ESから移植したのと同じような処理になる)実装したいと考えている。
ターゲットGPU
- Arm Mali
- Qualcomm Adreno
- Imagination PowerVR
- MoltenVk (Apple GPU上のエミュレーション)
- Intel
- AMD Radeon
- NVIDIA GeForce, Tegra
RaspberryPi4のVideoCoreやVeriSilicon(旧Vivante)、GoogleのSwiftShaderのような実装は相当するドキュメンテーションが無いので調べようがない。
Arm Mali
ArmのMaliはUtgard(GLES2、統合シェーダ でない)、Midgard(Vulkan 1.0)、Bifrost(Vulkan 1.2)、Valhallの各世代があり、Midgard中盤以降の世代でVulkanが使用できる。
Best Practice GuideはGLESとVulkanで統合されていて、アーキテクチャガイドは別に用意されている。
-
https://developer.arm.com/solutions/graphics-and-gaming/developer-guides/learn-the-basics
- The Utgard shader core などのドキュメントが相当する
諸元、制約
- タイルサイズ: 16x16が基本 (小せぇ)
- ピクセルシェーダからDepthに書く等でEarlyZやFPK( Forward Pixel Kill - EarlyZの補完的な派生)が使われなくなる (T620以降)
-
VK_PIPELINE_STAGE_*
毎に処理キューが決まっている。FragmentとVertex+Computeの2つ。 - それぞれのキューも1つのみで、
SIMULTANEOUS_USE_BIT
はエミュレーションされる - descriptor setは密に配置すべき
- メモリ帯域を節約するため、頂点は strip 形式を使用すべき
- attributeやvaryingは可能な限り精度が低いものを使用すべき。精度変換は無料、varyingは常にメモリに書かれる。
- メモリへのwritebackを減らすためにRenderpassの活用を推奨
- (FIXME: Uniform, push constants?)
PowerVRだとrenderpassの概念が無いGLESでTBDRアーキテクチャを活用するためにフレームバッファreadを無料にしていた(pixel local storage)けど、同じような最適化はMaliに有るんだろうか。
Qualcomm Adreno
Sphinxで書いた感バリバリのドキュメントが公開されている。Adrenoは元々AMD(旧ATI)のモバイル向け描画コアをQualcommが買収して独自に開発を続けているもので、MaliやPowerVRのようなタイルベース描画と、通常のデスクトップGPUのようなimmediate描画の両方を処理できる。
諸元、制約
他のタイルベースGPU(MaliやPowerVR)と異なり、AdrenoのレンダリングはGMEMと呼ぶローカルメモリに対して行うとだけ決まっていて、実際のbinを行うのはドライバに裁量がある。 (QCOM_binning_control
拡張が存在するが、最近のドライバには無いように見える。)
マルチパスのdrawをGMEMのresolveなしで行えるかは判然としない。OpenGLには QCOM_tiled_rendering
を用意しているが、VulkanのRenderPassでできるのでそちらを使えば十分なんだろう。。
- FlexRenderは暗黙に発動 し、明示的に有効化はできない。
- Early-Z の補完として Low Resolution Z-pass(LRZ) がある。LRZはbinningで生成するメタデータを使用して行うので、タイルレンダリングでなければならない & Vulkanのsecondary command bufferでは発動しない。depth writeをする事でも無効になる。
- 書き出し時にUniversal Bandwidth Compression(UBWC) によりデータは暗黙に圧縮される。ただし UBWCは対応フォーマットの制約 がある。
- Vulkanのpush constantの有効性は A6x以降でないと得られない 。
- レンダリングステートの一部だけが異なるvulkan pipelineでは pipeline derivativesの使用を推奨する 。
- combined sample objectを使わないとパフォーマンスが数パーセント劣化する 。つまりサンプラオブジェクトにtextureを与える形だと遅いって事か。。
歴史
GPUの系譜としては BitBoysにあたる 。
Imagination PowerVR
歴史のあるGPUだけに全体的にドキュメントも良く書けているように思う。
諸元、制約
- タイルサイズ: 32x32 (MSAAで 等価サイズが32x16とか16x16になる ケースがある) 、 128bppまたは256bpp 。
- FIXME: Clear色に制約は無い。。?
- PowerVRはパラメーターバッファ(頂点処理後に Tilerがbinしたデータを溜める バッファ)の 存在を明示 している。パラメータバッファが溢れると、ドライバは自動的に描画をflushするのでパフォーマンスペナルティ以外の副作用はない。(例えばVideoCoreとかだと暗黙に失敗していたと思う)
- Secondary command bufferは有効 。
- Push constantはコマンドバッファ内に確保される 。また、UBOも確保されることがある。
- Derivative pipelines にパフォーマンス上のベネフィットは無い 。Adrenoと対称的。
歴史
公式の History of PowerVR にはDreamcastやPS Vitaは載ってるのに、非常に重要なDesign winであるiPhoneが載っていないのは示唆的な気もする。
PVRTC(テクスチャ圧縮)やTA(Tile Accelerator)のように、非プログラマブルパイプラインの頃から使用されている用語が現代でも活きている。
MoltenVk
MoltenVkはApple Metal上に構築されたVulkanサブセット実装で、サブセット状況を表現するためにVulkanの拡張 VK_KHR_portability_subset
が定義されている。
Metalは(PowerVRベースである)AppleのGPU以外にIntelやAMDのGPUもサポートしているが、仮にApple以外のGPUで動作していたとしても、それらがVulkanで使われたときのような機能性を公開しているわけではない。
MoltenVkとしてのランタイム制約はドキュメントの 末尾に纏められている が、特に VkAllocationCallbacks
によるメモリ割り当てのコールバックが使用できない点がある。
諸元、制約
- MoltenVkが使用できるかは謎だがMetal 2以降が使用できるA11以降のGPUは Pixel Local Storageが使用できる 。Feature set tables によると、これが使えるのはApple GPUだけで、Macではエミュレーションすら提供されていない。
歴史
AppleはGLES1の時代から自前のOpenGL ESスタックを持ち ドキュメントもある が既にドキュメントはarchive行きでメンテナンスされていない。OpenGL ESはDeprecateされていて、いつサブミッション不能になるか固唾を呑んで見守られている状況と言って良いだろう。
Intel
Intelは自社製のGPUを相当長い事使用しており、スマホ時代の到来までは非常に重要なシェアを占めていた。当然PCでは依然重要なGPUの一角となっている。一部のチップセットはPowerVRやMali、また過去にはAMD Radeonを採用したプラットフォームもあったが、あまりリッチなドキュメンテーションは提供していない。
Intelは基本的に Gen〜 で自社のGPUのアーキテクチャを表現していて、Vulkanに対応しているのは Gen9 および Gen11 、Xe(= Gen12)となる。
-
https://software.intel.com/content/www/us/en/develop/articles/intel-graphics-developers-guides.html
- Gen〜 ごとのドキュメンテーションへのリンク(Gen11まで)
-
https://software.intel.com/content/www/us/en/develop/documentation/graphics-xe-lp-api-developer-optimization-guide/top/performance-recommendations-for-intel-x-lp-graphics-processors.html
- XeLP(Gen12)の最適化ガイド
-
https://www.intel.co.jp/content/www/jp/ja/support/articles/000005524/graphics.html
- 製品と対応APIの一覧表
諸元、制約
- ハードウェアクリア値: (0,0,0,0) または (1,1,1,1) ただしこの記述は Gen12のドキュメントでは消えている 。
- Gen12で FP64サポートを廃止 している。GPGPUの傾向変化か。
- Gen11にはいくつかの重要なアーキテクチャ変更がある。
- PTBR(Position-only shading Tile Based Rendering)は、プロセサのL3キャッシュをPowerVRのパラメータバッファのように使って遅延シェーディングを行う。 使用できるプリミティブはTriangle-listとTriangle-stripのみ 。タイルサイズ等は指定できず、ドライバ任せになる点はAdrenoのものに近い。
- CPS(Coarse Pixel Shading)は、要するにDX12のTier1 VRSで、画面解像度よりも低いレートでのピクセルシェーダ起動を行うことができる。これは従来の縮小バッファの拡大表示 → チェッカーボードレンダリング の流れの延長線上にあるテクニックで、ジオメトリの解像度は低下しないため見た目が良い。
- Gen9ではL3キャッシュをスレッド間の共有データを保持するために使用していたが、Gen11では専用のバッファが追加されレイテンシが改善している。
歴史
↑ のドキュメントリストは Gen6(= 最初のプロセッサ統合グラフィックス) から始まっているが、このカウントはプログラマブルシェーダの導入以前からカウントされている。
- Gen1: i740。 http://www.vgamuseum.info/index.php/cards/item/195-intel-740 データシート 、 Intel740™ Graphics AcceleratorSoftware Developer’s Manual 。系譜としてはSegaのModel2等で名を馳せたロッキード・マーティン → Real3Dにあたる。
- Gen2: いわゆる Intel Extreme Graphics 。ここまでの世代にはシェーダーが無い。
- Gen3: GMA900 〜 GMA3100 等。ピクセルシェーダーはあるがバーテックスシェーダーは無くソフトウェア実装。
- Gen4: GMA Series4。バーテックスシェーダも搭載された(統合シェーダ)が Intel Graphics Media Accelerator Developer's Guide ではソフトウェア側を推奨している "However, CPU vertex processing may offer even greater performance enhancements on the latest Intel multi-core processors" 。このころからシェーダコアをEUと呼称。
- Gen5: いわゆる Intel HD Graphics 。 Intel Integrated Graphics Developer's Guide 。最後のいわゆるオンボードグラフィックス。
NVIDIA
... ドキュメントが無い。。いくつかのtechnoteがあるが、それらを纏めてドキュメントにして欲しいところなんだけど。。GameWorks等のNDA側はまだちゃんと調べきれていない(が、ここにリンクを並べるわけにもいかないし。。。)。
- https://developer.nvidia.com/vulkan-shader-resource-binding
- https://developer.nvidia.com/opengl-vulkan -- Desktop OpenGL側からpipline object等に相当するVulkan要素を使う
歴史
NVIDIAは過去にはGeForce ULPを使用したOpenGL ES2.0実装も提供していた。 ...が、残念ながら市場ではあまり支持されずNintendo Switchのような非常に大きなdesign winを獲得しているもののモバイルではあまり存在感がない。
逆にデスクトップでは特にコンピュート分野についてはもうデファクトスタンダードといって良いシェアを抱えている。
今後NVIDIAはArmを吸収する見込となっているがMaliとかどうすんのかというのはあまり見えてきていない。