Direct3D12について雑記
自分が作った
自作Direct3D12ライブラリを公開したのも年単位で過ぎ去り、Direct3D12について結構忘れてきたので、忘れないようにBlogに書き留めておく。
数パートに分けて書くと思うが、Githubに公開してる
Direct3D11の解説程かっちりしたものにはせず、箇条書きに申し訳程度の追記と簡素なものにするつもり。
それと、あやふやな記憶を頼りに書いているので(特に歴史とかは聞きかじった程度の物)誤りを指摘いただける大変助かります。
この記事で言いたいこと
- Direct3D11からDirect3D12へのバージョンアップはJavaからC言語へバージョンアップするみたいなこと
- 下手なDirect3D12実装よりDirect3D11を使った方がましであるということ
- 速くするためのものではなく、無駄を削るものである
後、Direct3D12については
こちらの記事の方が詳しいです
Direct3D12とは?
Direct3D12とは非常によくできたグラフィックスAPIであったDirect3D11を基盤に、CPUオーバーヘッドを限りなく減らすため修正されたグラフィックスAPIである。
Direct3D12が公開された当初はLow CPU Overheadだ!なんやらと宣言され、それに触発されてかOpenGLは昔からLow CPU Overheadだったぜと言っていたり、Low CPU OverheadのきっかけとなったMantleの影が薄くなったり、それよりマルチプラットフォームでLow CPU OverheadなVulkanがあればDirect3Dなんていらないしと、数年前はグラフィックAPI界隈は賑やかであったと思う。
(個人的には今から勉強するならVulkanだと思う)
Low CPU Overhead化するということは、コンシューマゲーム機のように生身のGPUにPC上から触ることができることである。ゲーム業界に詳しくないなら、Direct3D11からDirect3D12へのバージョンアップは、JavaからC言語に進化したものだと思ってほしい。
さすがに使っているGPU全てにアクセスできる訳ではないが、
NVIDIAやAMDなどのGPUベンダーは独自拡張した機能をDirect3D12からアクセスできる拡張機能を提供している。
が、拡張機能を使うならVulkanの方が情報が多いのでやりやすい。
(やっぱり覚えるならVulkanじゃないかな…?)
Direct3D12を使うメリットは最新機能が比較的早く公開&触れる。(GPUは別売り)
それとWindowsという安定したプラットフォームで動作するので安心感がある、が挙げられる。
個人的にはDirect3Dのシェーダ言語、HLSLを気に入っているが、Vulkanでも使えるようになったので、昔のOpenGLとDirect3D9程の違いは現在のグラフィックスAPI間にはあまりない。
長々と書いたが、
Direct3D12とはLow CPU Overhead化を実現するためにDirect3D11から省けるところを省いたグラフィックスAPIである。
省かれた部分
それでは省かれた部分はどういったものかというと、下のものになる。
- GPUへのコマンド発行
- メモリ管理
- パイプラインステート管理
Low CPU Overhead化と宣伝されていたので1.GPUへのコマンド発行と3.のパイプラインステート管理が注目を集めていたが、2.メモリ管理も大変重要なところで、アロケータからメモリの断片化対策までこちらで面倒を見る必要がでてきた。後、リソースの初期化も手順が増えている。
Direct3D11までの時代はメモリ管理はGPUドライバー側が面倒を見ていた。
が、それに不満を持った開発者側と肥大化していくGPU機能の管理に疲れたGPUドライバー開発者側の意見の一致でこうなったのである。(たぶん)
(汎用的なメモリアロケータではゲームやCAD、モデリングツールすべてで最適なものを提供できるかと言われたら無理でしょう。)
なので、Direct3D12は誰でも触るものではなく、本当にプロフェッショナルな人が扱うAPIである。
記事にでも出ていたが、下手なDirect3D12実装されたレンダラーとDirect3D11実装されたレンダラーではパフォーマンス的にみるとDirect3D11の方が速くなるし(=GPUドライバー製作者の上を行く必要が出てくる + Direct3D12専用の処理の流れにしないといけない)、使っているCPUが速いと両者で違いがでないので注意が必要だ。(Direct3D11で生じるコストをCPUが十分にカバーしている)
低性能なCPU上では速くなりやすいが、そんな環境ってスマフォの方が多いという現実がある。(Vulkanの方が活躍できる環境が多いといえる)
あと、GPUが原因のボトルネックはDirect3Dは関係ないのでどうしようもない。
Direct3D12で速くなる場面が限られているので注意が必要だ。
実際に体験してみたくて、時間に余裕がある人は、私の作ったライブラリにあるBetterDrawCallSceneを実行して一度に発行するDrawコールの数を調節してみると体験できると思う。
(色々コードをいじる必要がある+動かないかもしれないので、面倒です。
dx12Test/scene/IScene.cpp内のIScene::sGetStartSceneNo関数の戻り値をeSCENE_BETTER_DRAW_CALLに変えてもらえたら確認用シーンは実行できます。
実行したら後は矢印キーでDrawコールの数を調節してください。
リングバッファの上限を超えると落ちます。)
速くするというより最大限にGPUとCPUを稼働させるためには、互いに待ち時間を持たせないようにすることが大事です。
じゃ、どうなのDirect3D12って
手放しで喜べるものではないDirect3D12であるが、(関係者ではないので)個人的には過去のGPUとのお別れを告げたものだと思う。昔はいろいろなGPUベンダーがいて、なかなか共通化が大変だったのが、近年はNVIDIAとAMDぐらいとベンダーの減少、それとGPU機能も似たものになった+昔は固定機能をもつ頂点シェーダやピクセルシェーダを実行するだけだったGPUがGPGPUといった汎用計算が可能なアーキテクチャに変化していった背景もあり、関係会社にってもはや過去の遺物となったものを清算するのにいい機会だったのではないでしょうか?
(特に21世紀以前から現役のOpenGLからVulkanへの変化は判りやすいと)
今後のGPUはDirect3D12とVulkanという土台を元に発展していくでしょう。
なので、GPUにとってのC言語的な役割を果たしていくDirect3D12は今後長く使われていくと思う。
速くするためじゃない、無駄を削るため、より作り手の思い通りにGPUを操るためにDirect3D12は誕生したといえるかもしれない。