【URP 17, RenderGraph】Invalid version: 20
環境
- Unity 6000.0.15f1
- Universal RP 17.0.3
- 2D Rendererカスタム
Invalid version: 20
既存のプロジェクトのUnityバージョンアップに伴い、URPを14から17にアップグレードし、諸々のカスタムレンダリングパスをRenderGraphに対応させていたところ、Render Graph Execution Errorというエラーが毎フレーム発生するようになりました。
Render Graph Execution error
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
Render Graph移行に伴うエラーはこれまでにも何度か目にしましたが、エラーが出始めた1フレーム目に原因の例外等が発生している傾向があるように感じます。
今回も大量のログを遡ると、先頭に次のようなエラーが見つかりました。
Exception: Invalid version: 20
UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler.ResourcesData.Index (UnityEngine.Rendering.RenderGraphModule.ResourceHandle h) (at ./Library/PackageCache/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/ResourcesData.cs:304)
UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler.ResourcesData.get_Item (UnityEngine.Rendering.RenderGraphModule.ResourceHandle h) (at ./Library/PackageCache/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/ResourcesData.cs:325)
UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler.NativePassCompiler.BuildGraph () (at ./Library/PackageCache/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.cs:261)
UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler.NativePassCompiler.Compile (UnityEngine.Rendering.RenderGraphModule.RenderGraphResourceRegistry resources) (at ./Library/PackageCache/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.cs:84)
UnityEngine.Rendering.RenderGraphModule.RenderGraph.CompileNativeRenderGraph (System.Int32 graphHash) (at ./Library/PackageCache/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.Compiler.cs:20)
UnityEngine.Rendering.RenderGraphModule.RenderGraph.Execute () (at ./Library/PackageCache/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs:1221)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)
調査
ソースを見に行ってみましょう。
まだよくわかりませんが、ResourceHandle
のversion
がMaxVersions
を超えているとエラーが発生するようです。
このResourceHandle
はRenderGraphにおけるテクスチャ等へのハンドルであり、あるフレーム内におけるリソースの状態の変遷をバージョン値として保存しています。
例えば、RenderGraphでパスを実行する際、次のようなコードで書き込み対象のリソースを宣言します。
UniversalResourceData resourcesData = frameData.Get<UniversalResourceData>();
using (var builder = renderGraph.AddRasterRenderPass<CopyPassData>("Copy Pass",
out var passData, profilingSampler))
{
// cameraColorを書き込み対象として宣言
builder.SetRenderAttachment(resourcesData.cameraColor, 0, AccessFlags.Write);
/* パスの発行 */
}
実はこのとき、SetRenderAttachment()
の呼び出しによって、cameraColor
のバージョンがインクリメントされています。
このバージョン値に上限があるというのが真相のようです。
もとの例外を投げている個所で参照されているMaxVersions
の定義を見てみました。
MaxVersions
は20
で、定数として定義されています。また、続くコメントには「ほとんどのグラフではこの制限で十分です」といったようなことが書かれています。
つまり、いちフレーム内のあるレンダーターゲットに対する書き込みは20パスくらいが上限として十分である、というのがRenderGraphの設計のようです。
対策
いまのところは書き込みパスの数を減らす、あるいはパッケージを改造してMaxVersions
を増やすというのが有効な対策となりそうです。どちらもなかなか面倒ですが……。
カスタムフルスクリーンパスを積んでいけば容易に達する制限のようにも思えるので、なにか簡単な回避策があるとうれしいですね。
Discussion