今までCPU側のスレッドについて対応してきたけど、GPU側のスレッドも効率的に使いたい。
Z Prepassや影、通常のメッシュ描画については何も考えずにDrawコマンドを発行すれば並列に処理してくれる。
![]() |
| GPU側で並列に処理されている様子 |
最近までシェーダを切り替える度にコマンドリストを実行して、その処理が終わるまで待っていた。なのでコマンドリストに詰めた単位では重なって並列に処理されているけど、コマンドリストの実行自体を1フレーム内で何回も呼んで、しかもGPU側の処理が終わるまで待っていたので処理の塊の間の隙間が大きくなっていた。
CPU側のマルチスレッド対応にともなって、複数のコマンドリストを用意してやること&シェーダを跨いでまとめて実行できるようになり、GPU側の処理の並列度が上がり、処理の塊の間隔も短くなった。
ライブラリ側の描画処理はDraw関数を呼び出すと、その中でZ Prepass、影、G Buffer描画、Defferdレンダリング、Emmisiveのポストエフェクトをまとめて実行するようになっている。
サブカメラを用意して、今のシーンをメインカメラと、サブカメラからレンダリング後メインカメラの描画をワイプで画面端に描画するようにしていた。
この時、レンダリングターゲットを変えて、2回Draw関数を呼び出している。
PIXで確認すると、同じような並びの処理の塊が2回続く。
Z Prepass、影、G Buffer描画、DefferdレンダリングまではGPU側で全体を並列で処理しているような形になっている。ただその後のEmmisiveの部分で並列にはならず、その前の処理を待って次の処理が始まっている。
Drawの処理を分解して、それぞれ独立して呼べるように修正した。
そして、メインカメラ、サブカメラのZ Prepass、影、G Buffer描画、Defferdレンダリングまでを先に処理して、それぞれのEmmisiveを最後に処理するようにした。
![]() |
| 前半の処理をまとめた結果 |
こうすることで、かなりの処理が並列に動いているように見えるようになった。
最後のEmissive部分も並列にできないかと、リソースを2倍にしてそれぞれ被らないようにして実行してみたけど、全く変わらなかった。
バリアを張ってしまうと、対象のリソースは関係なしに全部が止まってしまうのか?
おそらく同じ意味のバリアなら、複数同時に出来る。
例えばテクスチャコピーを2つ連続なら並列になる。
だけど、テクスチャコピーして、そのコピーが完了してミップマップを生成するとなると、全く別のリソースに対して行ってるのに、並列に行われなかった。
複数のキュー
バリアを挟む複数の操作をしてしまうと、最小単位で同じ操作をまとめていかない限り並列には処理ができなさそう。
こういった場合でも処理を並列にしたい場合は、キュー自体を複数用意すればいいのでは無いか?
例えば2人用、4人用など複数人用に別々の画面をレンダリングするような場合、1つのキューではなく複数のキューでそれぞれ処理して、最後に揃ったところで画面にレンダリングすると、何も考えずに並列処理ができそう。


0 件のコメント:
コメントを投稿