Skip to content

Various small fixes for render graph. #1232

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
Jul 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c421c34
Made conversion from render graph handles to actual resource implicit…
JulienIgnace-Unity Jun 29, 2020
588da00
Merge branch 'HDRP/staging' of https://github.com/Unity-Technologies/…
JulienIgnace-Unity Jun 29, 2020
009691a
Post merge fixes
JulienIgnace-Unity Jun 29, 2020
525db80
Added an exception when accessing resources while not executing rende…
JulienIgnace-Unity Jul 2, 2020
a498747
Removed auto binding of global texture and updated passes accordingly.
JulienIgnace-Unity Jul 3, 2020
d3fd41a
Merge branch 'HDRP/staging' of https://github.com/Unity-Technologies/…
JulienIgnace-Unity Jul 8, 2020
fc73b49
Post merge fix
JulienIgnace-Unity Jul 8, 2020
5841c16
Fixed shadow mask texture binding.
JulienIgnace-Unity Jul 8, 2020
91d9c79
Fix wrong merge
JulienIgnace-Unity Jul 8, 2020
d578450
Fixed fog with MSAA and render graph
JulienIgnace-Unity Jul 8, 2020
3fe335b
Replace new TextureHandle by TextureHandle.nullHandle
JulienIgnace-Unity Jul 8, 2020
033c6b8
Fixed name of some textures
JulienIgnace-Unity Jul 8, 2020
9bfacca
Implemented stub of ScreenSpaceShadows to fix default texture binding.
JulienIgnace-Unity Jul 8, 2020
4f00018
Correctly deallocate cached shadows atlas
JulienIgnace-Unity Jul 8, 2020
4f969ed
Properly set color buffer for transparent custom passes.
JulienIgnace-Unity Jul 8, 2020
a7573ee
Small comment update.
JulienIgnace-Unity Jul 8, 2020
af137c3
Made naming of resources created by RG generic (user names are used f…
JulienIgnace-Unity Jul 10, 2020
5f4f65e
Fixed custom pass global texture binding.
JulienIgnace-Unity Jul 10, 2020
ffb8f49
Added name to real time reflection probe textures.
JulienIgnace-Unity Jul 10, 2020
34a5d3b
Added an option to disable pass pruning and simplified logging code.
JulienIgnace-Unity Jul 10, 2020
e79d159
Added XR copy depth
JulienIgnace-Unity Jul 10, 2020
870fdc5
Merge branch 'HDRP/staging' of https://github.com/Unity-Technologies/…
JulienIgnace-Unity Jul 10, 2020
973de25
Rename "pass pruning" to "pass culling"
JulienIgnace-Unity Jul 10, 2020
6706275
Fixed tests compilation
JulienIgnace-Unity Jul 15, 2020
953a33f
Revert logger changes because they made unavoidable allocs.
JulienIgnace-Unity Jul 15, 2020
235fab6
Removed useless formatting.
JulienIgnace-Unity Jul 15, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 68 additions & 43 deletions com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,36 @@ public struct RenderGraphExecuteParams

class RenderGraphDebugParams
{
public bool tagResourceNamesWithRG;
public bool clearRenderTargetsAtCreation;
public bool clearRenderTargetsAtRelease;
public bool disablePassCulling;
public bool logFrameInformation;
public bool logResources;

public void RegisterDebug()
{
var list = new List<DebugUI.Widget>();
list.Add(new DebugUI.BoolField { displayName = "Tag Resources with RG", getter = () => tagResourceNamesWithRG, setter = value => tagResourceNamesWithRG = value });
list.Add(new DebugUI.BoolField { displayName = "Clear Render Targets at creation", getter = () => clearRenderTargetsAtCreation, setter = value => clearRenderTargetsAtCreation = value });
list.Add(new DebugUI.BoolField { displayName = "Clear Render Targets at release", getter = () => clearRenderTargetsAtRelease, setter = value => clearRenderTargetsAtRelease = value });
list.Add(new DebugUI.Button { displayName = "Log Frame Information", action = () => logFrameInformation = true });
list.Add(new DebugUI.Button { displayName = "Log Resources", action = () => logResources = true });
list.Add(new DebugUI.BoolField { displayName = "Disable Pass Culling", getter = () => disablePassCulling, setter = value => disablePassCulling = value });
list.Add(new DebugUI.Button { displayName = "Log Frame Information",
action = () =>
{
logFrameInformation = true;
#if UNITY_EDITOR
UnityEditor.SceneView.RepaintAll();
#endif
}
});
list.Add(new DebugUI.Button { displayName = "Log Resources",
action = () =>
{
logResources = true;
#if UNITY_EDITOR
UnityEditor.SceneView.RepaintAll();
#endif
}
});

var panel = DebugManager.instance.GetPanel("Render Graph", true);
panel.children.Add(list.ToArray());
Expand Down Expand Up @@ -120,15 +136,15 @@ internal struct CompiledPassInfo
public List<int>[] resourceCreateList;
public List<int>[] resourceReleaseList;
public int refCount;
public bool pruned;
public bool culled;
public bool hasSideEffect;
public int syncToPassIndex; // Index of the pass that needs to be waited for.
public int syncFromPassIndex; // Smaller pass index that waits for this pass.
public bool needGraphicsFence;
public GraphicsFence fence;

public bool enableAsyncCompute { get { return pass.enableAsyncCompute; } }
public bool allowPassPruning { get { return pass.allowPassPruning; } }
public bool allowPassCulling { get { return pass.allowPassCulling; } }

#if DEVELOPMENT_BUILD || UNITY_EDITOR
// This members are only here to ease debugging.
Expand Down Expand Up @@ -168,7 +184,7 @@ public void Reset(RenderGraphPass pass)
}

refCount = 0;
pruned = false;
culled = false;
hasSideEffect = false;
syncToPassIndex = -1;
syncFromPassIndex = -1;
Expand Down Expand Up @@ -198,7 +214,7 @@ public void Reset(RenderGraphPass pass)
// Compiled Render Graph info.
DynamicArray<CompiledResourceInfo>[] m_CompiledResourcesInfos = new DynamicArray<CompiledResourceInfo>[(int)RenderGraphResourceType.Count];
DynamicArray<CompiledPassInfo> m_CompiledPassInfos = new DynamicArray<CompiledPassInfo>();
Stack<int> m_PruningStack = new Stack<int>();
Stack<int> m_CullingStack = new Stack<int>();

#region Public Interface

Expand Down Expand Up @@ -262,7 +278,7 @@ public void PurgeUnusedResources()

/// <summary>
/// Import an external texture to the Render Graph.
/// Any pass writing to an imported texture will be considered having side effects and can't be automatically pruned.
/// Any pass writing to an imported texture will be considered having side effects and can't be automatically culled.
/// </summary>
/// <param name="rt">External RTHandle that needs to be imported.</param>
/// <returns>A new TextureHandle.</returns>
Expand Down Expand Up @@ -323,7 +339,7 @@ public RendererListHandle CreateRendererList(in RendererListDesc desc)

/// <summary>
/// Import an external Compute Buffer to the Render Graph
/// Any pass writing to an imported compute buffer will be considered having side effects and can't be automatically pruned.
/// Any pass writing to an imported compute buffer will be considered having side effects and can't be automatically culled.
/// </summary>
/// <param name="computeBuffer">External Compute Buffer that needs to be imported.</param>
/// <returns>A new ComputeBufferHandle.</returns>
Expand Down Expand Up @@ -511,21 +527,21 @@ void CountReferences()
}
}

void PruneOutputlessPasses()
void CullOutputlessPasses()
{
// Gather passes that don't produce anything and prune them.
m_PruningStack.Clear();
// Gather passes that don't produce anything and cull them.
m_CullingStack.Clear();
for (int pass = 0; pass < m_CompiledPassInfos.size; ++pass)
{
ref CompiledPassInfo passInfo = ref m_CompiledPassInfos[pass];

if (passInfo.refCount == 0 && !passInfo.hasSideEffect && passInfo.allowPassPruning)
if (passInfo.refCount == 0 && !passInfo.hasSideEffect && passInfo.allowPassCulling)
{
// Producer is not necessary as it produces zero resources
// Prune it and decrement refCount of all the resources it reads.
// Cull it and decrement refCount of all the resources it reads.
// We don't need to go recursively here because we decrement ref count of read resources
// so the subsequent passes of pruning will detect those and remove the related passes.
passInfo.pruned = true;
// so the subsequent passes of culling will detect those and remove the related passes.
passInfo.culled = true;
for (int type = 0; type < (int)RenderGraphResourceType.Count; ++type)
{
foreach (var index in passInfo.pass.resourceReadLists[type])
Expand All @@ -538,55 +554,64 @@ void PruneOutputlessPasses()
}
}

void PruneUnusedPasses()
void CullUnusedPasses()
{
// TODO RENDERGRAPH: temporarily remove pruning of passes without product.
// Many passes are used just to set global variables so we don't want to force users to disallow pruning on those explicitly every time.
// This will prune passes with no outputs.
//PruneOutputlessPasses();
if (m_DebugParameters.disablePassCulling)
{
if (m_DebugParameters.logFrameInformation)
{
m_Logger.LogLine("- Pass Culling Disabled -\n");
}
return;
}

// This will prune all passes that produce resource that are never read.
// TODO RENDERGRAPH: temporarily remove culling of passes without product.
// Many passes are used just to set global variables so we don't want to force users to disallow culling on those explicitly every time.
// This will cull passes with no outputs.
//CullOutputlessPasses();

// This will cull all passes that produce resource that are never read.
for (int type = 0; type < (int)RenderGraphResourceType.Count; ++type)
{
DynamicArray<CompiledResourceInfo> resourceUsageList = m_CompiledResourcesInfos[type];

// Gather resources that are never read.
m_PruningStack.Clear();
m_CullingStack.Clear();
for (int i = 0; i < resourceUsageList.size; ++i)
{
if (resourceUsageList[i].refCount == 0)
{
m_PruningStack.Push(i);
m_CullingStack.Push(i);
}
}

while (m_PruningStack.Count != 0)
while (m_CullingStack.Count != 0)
{
var unusedResource = resourceUsageList[m_PruningStack.Pop()];
var unusedResource = resourceUsageList[m_CullingStack.Pop()];
foreach (var producerIndex in unusedResource.producers)
{
ref var producerInfo = ref m_CompiledPassInfos[producerIndex];
producerInfo.refCount--;
if (producerInfo.refCount == 0 && !producerInfo.hasSideEffect && producerInfo.allowPassPruning)
if (producerInfo.refCount == 0 && !producerInfo.hasSideEffect && producerInfo.allowPassCulling)
{
// Producer is not necessary anymore as it produces zero resources
// Prune it and decrement refCount of all the textures it reads.
producerInfo.pruned = true;
// Cull it and decrement refCount of all the textures it reads.
producerInfo.culled = true;

foreach (var resourceIndex in producerInfo.pass.resourceReadLists[type])
{
ref CompiledResourceInfo resourceInfo = ref resourceUsageList[resourceIndex];
resourceInfo.refCount--;
// If a resource is not used anymore, add it to the stack to be processed in subsequent iteration.
if (resourceInfo.refCount == 0)
m_PruningStack.Push(resourceIndex);
m_CullingStack.Push(resourceIndex);
}
}
}
}
}

LogPrunedPasses();
LogCulledPasses();
}

void UpdatePassSynchronization(ref CompiledPassInfo currentPassInfo, ref CompiledPassInfo producerPassInfo, int currentPassIndex, int lastProducer, ref int intLastSyncIndex)
Expand Down Expand Up @@ -657,7 +682,7 @@ int GetLatestValidReadIndex(in CompiledResourceInfo info)
var consumers = info.consumers;
for (int i = consumers.Count - 1; i >= 0; --i)
{
if (!m_CompiledPassInfos[consumers[i]].pruned)
if (!m_CompiledPassInfos[consumers[i]].culled)
return consumers[i];
}

Expand All @@ -672,7 +697,7 @@ int GetFirstValidWriteIndex(in CompiledResourceInfo info)
var producers = info.producers;
for (int i = 0; i < producers.Count; i++)
{
if (!m_CompiledPassInfos[producers[i]].pruned)
if (!m_CompiledPassInfos[producers[i]].culled)
return producers[i];
}

Expand All @@ -687,7 +712,7 @@ int GetLatestValidWriteIndex(in CompiledResourceInfo info)
var producers = info.producers;
for (int i = producers.Count - 1; i >= 0; --i)
{
if (!m_CompiledPassInfos[producers[i]].pruned)
if (!m_CompiledPassInfos[producers[i]].culled)
return producers[i];
}

Expand All @@ -708,7 +733,7 @@ void UpdateResourceAllocationAndSynchronization()
{
ref CompiledPassInfo passInfo = ref m_CompiledPassInfos[passIndex];

if (passInfo.pruned)
if (passInfo.culled)
continue;

for (int type = 0; type < (int)RenderGraphResourceType.Count; ++type)
Expand Down Expand Up @@ -789,16 +814,16 @@ void UpdateResourceAllocationAndSynchronization()
m_Resources.CreateRendererLists(m_RendererLists);
}

// Internal for testing purpose only
// Internal visibility for testing purpose only
// Traverse the render graph:
// - Determines when resources are created/released
// - Determines async compute pass synchronization
// - Prune unused render passes.
// - Cull unused render passes.
internal void CompileRenderGraph()
{
InitializeCompilationData();
CountReferences();
PruneUnusedPasses();
CullUnusedPasses();
UpdateResourceAllocationAndSynchronization();
LogRendererListsCreation();
}
Expand All @@ -814,7 +839,7 @@ void ExecuteRenderGraph(ScriptableRenderContext renderContext, CommandBuffer cmd
for (int passIndex = 0; passIndex < m_CompiledPassInfos.size; ++passIndex)
{
ref var passInfo = ref m_CompiledPassInfos[passIndex];
if (passInfo.pruned)
if (passInfo.culled)
continue;

if (!passInfo.pass.HasRenderFunc())
Expand Down Expand Up @@ -982,16 +1007,16 @@ void LogRenderPassBegin(in CompiledPassInfo passInfo)
}
}

void LogPrunedPasses()
void LogCulledPasses()
{
if (m_DebugParameters.logFrameInformation)
{
m_Logger.LogLine("Pass pruning report:");
m_Logger.LogLine("Pass Culling Report:");
using (new RenderGraphLogIndent(m_Logger))
{
for (int i = 0; i < m_CompiledPassInfos.size; ++i)
{
if (m_CompiledPassInfos[i].pruned)
if (m_CompiledPassInfos[i].culled)
{
var pass = m_RenderPasses[i];
m_Logger.LogLine("[{0}] {1}", pass.index, pass.name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,15 +175,15 @@ public void EnableAsyncCompute(bool value)
}

/// <summary>
/// Allow or not pass pruning
/// By default all passes can be pruned out if the render graph detects it's not actually used.
/// Allow or not pass culling
/// By default all passes can be culled out if the render graph detects it's not actually used.
/// In some cases, a pass may not write or read any texture but rather do something with side effects (like setting a global texture parameter for example).
/// This function can be used to tell the system that it should not prune this pass.
/// This function can be used to tell the system that it should not cull this pass.
/// </summary>
/// <param name="value"></param>
public void AllowPassPruning(bool value)
/// <param name="value">True to allow pass culling.</param>
public void AllowPassCulling(bool value)
{
m_RenderPass.AllowPassPruning(value);
m_RenderPass.AllowPassCulling(value);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public class RenderGraphDefaultResources
public TextureHandle magentaTextureXR { get; private set; }
/// <summary>Default black XR 2D texture.</summary>
public TextureHandle blackTextureXR { get; private set; }
/// <summary>Default black XR 2D Array texture.</summary>
public TextureHandle blackTextureArrayXR { get; private set; }
/// <summary>Default black (UInt) XR 2D texture.</summary>
public TextureHandle blackUIntTextureXR { get; private set; }
/// <summary>Default black XR 3D texture.</summary>
Expand Down Expand Up @@ -52,6 +54,7 @@ internal void InitializeForRendering(RenderGraph renderGraph)
clearTextureXR = renderGraph.ImportTexture(TextureXR.GetClearTexture());
magentaTextureXR = renderGraph.ImportTexture(TextureXR.GetMagentaTexture());
blackTextureXR = renderGraph.ImportTexture(TextureXR.GetBlackTexture());
blackTextureArrayXR = renderGraph.ImportTexture(TextureXR.GetBlackTextureArray());
blackUIntTextureXR = renderGraph.ImportTexture(TextureXR.GetBlackUIntTexture());
blackTexture3DXR = renderGraph.ImportTexture(TextureXR.GetBlackTexture3D());
whiteTextureXR = renderGraph.ImportTexture(TextureXR.GetWhiteTexture());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public RenderFunc<PassData> GetExecuteDelegate<PassData>()
public int index { get; protected set; }
public ProfilingSampler customSampler { get; protected set; }
public bool enableAsyncCompute { get; protected set; }
public bool allowPassPruning { get; protected set; }
public bool allowPassCulling { get; protected set; }

public TextureHandle depthBuffer { get; protected set; }
public TextureHandle[] colorBuffers { get; protected set; } = new TextureHandle[RenderGraph.kMaxMRTCount];
Expand Down Expand Up @@ -56,15 +56,15 @@ public void Clear()

usedRendererListList.Clear();
enableAsyncCompute = false;
allowPassPruning = true;
allowPassCulling = true;
refCount = 0;

// Invalidate everything
colorBufferMaxIndex = -1;
depthBuffer = new TextureHandle();
depthBuffer = TextureHandle.nullHandle;
for (int i = 0; i < RenderGraph.kMaxMRTCount; ++i)
{
colorBuffers[i] = new TextureHandle();
colorBuffers[i] = TextureHandle.nullHandle;
}
}

Expand Down Expand Up @@ -93,9 +93,9 @@ public void EnableAsyncCompute(bool value)
enableAsyncCompute = value;
}

public void AllowPassPruning(bool value)
public void AllowPassCulling(bool value)
{
allowPassPruning = value;
allowPassCulling = value;
}

public void SetColorBuffer(TextureHandle resource, int index)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace UnityEngine.Experimental.Rendering.RenderGraphModule

abstract class RenderGraphResourcePool<Type> where Type : class
{
// Dictionary tracks resources by hash and stores resources with same hash in a List (list instead of a stack because we need to be able to remove stale allocations).
// Dictionary tracks resources by hash and stores resources with same hash in a List (list instead of a stack because we need to be able to remove stale allocations, potentially in the middle of the stack).
protected Dictionary<int, List<(Type resource, int frameIndex)>> m_ResourcePool = new Dictionary<int, List<(Type resource, int frameIndex)>>();

#if DEVELOPMENT_BUILD || UNITY_EDITOR
Expand Down
Loading