Vulkanでハマる
ここ数年、仕事で3Dを直接扱うことがあまり多くなかったので
ちょっと勘が鈍っています。
直接というのは
自分で座標計算やらなんやらしてGPUを叩く的な意味です。
最近はライブラリが充実しているので
あまり気にせず組めてしまうんですよね。
楽に作れると面を見れば良いことなのでしょうが
ライブラリに頼っていると
基礎が抜けてしまうので長い目で見れば自分のためにはならないなと思っています。
そんなわけで昨年の年末くらいから
Direct3D12とVulkanの勉強を始めました。
Vulkan ってなんぞや?
Vulkan公式: https://www.khronos.org/vulkan/
3D APIで有名なところといえば、OpenGL ですが
OpenGLはなんせ数十年前に出来たAPIです。
アップデートを重ねて互換性を保っていますが
内部はかなり複雑になり、APIとしてのオーバーヘッドが大きくなっています。
そこで、最近のAPIの流行である
「低レベルAPI」な規格が「Vulkan」です。
OpenGL同様に、khronos group が仕様をまとめています。
対応環境
マルチプラットフォームがウリのVulkanですが
今のところ使用できるのは
WindowsとAndroid(7.0以降)、LinuxなどのUnix likeなOSです。
ちなみにAppleはどうやらサポートしない気のようです。
独自にMetalというAPIを公開していますし、そちらを普及させたいのでしょう。
個人的にはApple系のOSでもVulkanをサポートしてもらいたいところです。
対応GPU
正式にサポートしているのは AMD と nVidia です。
AMDだとR7以降、nVidiaだとKelper世代以降で対応です。
基本的には2012年以降のGPUなら対応可能です。
Intelはというと、SkyLakeとKabyLakeで対応となっています。
ただ、こちらについてはドライバーがまだBeta版になっていますので
事実上、使用できるとはまだ言い難いですね。
Direct3D12との違い
細かい違いはあるものの大きな方針はそれほど違いはありません。
ただ、APIとしてはDirect3D12のほうが洗礼されているというか
多少は扱いやすいというかわかりやすくなっています。
Vulkanはそれこそ何から何までプログラムで設定しないとならないので
「それくらいは管理してよ!」と思うところもあります。
特にパラメータの取得系がほとんどないのは厳しいですね。
基本的に全部ラップしないとならないような作りなので
手間がかかります。
まぁオーバーヘッドが極力少なくなるというメリットもあるのでしょうが……
OpenGLの時もですが、khronos groupのAPIは全体的に
設計が雑という感じがします。
……まぁそこは文句を言ってもしゃーないのですが。
特に、今回ハマっているバリア回りはかなり面倒です……
パラメータが細かすぎるっちゅーねん!
しかし面白い!
とりあえず Vulkan で画面をクリアしただけのプログラムです。
よく見ると、画面の下のほうは塗りつぶされていますが
上のほうはドット模様のようになっていますね。
これ、画面のクリアの終了待ちの処理がうまくいってないからなのですが
GPUがどうやって処理しているかがよくわかります。
Windowsの場合、ディスプレイの下側から上に向かって画面を更新します。
これは単純に垂直同期を待たずに画面を更新するときに
下から上に書いたほうがチラつきを少なくできるからです。
というわけで、GPUもそれに合わせてか下から上に描画していると推測してみます。
なので、下の方だけ塗りつぶされているわけですね。
で、今度はドット模様になっている理由ですが
これはおそらく、GPUの中では複数のコアが走っているわけですが
クリア命令も複数のコアが同時に行っています。
なので、つくりとしては各コアごとに小さな描画エリアを担当し
並列に塗りつぶしを行っているわけですね。
いわゆるタイルベースな構造です。
今までのAPIだとこういったことは起こらないように
ドライバーの中身で同期をとっていてくれたので
まず見ることはできませんでしたが
D3D12やVulkanではドライバーがやってくれないので
こうした意図しない結果が簡単に起きてしまいます。
逆に言うと、そうした意図しない結果になったときに
GPUの動きがどうなっているのかがチラっと見えるわけです。
こういうのが見えるのは技術者としては楽しくもあります。
面倒でもありますが(笑)