見出し画像

Unity URPでGPU処理負荷を画面に出してみる

Unity 2020.3 + URP 10.7.0 や、Unity2021.2 + URP 12.1.0で画像のような形で、項目別にGPUの負荷を出すものをつくりました。

画像1

※動作環境によっては対応していません。
動作環境がサポートしているかどうかは SystemInfo.supportsGpuRecorderで判定可能です

こちらは、このソースをプロジェクトの何処かに格納したのち、PlayerSettingsでDefineに「UNITY_USE_RECORDER」を定義することで利用が可能になっています。(画像を参照)

画像2

※ソース側に表示用のUIオブジェクトの生成など諸々入っていますので、ソースコードいれるだけで利用できます。

■実現方法について

UnityのAPI CustomSamplerでは実は関連したGPU処理負荷を収集するかどうかを指定することが出来ます。
CustomSampler.Createの引数でGPUを集めるかどうかという事が指定可能です。そして、GPUを集めるCustomSamplerからGetRecorderして、Recorder.gpuElapsedNanosecondsにてGPUの処理時間を取得することが可能となっています。
今回はこの辺の仕組みから値を取得するようになっています。

■URPでの事

Unityのcom.unity.render-pipelines.coreパッケージにあるUnityEngine.Rendering.ProfilingSamplerというクラスがこの辺をラップしています。

つまり、このProfilingSamplerをひたすら集めていって、それをもとに出せば良さそうです。

ちなみに自分で書いたPassでも計測したい場合は、URPのDrawObjectsPass.csとかが参考になります。
1.ProfilerSamplerをメンバー変数として作成
2.ProfilingScopeをusing ブロックで括る
こんな感じで、計測可能になります。

■そして実装

InternalやPrivateの壁があり、ProfilingSampler一覧をそのままでは取得できなかったので、Reflectionを駆使して集めて回っていくという事をやっただけです。

このような形でGPU負荷を表示することが出来ました。

※あと諸注意ですが・・・。今回は「ソースコード一つで完結する&さっくり作る」ことを目指してたので、GC Allocフリーということまではしていません。UIの数字更新ごとに、GC Allocします。ご注意を…
あと毎フレーム書き換えだと人類には速すぎたので、1秒に1度しか変えてません。頻度を変更したい場合はソース書き換えて下さい。

最後にソースコード載せておきます。



いいなと思ったら応援しよう!