Skip to content

Commit e9b4a98

Browse files
axolotoEvergreen
authored andcommitted
Graphics/SRP/RPF - [UUM-72067] Fix nullptr exception with missing renderFunc hash
This PR fixes the nullptr exception thrown when a Render Graph pass was missing a renderFunc but tried to compute its hash value. We will now return a hash value of 0 if no render function, the Render Graph compiler will return later an explicit error if the renderFunc is missing anyway. At least, now users have a clear message so they can address the issue by implementing their missing renderFunc.
1 parent 723d2c9 commit e9b4a98

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphPass.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ public override bool HasRenderFunc()
557557
[MethodImpl(MethodImplOptions.AggressiveInlining)]
558558
public override int GetRenderFuncHash()
559559
{
560-
return renderFunc.GetHashCode();
560+
return (renderFunc != null) ? renderFunc.GetHashCode() : 0;
561561
}
562562
}
563563

@@ -595,7 +595,7 @@ public override bool HasRenderFunc()
595595
[MethodImpl(MethodImplOptions.AggressiveInlining)]
596596
public override int GetRenderFuncHash()
597597
{
598-
return renderFunc.GetHashCode();
598+
return (renderFunc != null) ? renderFunc.GetHashCode() : 0;
599599
}
600600
}
601601

@@ -633,7 +633,7 @@ public override bool HasRenderFunc()
633633
[MethodImpl(MethodImplOptions.AggressiveInlining)]
634634
public override int GetRenderFuncHash()
635635
{
636-
return renderFunc.GetHashCode();
636+
return (renderFunc != null) ? renderFunc.GetHashCode() : 0;
637637
}
638638
}
639639

@@ -671,7 +671,7 @@ public override bool HasRenderFunc()
671671
[MethodImpl(MethodImplOptions.AggressiveInlining)]
672672
public override int GetRenderFuncHash()
673673
{
674-
return renderFunc.GetHashCode();
674+
return (renderFunc != null) ? renderFunc.GetHashCode() : 0;
675675
}
676676
}
677677
}

Packages/com.unity.render-pipelines.core/Tests/Editor/RenderGraphTests.cs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using UnityEngine.Experimental.Rendering;
55
using UnityEngine.Rendering.RenderGraphModule;
66
using System.Collections.Generic;
7+
using UnityEngine.TestTools;
78

89
#if UNITY_EDITOR
910
using UnityEditor.Rendering;
@@ -13,10 +14,12 @@ namespace UnityEngine.Rendering.Tests
1314
class RenderGraphTests
1415
{
1516
// For RG Record/Hash/Compile testing, use m_RenderGraph
16-
RenderGraph m_RenderGraph;
17+
RenderGraph m_RenderGraph;
18+
1719
RenderPipelineAsset m_OldDefaultRenderPipeline;
20+
RenderPipelineAsset m_OldQualityRenderPipeline;
1821

19-
// For RG Execute/Submit testing with rendering, use m_RenderGraphTestPipeline and its recordRenderGraphBody
22+
// For RG Execute/Submit testing with rendering, use m_RenderGraphTestPipeline and m_RenderGraph in its recordRenderGraphBody
2023
RenderGraphTestPipelineAsset m_RenderGraphTestPipeline;
2124
RenderGraphTestGlobalSettings m_RenderGraphTestGlobalSettings;
2225

@@ -96,12 +99,14 @@ public void Setup()
9699
#if UNITY_EDITOR
97100
EditorGraphicsSettings.SetRenderPipelineGlobalSettingsAsset<RenderGraphTestPipelineInstance>(m_RenderGraphTestGlobalSettings);
98101
#endif
99-
// Saving old render pipeline to set it back after testing
102+
// Saving old render pipelines to set them back after testing
100103
m_OldDefaultRenderPipeline = GraphicsSettings.defaultRenderPipeline;
104+
m_OldQualityRenderPipeline = QualitySettings.renderPipeline;
101105

102106
// Setting the custom RG render pipeline
103107
m_RenderGraphTestPipeline = ScriptableObject.CreateInstance<RenderGraphTestPipelineAsset>();
104108
GraphicsSettings.defaultRenderPipeline = m_RenderGraphTestPipeline;
109+
QualitySettings.renderPipeline = m_RenderGraphTestPipeline;
105110

106111
// Getting the RG from the custom asset pipeline
107112
m_RenderGraph = m_RenderGraphTestPipeline.renderGraph;
@@ -113,6 +118,9 @@ public void Cleanup()
113118
GraphicsSettings.defaultRenderPipeline = m_OldDefaultRenderPipeline;
114119
m_OldDefaultRenderPipeline = null;
115120

121+
QualitySettings.renderPipeline = m_OldQualityRenderPipeline;
122+
m_OldQualityRenderPipeline = null;
123+
116124
m_RenderGraph.Cleanup();
117125

118126
Object.DestroyImmediate(m_RenderGraphTestPipeline);
@@ -969,6 +977,35 @@ public void CreateLegacyRendererLists()
969977
GameObject.DestroyImmediate(gameObject);
970978
}
971979

980+
[Test]
981+
public void RenderPassWithNoRenderFuncThrows()
982+
{
983+
// We need a real ScriptableRenderContext and a camera to execute the render graph
984+
// add the default camera
985+
var gameObject = new GameObject("testGameObject")
986+
{
987+
hideFlags = HideFlags.HideAndDontSave
988+
};
989+
gameObject.tag = "MainCamera";
990+
var camera = gameObject.AddComponent<Camera>();
991+
992+
// record and execute render graph calls
993+
m_RenderGraphTestPipeline.recordRenderGraphBody = (context, camera, cmd) =>
994+
{
995+
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPassWithNoRenderFunc", out var passData))
996+
{
997+
builder.AllowPassCulling(false);
998+
999+
// no render func
1000+
}
1001+
};
1002+
LogAssert.Expect(LogType.Error, "Render Graph Execution error");
1003+
LogAssert.Expect(LogType.Exception, "InvalidOperationException: RenderPass TestPassWithNoRenderFunc was not provided with an execute function.");
1004+
camera.Render();
1005+
1006+
GameObject.DestroyImmediate(gameObject);
1007+
}
1008+
9721009
/*
9731010
// Disabled for now as version management is not exposed to user code
9741011
[Test]

0 commit comments

Comments
 (0)