From 25ce9f2a5a126bf338f68c8465c87abb54125cb5 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 26 Mar 2015 18:16:38 +0000 Subject: [PATCH] Fix filling out drawcall timings if 'hide empty' option is enabled * Previously we'd expect to run through the same algorithm to generate the drawcall nodes, but fill in the existing nodes. However this completely broke down when some nodes weren't created because they were empty. Now instead we just iterate the nodes that are there and look up any values in the timing results. --- renderdocui/Windows/EventBrowser.cs | 92 +++++++++++++++++------------ 1 file changed, 53 insertions(+), 39 deletions(-) diff --git a/renderdocui/Windows/EventBrowser.cs b/renderdocui/Windows/EventBrowser.cs index 6d9b248ac..c6ed6c26b 100644 --- a/renderdocui/Windows/EventBrowser.cs +++ b/renderdocui/Windows/EventBrowser.cs @@ -224,7 +224,7 @@ namespace renderdocui.Windows return new TreelistView.Node(new object[] { EID, draw, text, duration }); } - private TreelistView.Node AddDrawcall(TreelistView.Node existing, FetchDrawcall drawcall, TreelistView.Node root, Dictionary> times) + private TreelistView.Node AddDrawcall(FetchDrawcall drawcall, TreelistView.Node root) { if (m_Core.Config.EventBrowser_HideEmpty) { @@ -233,20 +233,7 @@ namespace renderdocui.Windows } UInt32 eventNum = drawcall.eventID; - double duration = 0.0; - if (times != null && times.ContainsKey(eventNum)) - duration = times[eventNum][0].value.d; - TreelistView.Node drawNode = MakeNode(eventNum, drawcall.drawcallID, drawcall.name, duration); - - if (existing != null) - { - existing.SetData(drawNode.GetData()); - drawNode = existing; - } - else - { - root.Nodes.Add(drawNode); - } + TreelistView.Node drawNode = MakeNode(eventNum, drawcall.drawcallID, drawcall.name, 0.0); DeferredEvent def = new DeferredEvent(); def.frameID = m_Core.CurFrame; @@ -275,17 +262,12 @@ namespace renderdocui.Windows { for (int i = 0; i < drawcall.children.Length; i++) { - TreelistView.Node d = drawNode.Nodes.Count > i ? drawNode.Nodes[i] : null; - - AddDrawcall(d, drawcall.children[i], drawNode, times); + AddDrawcall(drawcall.children[i], drawNode); if (i > 0 && (drawcall.children[i-1].flags & DrawcallFlags.SetMarker) > 0) { drawNode.Nodes[drawNode.Nodes.Count - 2].Tag = drawNode.Nodes.LastNode.Tag; } - - if (i < drawNode.Nodes.Count && (double)drawNode.Nodes[i]["Duration"] > 0.0) - drawNode["Duration"] = Math.Max(0.0, (double)drawNode["Duration"]) + (double)drawNode.Nodes[i]["Duration"]; } bool found = false; @@ -305,10 +287,50 @@ namespace renderdocui.Windows drawNode.Tag = drawNode.Nodes.LastNode.Tag; } + if (drawNode.Nodes.IsEmpty() && (drawcall.flags & DrawcallFlags.PushMarker) != 0) + return null; + + root.Nodes.Add(drawNode); + return drawNode; } - private void AddFrameDrawcalls(TreelistView.Node frame, FetchDrawcall[] drawcalls, Dictionary> times) + private void SetDrawcallTimes(TreelistView.Node n, Dictionary> times) + { + if (n == null || times == null) return; + + // parent nodes take the value of the sum of their children + double duration = 0.0; + + // look up leaf nodes in the dictionary + if (n.Nodes.IsEmpty()) + { + uint eid = (uint)n["EID"]; + + if (times.ContainsKey(eid)) + duration = times[eid][0].value.d; + else + duration = -1.0; + + n["Duration"] = duration; + + return; + } + + for (int i = 0; i < n.Nodes.Count; i++) + { + SetDrawcallTimes(n.Nodes[i], times); + + double nd = (double)n.Nodes[i]["Duration"]; + + if(nd > 0.0) + duration += nd; + } + + n["Duration"] = duration; + } + + private void AddFrameDrawcalls(TreelistView.Node frame, FetchDrawcall[] drawcalls) { eventView.BeginUpdate(); @@ -318,23 +340,11 @@ namespace renderdocui.Windows startEv.frameID = m_Core.CurFrame; startEv.eventID = 0; - if(frame.Nodes.Count == 0) - frame.Nodes.Add(MakeNode(0, 0, "Frame Start", -1.0)).Tag = startEv; + frame.Nodes.Clear(); + frame.Nodes.Add(MakeNode(0, 0, "Frame Start", -1.0)).Tag = startEv; for (int i = 0; i < drawcalls.Length; i++) - { - TreelistView.Node d = frame.Nodes.Count > (i + 1) ? frame.Nodes[i + 1] : null; - - TreelistView.Node newD = AddDrawcall(d, drawcalls[i], frame, times); - - if (newD != null) - { - d = newD; - - if ((double)d["Duration"] > 0.0) - frame["Duration"] = Math.Max(0.0, (double)frame["Duration"]) + (double)d["Duration"]; - } - } + AddDrawcall(drawcalls[i], frame); frame.Tag = frame.Nodes.LastNode.Tag; @@ -377,7 +387,7 @@ namespace renderdocui.Windows eventView.EndUpdate(); for (int curFrame = 0; curFrame < frameList.Length; curFrame++) - AddFrameDrawcalls(m_FrameNodes[curFrame], m_Core.GetDrawcalls((UInt32)curFrame), null); + AddFrameDrawcalls(m_FrameNodes[curFrame], m_Core.GetDrawcalls((UInt32)curFrame)); if (frameList.Length > 0) { @@ -704,8 +714,12 @@ namespace renderdocui.Windows eventView.Columns.SetVisibleIndex(col, eventView.Columns.VisibleColumns.Length); } + eventView.BeginUpdate(); + for (int curFrame = 0; curFrame < m_FrameNodes.Count; curFrame++) - AddFrameDrawcalls(m_FrameNodes[curFrame], m_Core.GetDrawcalls((UInt32)curFrame), times[curFrame]); + SetDrawcallTimes(m_FrameNodes[curFrame], times[curFrame]); + + eventView.EndUpdate(); }); }); }