UCableComponent のロード時に RayTracingGeometry パスで GPU クラッシュが発生する

Windows(D3D12 / NVIDIA GPU)環境で r.RayTracing を有効にしている場合、UCableComponent のロード時に GPU クラッシュが発生する問題に遭遇しています。

クラッシュログを見ると、内部の BLAS ビルド用シェーダー内でクラッシュしているようです。

​

以下は、Game ビルドでクラッシュが発生した際の NVIDIA Aftermath ログを

GPUCrash_UCableComponent_NVIDIA_Aftermath_Log.txt

として添付させていただいております。​

​

調査したところ、UCableComponent の未初期化の index buffer(および、おそらく vertex buffer)が BLAS(FRayTracingGeometry)のビルドに使用されていることが原因ではないかと考えています。

​

UE5.7.4のソースコードを見る限り、FCableSceneProxy の index buffer / vertex Bbuffer は、最初の FSendCableDynamicData コマンドが送信・実行されるまで初期化されません。

一方で、StaticRayTracingGeometry は SceneProxy が生成された直後に作成され、BLAS ビルド対象として GRayTracingGeometryManager に追加されています。

​

​

```

class FCableSceneProxy final : public FPrimitiveSceneProxy

{

…

FCableSceneProxy(UCableComponent* Component)

…

{

…

ENQUEUE_RENDER_COMMAND(InitCableResources)(UE::RenderCommandPipe::Cable,

[this] (FRHICommandList& RHICmdList)

{

…

FRayTracingGeometry& RayTracingGeometry = StaticRayTracingGeometry;

CreateRayTracingGeometry_RenderingThread(RayTracingGeometry, RHICmdList);

…

}

}

…

void SetDynamicData_RenderThread(FRHICommandListBase& RHICmdList, FCableDynamicData* NewDynamicData)

{

…

BuildCableMesh(RHICmdList, NewDynamicData);

}

…

};

```

​

UCableComponent::CreateRenderState_Concurrent では、SceneProxy の生成後に index buffer を初期化するため、SendRenderDynamicData が呼び出されているものと理解しています。

​

しかし今回のケースでは、CableComponent が bHiddenInGame = true の状態で Spawn されているため、Spawn 時点では CreateRenderState_Concurrent による SceneProxy が生成されず、SendRenderDynamicData もスキップされます。

その後、bHiddenInGame が Flase に変更された原因で、DoDeferredRenderUpdates_Concurrent → SendRenderTransform_Concurrent の経路によって SceneProxy の作成が強制されます。

​

この経路では SendRenderDynamicData による index buffer の初期化が行われていないまま、CableComponent の StaticRayTracingGeometry が BLAS ビルド対象として追加されるため、無効な index buffer を使用して BLAS がビルドされ、GPU クラッシュにつながっているように見えます。

[Attachment Removed]

再現手順[Attachment Removed]

お世話になっております。

社内でご報告頂いたような類似の問題は今のところ登録されていないようでしたので、この問題についての対応チェンジリストを見つけることはできなかったのですが、原因となる点について調査いたしました。

原因

ご推察の通りですが、Ray Tracing 有効時、UCableComponent の SceneProxy 生成直後に BLAS(FRayTracingGeometry)がビルド対象へ追加されます。一方、ケーブルメッシュの Index Buffer は、最初の SendRenderDynamicData(BuildCableMesh)が実行されるまで未初期化です。未初期化の Index Buffer のまま Acceleration Structure をビルドすると、範囲外インデックス参照により GPU page fault(NVIDIA Aftermath 上は AS Build / Refit 中の MMU Fault)が発生することが推測されます。

bHiddenInGame = true で生成された後に表示へ切り替わるケースでは、SceneProxy が transform 更新経路で作られ、Index Buffer 初期化前に BLAS ビルドが走るため特に顕在化しやすいく、根本原因は「バッファ初期化前に BLAS を組む」ことです。

修正方針

最初の BuildCableMesh 完了まで Ray Tracing geometry / BLAS ビルドを遅延します。Index Buffer が有効になった後にのみ BLAS を作成・更新し、未初期化バッファではビルドしないようにすることで解消できる可能性があります(ProceduralMesh / TextRender と同様)。こちらにつきましては、UE5.7でのパッチを共有いたしますので、問題が解消されるかどうか、お手数ですがご確認いただけますと幸いです。

[Attachment Removed]

ご確認頂きありがとうございます。

こちらの修正が有効であることが確認できましたら、問題をデータベースにバグとして登録し、Engineの本流に反映させることをすすめたいと考えております。

この問題の再現方法が明確になっていない点が現状の課題となっている点です。この問題が再現する条件や設定などが判明しましたら、修正および修正確認を行い本流への反映を行う流れです。最初に再現手順にご記載がありませんでしたので、この問題の再現はプロジェクトの設定や構成、状況に依存して発生している問題であるという理解をしております。もしこの問題の明確な再現方法や手順が分かりましたらお知らせ頂けますと幸いです。この問題を引き続きこちらでも検証して、問題の修正確認をすすめたいと考えております。

[Attachment Removed]

ご確認およびご返答いただきありがとうございます。CableComponentを利用しない方針となった旨、承知いたしました。

本件はクローズいたしますが、もしまた問題が発生しましたら、本件にコメントを追加して頂くか、別途スレッドを立てて頂けますと幸いです。​どうぞ、よろしくお願いします。​

[Attachment Removed]

お世話になっております。

ご調査ならびに修正パッチのご共有、ありがとうございます。

原因についても詳しくご説明いただき、大変助かりました。

共有いただいたパッチについては、こちらでも適用のうえ、問題が解消されるか確認させていただきます。

また一点確認させてください。

今回の問題について、Epic Games様側でも今後のUnreal Engine本体への修正候補として登録いただき、正式な修正を行うフローに載せていただくことは可能でしょうか。

いつも丁寧にご対応いただき、ありがとうございます。

引き続きよろしくお願いいたします。

[Attachment Removed]

返答が遅くなってしまいまして申し訳ありません。​

ご確認ならびにご対応いただき、ありがとうございます。

​

ゲーム仕様の変更に伴い、UCableComponentは当面、弊社プロジェクトでは利用しない方針となりました。そのため、こちらでも引き続き検証を行いたいところではございますが、追加検証や明確な再現手順のご案内が難しい状況です。

ご対応いただいている中、大変恐縮ではございますが、本スレッドはクローズしていただいて問題ございません。これまでご調査・ご対応いただき、ありがとうございました。

[Attachment Removed]