【URP 17, RenderGraph】Invalid version: 20

2024/09/10に公開

環境

  • 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&)

調査

ソースを見に行ってみましょう。

https://github.com/Unity-Technologies/Graphics/blob/fc267ad41df7e0cf39300c4c4d57dd1dc890c054/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/ResourcesData.cs#L298-L307

まだよくわかりませんが、ResourceHandleversionMaxVersionsを超えているとエラーが発生するようです。

この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のバージョンがインクリメントされています。

https://github.com/Unity-Technologies/Graphics/blob/fc267ad41df7e0cf39300c4c4d57dd1dc890c054/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphBuilders.cs#L238-L243

このバージョン値に上限があるというのが真相のようです。

もとの例外を投げている個所で参照されているMaxVersionsの定義を見てみました。

https://github.com/Unity-Technologies/Graphics/blob/fc267ad41df7e0cf39300c4c4d57dd1dc890c054/Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/ResourcesData.cs#L196

MaxVersions20で、定数として定義されています。また、続くコメントには「ほとんどのグラフではこの制限で十分です」といったようなことが書かれています。

つまり、いちフレーム内のあるレンダーターゲットに対する書き込みは20パスくらいが上限として十分である、というのがRenderGraphの設計のようです。

対策

いまのところは書き込みパスの数を減らす、あるいはパッケージを改造してMaxVersionsを増やすというのが有効な対策となりそうです。どちらもなかなか面倒ですが……。

カスタムフルスクリーンパスを積んでいけば容易に達する制限のようにも思えるので、なにか簡単な回避策があるとうれしいですね。

Discussion