コード例 #1
0
ファイル: TimelineBar.cs プロジェクト: loosche/renderdoc
        private FetchDrawcall FindDraw(Point p)
        {
            FetchDrawcall left   = null;
            FetchDrawcall right  = null;
            float         dleft  = -1.0f;
            float         dright = -1.0f;
            bool          uleft  = false;
            bool          uright = false;

            FindDraw(p, m_Root, ref left, ref dleft, ref uleft, ref right, ref dright, ref uright);

            if (left == null)
            {
                return(right);
            }
            if (right == null)
            {
                return(left);
            }

            if (Math.Abs(p.X - dleft) < Math.Abs(p.X - dright))
            {
                return(left);
            }
            else
            {
                return(right);
            }
        }
コード例 #2
0
        private void CountContributingEvents(FetchDrawcall draw, ref uint drawCount, ref uint dispatchCount, ref uint diagnosticCount)
        {
            const uint diagnosticMask   = (uint)DrawcallFlags.SetMarker | (uint)DrawcallFlags.PushMarker | (uint)DrawcallFlags.PopMarker;
            uint       diagnosticMasked = (uint)draw.flags & diagnosticMask;

            if (diagnosticMasked != 0)
            {
                diagnosticCount += 1;
            }

            if ((draw.flags & DrawcallFlags.Drawcall) != 0)
            {
                drawCount += 1;
            }

            if ((draw.flags & DrawcallFlags.Dispatch) != 0)
            {
                dispatchCount += 1;
            }

            if (draw.children != null)
            {
                foreach (var c in draw.children)
                {
                    CountContributingEvents(c, ref drawCount, ref dispatchCount, ref diagnosticCount);
                }
            }
        }
コード例 #3
0
        private void prevDraw_Click(object sender, EventArgs e)
        {
            FetchDrawcall draw = m_Core.CurDrawcall;

            if (draw != null && draw.previous != null)
            {
                SelectEvent(draw.previous.eventID);
            }
        }
コード例 #4
0
        private void nextDraw_Click(object sender, EventArgs e)
        {
            FetchDrawcall draw = m_Core.CurDrawcall;

            if (draw != null && draw.next != null)
            {
                SelectEvent(draw.next.eventID);
            }
        }
コード例 #5
0
        private uint GetEndDrawID(FetchDrawcall drawcall)
        {
            if (drawcall.children.Length == 0)
            {
                return(drawcall.drawcallID);
            }

            return(GetEndDrawID(drawcall.children.Last()));
        }
コード例 #6
0
        private string GetExportDrawcallString(int indent, bool firstchild, FetchDrawcall drawcall)
        {
            string prefix = new string(' ', indent * 2 - (firstchild ? 1 : 0));

            if (firstchild)
            {
                prefix += '\\';
            }

            return(String.Format("{0}- {1}", prefix, drawcall.name));
        }
コード例 #7
0
ファイル: APIInspector.cs プロジェクト: loosche/renderdoc
        public void FillAPIView()
        {
            apiEvents.BeginUpdate();
            apiEvents.Nodes.Clear();

            Regex  rgx         = new Regex("^\\s*[{}]?");
            string replacement = "";

            FetchDrawcall draw = m_Core.CurDrawcall;

            if (draw != null && draw.events != null && draw.events.Length > 0)
            {
                foreach (var ev in draw.events)
                {
                    // hack until I have a proper interface. Skip events associated with this draw that
                    // come from another context (means they will just be completely omitted/invisible).
                    if (ev.context != draw.context)
                    {
                        continue;
                    }

                    string[] lines = ev.eventDesc.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);

                    TreelistView.Node node = apiEvents.Nodes.Add(new TreelistView.Node(new object[] { ev.eventID, lines[0] }));

                    for (int i = 1; i < lines.Length; i++)
                    {
                        string l = rgx.Replace(lines[i], replacement);
                        if (l.Length > 0)
                        {
                            node.Nodes.Add(new TreelistView.Node(new object[] { "", l }));
                        }
                    }

                    if (ev.eventID == draw.eventID)
                    {
                        node.Bold = true;
                    }

                    node.Tag = (object)ev;
                }

                if (apiEvents.Nodes.Count > 0)
                {
                    apiEvents.NodesSelection.Add(apiEvents.Nodes[0]);
                }
            }

            apiEvents.EndUpdate();
        }
コード例 #8
0
        private void prevDraw_Click(object sender, EventArgs e)
        {
            FetchDrawcall draw = m_Core.CurDrawcall;

            if (draw != null && draw.eventID == 0)
            {
                FetchDrawcall d = m_Core.CurDrawcall;
                while (d.next != null)
                {
                    SelectEvent(draw.next.eventID);
                    string FileName = "C:\\Users\\zhlin\\Desktop\\rdump\\" + d.drawcallID + ".png";
                    m_Core.GetTextureViewer().saveTex_auto(FileName);
                }
            }

            if (draw != null && draw.previous != null)
            {
                SelectEvent(draw.previous.eventID);
            }
        }
コード例 #9
0
        private double GetDrawTime(FetchDrawcall drawcall)
        {
            if (drawcall.children.Length > 0)
            {
                double total = 0.0;

                foreach (FetchDrawcall c in drawcall.children)
                {
                    double f = GetDrawTime(c);
                    if (f >= 0)
                    {
                        total += f;
                    }
                }

                return(total);
            }
            else if (m_Times.ContainsKey(drawcall.eventID))
            {
                return(m_Times[drawcall.eventID][0].value.d);
            }

            return(-1.0);
        }
コード例 #10
0
        private void eventView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            prevDraw.Enabled = false;
            nextDraw.Enabled = false;

            if (eventView.SelectedNode.Tag != null)
            {
                DeferredEvent def = eventView.SelectedNode.Tag as DeferredEvent;
                m_Core.SetEventID(this, def.eventID);

                FetchDrawcall draw = m_Core.CurDrawcall;

                if (draw != null && draw.previous != null)
                {
                    prevDraw.Enabled = true;
                }
                if (draw != null && draw.next != null)
                {
                    nextDraw.Enabled = true;
                }
            }

            HighlightBookmarks();
        }
コード例 #11
0
        private TreelistView.Node AddDrawcall(FetchDrawcall drawcall, TreelistView.Node root)
        {
            if (m_Core.Config.EventBrowser_HideEmpty)
            {
                if ((drawcall.children == null || drawcall.children.Length == 0) && (drawcall.flags & DrawcallFlags.PushMarker) != 0)
                {
                    return(null);
                }
            }

            UInt32 eventNum = drawcall.eventID;

            TreelistView.Node drawNode = null;

            if (drawcall.children.Length > 0)
            {
                drawNode = MakeNode(eventNum, GetEndEventID(drawcall), drawcall.drawcallID, GetEndDrawID(drawcall), drawcall.name, 0.0);
            }
            else
            {
                drawNode = MakeNode(eventNum, drawcall.drawcallID, drawcall.name, 0.0);
            }

            if (m_Core.Config.EventBrowser_ApplyColours)
            {
                // if alpha isn't 0, assume the colour is valid
                if ((drawcall.flags & (DrawcallFlags.PushMarker | DrawcallFlags.SetMarker)) > 0 && drawcall.markerColour[3] > 0.0f)
                {
                    float red   = drawcall.markerColour[0];
                    float green = drawcall.markerColour[1];
                    float blue  = drawcall.markerColour[2];
                    float alpha = drawcall.markerColour[3];

                    drawNode.TreeLineColor = drawcall.GetColor();
                    drawNode.TreeLineWidth = 3.0f;

                    if (m_Core.Config.EventBrowser_ColourEventRow)
                    {
                        drawNode.BackColor = drawcall.GetColor();
                        drawNode.ForeColor = drawcall.GetTextColor(eventView.ForeColor);
                    }
                }
            }

            DeferredEvent def = new DeferredEvent();

            def.eventID = eventNum;
            def.marker  = (drawcall.flags & DrawcallFlags.SetMarker) != 0;

            drawNode.Tag = def;

            if (drawcall.children != null && drawcall.children.Length > 0)
            {
                for (int i = 0; i < drawcall.children.Length; i++)
                {
                    AddDrawcall(drawcall.children[i], drawNode);

                    if (i > 0 && drawNode.Nodes.Count >= 2 &&
                        (drawcall.children[i - 1].flags & DrawcallFlags.SetMarker) > 0)
                    {
                        drawNode.Nodes[drawNode.Nodes.Count - 2].Tag = drawNode.Nodes.LastNode.Tag;
                    }
                }

                bool found = false;

                for (int i = drawNode.Nodes.Count - 1; i >= 0; i--)
                {
                    DeferredEvent t = drawNode.Nodes[i].Tag as DeferredEvent;
                    if (t != null && !t.marker)
                    {
                        drawNode.Tag = drawNode.Nodes[i].Tag;
                        found        = true;
                        break;
                    }
                }

                if (!found && !drawNode.Nodes.IsEmpty())
                {
                    drawNode.Tag = drawNode.Nodes.LastNode.Tag;
                }
            }

            if (drawNode.Nodes.IsEmpty() && (drawcall.flags & DrawcallFlags.PushMarker) != 0 && m_Core.Config.EventBrowser_HideEmpty)
            {
                return(null);
            }

            root.Nodes.Add(drawNode);

            return(drawNode);
        }
コード例 #12
0
        public void FillAPIView()
        {
            apiEvents.BeginUpdate();
            apiEvents.Nodes.Clear();

            Regex rgxopen  = new Regex("^\\s*{");
            Regex rgxclose = new Regex("^\\s*}");

            FetchDrawcall draw = m_Core.CurDrawcall;

            if (draw != null && draw.events != null && draw.events.Length > 0)
            {
                foreach (var ev in draw.events)
                {
                    // hack until I have a proper interface. Skip events associated with this draw that
                    // come from another context (means they will just be completely omitted/invisible).
                    if (ev.context != draw.context)
                    {
                        continue;
                    }

                    string[] lines = ev.eventDesc.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);

                    TreelistView.Node root = new TreelistView.Node(new object[] { ev.eventID, lines[0] });

                    int i = 1;

                    if (i < lines.Length && lines[i].Trim() == "{")
                    {
                        i++;
                    }

                    List <TreelistView.Node> nodestack = new List <TreelistView.Node>();
                    nodestack.Add(root);

                    for (; i < lines.Length; i++)
                    {
                        if (rgxopen.IsMatch(lines[i]))
                        {
                            nodestack.Add(nodestack.Last().Nodes.LastNode);
                        }
                        else if (rgxclose.IsMatch(lines[i]))
                        {
                            nodestack.RemoveAt(nodestack.Count - 1);
                        }
                        else if (lines[i].Trim().Length > 0 && nodestack.Count > 0)
                        {
                            nodestack.Last().Nodes.Add(new TreelistView.Node(new object[] { "", lines[i].Trim() }));
                        }
                    }

                    if (ev.eventID == draw.eventID)
                    {
                        root.Bold = true;
                    }

                    root.Tag = (object)ev;

                    apiEvents.Nodes.Add(root);
                }

                if (apiEvents.Nodes.Count > 0)
                {
                    apiEvents.NodesSelection.Add(apiEvents.Nodes[0]);
                }
            }

            apiEvents.EndUpdate();
        }
コード例 #13
0
        private void ExportDrawcall(StreamWriter sw, int maxNameLength, int indent, bool firstchild, FetchDrawcall drawcall)
        {
            string eidString = drawcall.children.Length > 0 ? "" : drawcall.eventID.ToString();

            string nameString = GetExportDrawcallString(indent, firstchild, drawcall);

            sw.WriteLine(String.Format("{0,-5} | {1,-" + maxNameLength + "} | {2,-5}", eidString, nameString, drawcall.drawcallID));

            for (int i = 0; i < drawcall.children.Length; i++)
            {
                ExportDrawcall(sw, maxNameLength, indent + 1, i == 0, drawcall.children[i]);
            }
        }
コード例 #14
0
        private void GetMaxNameLength(ref int maxNameLength, int indent, bool firstchild, FetchDrawcall drawcall)
        {
            string nameString = GetExportDrawcallString(indent, firstchild, drawcall);

            maxNameLength = Math.Max(maxNameLength, nameString.Length);

            for (int i = 0; i < drawcall.children.Length; i++)
            {
                GetMaxNameLength(ref maxNameLength, indent + 1, i == 0, drawcall.children[i]);
            }
        }
コード例 #15
0
        private TreelistView.Node AddDrawcall(TreelistView.Node existing, FetchDrawcall drawcall, TreelistView.Node root)
        {
            if (m_Core.Config.EventBrowser_HideEmpty)
            {
                if ((drawcall.children == null || drawcall.children.Length == 0) && (drawcall.flags & DrawcallFlags.PushMarker) != 0)
                {
                    return(null);
                }
            }

            UInt32 eventNum = drawcall.eventID;
            double duration = drawcall.duration;

            TreelistView.Node drawNode = MakeNode(eventNum, drawcall.drawcallID, drawcall.name, duration);

            if (existing != null)
            {
                existing.SetData(drawNode.GetData());
                drawNode = existing;
            }
            else
            {
                root.Nodes.Add(drawNode);
            }

            DeferredEvent def = new DeferredEvent();

            def.frameID = m_Core.CurFrame;
            def.eventID = eventNum;

            if (drawcall.context != m_Core.FrameInfo[m_Core.CurFrame].immContextId)
            {
                def.defCtx    = drawcall.context;
                def.lastDefEv = drawcall.eventID;

                FetchDrawcall parent = drawcall.parent;
                while (!parent.name.Contains("ExecuteCommand"))
                {
                    parent = parent.parent;
                }

                def.eventID = parent.eventID - 1;

                def.firstDefEv = parent.children[0].eventID;
                if (parent.children[0].events.Length > 0)
                {
                    def.firstDefEv = parent.children[0].events[0].eventID;
                }
            }

            drawNode.Tag = def;

            if (drawcall.children != null && drawcall.children.Length > 0)
            {
                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);

                    if (i > 0 && (drawcall.children[i - 1].flags & DrawcallFlags.SetMarker) > 0)
                    {
                        drawNode.Nodes[drawNode.Nodes.Count - 2].Tag = drawNode.Nodes.LastNode.Tag;
                    }

                    if ((double)drawNode.Nodes[i]["Duration"] > 0.0)
                    {
                        drawNode["Duration"] = Math.Max(0.0, (double)drawNode["Duration"]) + (double)drawNode.Nodes[i]["Duration"];
                    }
                }

                drawNode.Tag = drawNode.Nodes.LastNode.Tag;
            }

            return(drawNode);
        }
コード例 #16
0
        private TreelistView.Node AddDrawcall(FetchDrawcall drawcall, TreelistView.Node root)
        {
            if (m_Core.Config.EventBrowser_HideEmpty)
            {
                if ((drawcall.children == null || drawcall.children.Length == 0) && (drawcall.flags & DrawcallFlags.PushMarker) != 0)
                {
                    return(null);
                }
            }

            UInt32 eventNum = drawcall.eventID;

            TreelistView.Node drawNode = null;

            if (drawcall.children.Length > 0)
            {
                drawNode = MakeNode(eventNum, GetEndEventID(drawcall), drawcall.drawcallID, drawcall.name, 0.0);
            }
            else
            {
                drawNode = MakeNode(eventNum, drawcall.drawcallID, drawcall.name, 0.0);
            }

            DeferredEvent def = new DeferredEvent();

            def.eventID = eventNum;
            def.marker  = (drawcall.flags & DrawcallFlags.SetMarker) != 0;

            if (drawcall.context != m_Core.FrameInfo.immContextId)
            {
                def.defCtx    = drawcall.context;
                def.lastDefEv = drawcall.eventID;

                FetchDrawcall parent = drawcall.parent;
                while (!parent.name.Contains("ExecuteCommand"))
                {
                    parent = parent.parent;
                }

                def.eventID = parent.eventID - 1;

                def.firstDefEv = parent.children[0].eventID;
                if (parent.children[0].events.Length > 0)
                {
                    def.firstDefEv = parent.children[0].events[0].eventID;
                }
            }

            drawNode.Tag = def;

            if (drawcall.children != null && drawcall.children.Length > 0)
            {
                for (int i = 0; i < drawcall.children.Length; i++)
                {
                    AddDrawcall(drawcall.children[i], drawNode);

                    if (i > 0 && drawNode.Nodes.Count >= 2 &&
                        (drawcall.children[i - 1].flags & DrawcallFlags.SetMarker) > 0)
                    {
                        drawNode.Nodes[drawNode.Nodes.Count - 2].Tag = drawNode.Nodes.LastNode.Tag;
                    }
                }

                bool found = false;

                for (int i = drawNode.Nodes.Count - 1; i >= 0; i--)
                {
                    DeferredEvent t = drawNode.Nodes[i].Tag as DeferredEvent;
                    if (t != null && !t.marker)
                    {
                        drawNode.Tag = drawNode.Nodes[i].Tag;
                        found        = true;
                        break;
                    }
                }

                if (!found && !drawNode.Nodes.IsEmpty())
                {
                    drawNode.Tag = drawNode.Nodes.LastNode.Tag;
                }
            }

            if (drawNode.Nodes.IsEmpty() && (drawcall.flags & DrawcallFlags.PushMarker) != 0 && m_Core.Config.EventBrowser_HideEmpty)
            {
                return(null);
            }

            root.Nodes.Add(drawNode);

            return(drawNode);
        }
コード例 #17
0
ファイル: APIInspector.cs プロジェクト: hackerlank/renderdoc
        public void FillAPIView()
        {
            apiEvents.BeginUpdate();
            apiEvents.Nodes.Clear();

            Regex rgxopen  = new Regex("^\\s*{");
            Regex rgxclose = new Regex("^\\s*}");

            FetchDrawcall draw = m_Core.CurDrawcall;

            if (draw != null && draw.events != null && draw.events.Length > 0)
            {
                foreach (var ev in draw.events)
                {
                    string[] lines = ev.eventDesc.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);

                    TreelistView.Node root = new TreelistView.Node(new object[] { ev.eventID, lines[0] });

                    int i = 1;

                    if (i < lines.Length && lines[i].Trim() == "{")
                    {
                        i++;
                    }

                    List <TreelistView.Node> nodestack = new List <TreelistView.Node>();
                    nodestack.Add(root);

                    for (; i < lines.Length; i++)
                    {
                        if (rgxopen.IsMatch(lines[i]))
                        {
                            nodestack.Add(nodestack.Last().Nodes.LastNode);
                        }
                        else if (rgxclose.IsMatch(lines[i]))
                        {
                            nodestack.RemoveAt(nodestack.Count - 1);
                        }
                        else if (lines[i].Trim().Length > 0 && nodestack.Count > 0)
                        {
                            nodestack.Last().Nodes.Add(new TreelistView.Node(new object[] { "", lines[i].Trim() }));
                        }
                    }

                    if (ev.eventID == draw.eventID)
                    {
                        root.Bold = true;
                    }

                    root.Tag = (object)ev;

                    apiEvents.Nodes.Add(root);
                }

                if (apiEvents.Nodes.Count > 0)
                {
                    apiEvents.NodesSelection.Add(apiEvents.Nodes[0]);
                }
            }

            apiEvents.EndUpdate();
        }
コード例 #18
0
ファイル: Core.cs プロジェクト: UIKit0/renderdoc
        // used to determine if two drawcalls can be considered in the same 'pass',
        // ie. writing to similar targets, same type of call, etc.
        //
        // When a log has no markers, this is used to group up drawcalls into fake markers
        private bool PassEquivalent(FetchDrawcall a, FetchDrawcall b)
        {
            // executing command lists can have children
            if (a.children.Length > 0 || b.children.Length > 0)
            {
                return(false);
            }

            // don't group draws and compute executes
            if ((a.flags & DrawcallFlags.Dispatch) != (b.flags & DrawcallFlags.Dispatch))
            {
                return(false);
            }

            // don't group things run on different multithreaded contexts
            if (a.context != b.context)
            {
                return(false);
            }

            // don't group things with different depth outputs
            if (a.depthOut != b.depthOut)
            {
                return(false);
            }

            int numAOuts = 0, numBOuts = 0;

            for (int i = 0; i < 8; i++)
            {
                if (a.outputs[i] != ResourceId.Null)
                {
                    numAOuts++;
                }
                if (b.outputs[i] != ResourceId.Null)
                {
                    numBOuts++;
                }
            }

            int numSame = 0;

            if (a.depthOut != ResourceId.Null)
            {
                numAOuts++;
                numBOuts++;
                numSame++;
            }

            for (int i = 0; i < 8; i++)
            {
                if (a.outputs[i] != ResourceId.Null)
                {
                    for (int j = 0; j < 8; j++)
                    {
                        if (a.outputs[i] == b.outputs[j])
                        {
                            numSame++;
                            break;
                        }
                    }
                }
                else if (b.outputs[i] != ResourceId.Null)
                {
                    for (int j = 0; j < 8; j++)
                    {
                        if (a.outputs[j] == b.outputs[i])
                        {
                            numSame++;
                            break;
                        }
                    }
                }
            }

            // use a kind of heuristic to group together passes where the outputs are similar enough.
            // could be useful for example if you're rendering to a gbuffer and sometimes you render
            // without one target, but the draws are still batched up.
            if (numSame > Math.Max(numAOuts, numBOuts) / 2 && Math.Max(numAOuts, numBOuts) > 1)
            {
                return(true);
            }

            if (numSame == Math.Max(numAOuts, numBOuts))
            {
                return(true);
            }

            return(false);
        }
コード例 #19
0
ファイル: Core.cs プロジェクト: trs-jimmy-lee/renderdoc
        // if a log doesn't contain any markers specified at all by the user, then we can
        // fake some up by determining batches of draws that are similar and giving them a
        // pass number
        private FetchDrawcall[] FakeProfileMarkers(FetchDrawcall[] draws)
        {
            if (Config.EventBrowser_AddFake == false)
            {
                return(draws);
            }

            if (ContainsMarker(draws))
            {
                return(draws);
            }

            var ret = new List <FetchDrawcall>();

            int depthpassID   = 1;
            int computepassID = 1;
            int passID        = 1;

            int start   = 0;
            int refdraw = 0;

            for (int i = 1; i < draws.Length; i++)
            {
                if ((draws[refdraw].flags & (DrawcallFlags.Copy | DrawcallFlags.Resolve | DrawcallFlags.SetMarker | DrawcallFlags.CmdList)) > 0)
                {
                    refdraw = i;
                    continue;
                }

                if ((draws[i].flags & (DrawcallFlags.Copy | DrawcallFlags.Resolve | DrawcallFlags.SetMarker | DrawcallFlags.CmdList)) > 0)
                {
                    continue;
                }

                if (PassEquivalent(draws[i], draws[refdraw]))
                {
                    continue;
                }

                int end = i - 1;

                if (end - start < 2 ||
                    draws[i].children.Length > 0 || draws[refdraw].children.Length > 0)
                {
                    for (int j = start; j <= end; j++)
                    {
                        ret.Add(draws[j]);
                    }

                    start   = i;
                    refdraw = i;
                    continue;
                }

                int minOutCount = 100;
                int maxOutCount = 0;

                for (int j = start; j <= end; j++)
                {
                    int outCount = 0;
                    foreach (var o in draws[j].outputs)
                    {
                        if (o != ResourceId.Null)
                        {
                            outCount++;
                        }
                    }
                    minOutCount = Math.Min(minOutCount, outCount);
                    maxOutCount = Math.Max(maxOutCount, outCount);
                }

                FetchDrawcall mark = new FetchDrawcall();

                mark.eventID      = draws[start].eventID;
                mark.drawcallID   = draws[start].drawcallID;
                mark.markerColour = new float[] { 0.0f, 0.0f, 0.0f, 0.0f };

                mark.flags    = DrawcallFlags.PushMarker;
                mark.outputs  = draws[end].outputs;
                mark.depthOut = draws[end].depthOut;

                mark.name = "Guessed Pass";

                minOutCount = Math.Max(1, minOutCount);

                if ((draws[refdraw].flags & DrawcallFlags.Dispatch) != 0)
                {
                    mark.name = String.Format("Compute Pass #{0}", computepassID++);
                }
                else if (maxOutCount == 0)
                {
                    mark.name = String.Format("Depth-only Pass #{0}", depthpassID++);
                }
                else if (minOutCount == maxOutCount)
                {
                    mark.name = String.Format("Colour Pass #{0} ({1} Targets{2})", passID++, minOutCount, draws[end].depthOut == ResourceId.Null ? "" : " + Depth");
                }
                else
                {
                    mark.name = String.Format("Colour Pass #{0} ({1}-{2} Targets{3})", passID++, minOutCount, maxOutCount, draws[end].depthOut == ResourceId.Null ? "" : " + Depth");
                }

                mark.children = new FetchDrawcall[end - start + 1];

                for (int j = start; j <= end; j++)
                {
                    mark.children[j - start] = draws[j];
                    draws[j].parent          = mark;
                }

                ret.Add(mark);

                start   = i;
                refdraw = i;
            }

            if (start < draws.Length)
            {
                for (int j = start; j < draws.Length; j++)
                {
                    ret.Add(draws[j]);
                }
            }

            return(ret.ToArray());
        }
コード例 #20
0
ファイル: TimelineBar.cs プロジェクト: loosche/renderdoc
        private void FindDraw(Point p, Section s,
                              ref FetchDrawcall left, ref float dleft, ref bool uleft,
                              ref FetchDrawcall right, ref float dright, ref bool uright)
        {
            if (s == null)
            {
                return;
            }

            var rect = s.lastRect;

            rect.Y      = 0;
            rect.Height = 10000;

            if (s.subsections != null)
            {
                foreach (var sub in s.subsections)
                {
                    FindDraw(p, sub, ref left, ref dleft, ref uleft, ref right, ref dright, ref uright);

                    if (left != null && right != null)
                    {
                        return;
                    }
                }
            }

            if (rect.Contains(p))
            {
                if (s.draws == null || s.draws.Count == 0)
                {
                    return;
                }

                for (int i = 0; i < s.lastPoss.Count; i++)
                {
                    if (s.lastVisible[i])
                    {
                        if (s.lastPoss[i] <= p.X)
                        {
                            if (
                                // not found left
                                left == null ||
                                // this left is closer and as usage-y, or we don't have a usage-y one yet
                                (s.lastPoss[i] > dleft && s.lastUsage[i] == uleft) ||
                                // this left is WAY closer
                                (s.lastPoss[i] > dleft + 20.0f) ||
                                // this left is more usage-y
                                (s.lastUsage[i] && !uleft)
                                )
                            {
                                dleft = s.lastPoss[i];
                                uleft = s.lastUsage[i];
                                left  = s.draws[i];
                            }
                        }

                        if (s.lastPoss[i] > p.X)
                        {
                            if (
                                // not found right
                                right == null ||
                                // this right is closer and as usage-y, or we don't have a usage-y one yet
                                (s.lastPoss[i] < dright && s.lastUsage[i] == uright) ||
                                // this right is WAY closer
                                (s.lastPoss[i] < dright - 20.0f) ||
                                // this right is more usage-y
                                (s.lastUsage[i] && !uright)
                                )
                            {
                                dright = s.lastPoss[i];
                                uright = s.lastUsage[i];
                                right  = s.draws[i];
                            }
                        }
                    }
                }

                if (left != null && right != null)
                {
                    return;
                }
            }
        }
コード例 #21
0
        private void UpdateState()
        {
            if (!m_Core.LogLoaded)
            {
                return;
            }

            FetchTexture[]  texs  = m_Core.CurTextures;
            FetchBuffer[]   bufs  = m_Core.CurBuffers;
            GLPipelineState state = m_Core.CurGLPipelineState;
            FetchDrawcall   draw  = m_Core.CurDrawcall;

            var tick  = global::renderdocui.Properties.Resources.tick;
            var cross = global::renderdocui.Properties.Resources.cross;

            bool[] usedVBuffers = new bool[128];

            for (int i = 0; i < 128; i++)
            {
                usedVBuffers[i] = false;
            }

            ////////////////////////////////////////////////
            // Input Assembler

            inputLayouts.Nodes.Clear();
            inputLayouts.BeginUpdate();
            if (state.m_VtxIn.attributes != null)
            {
                int i = 0;
                foreach (var l in state.m_VtxIn.attributes)
                {
                    if (l.Enabled || showDisabled.Checked)
                    {
                        string byteOffs = l.RelativeOffset.ToString();

                        var node = inputLayouts.Nodes.Add(new object[] {
                            i, l.Enabled ? "Enabled" : "Disabled", "", l.Format, l.BufferSlot.ToString(), byteOffs,
                            "", ""
                        });

                        usedVBuffers[l.BufferSlot] = true;

                        node.Image      = global::renderdocui.Properties.Resources.action;
                        node.HoverImage = global::renderdocui.Properties.Resources.action_hover;

                        if (!l.Enabled)
                        {
                            InactiveRow(node);
                        }
                    }

                    i++;
                }
            }
            inputLayouts.NodesSelection.Clear();
            inputLayouts.EndUpdate();

            topology.Text = state.m_VtxIn.Topology.ToString();
            if (state.m_VtxIn.Topology > PrimitiveTopology.PatchList)
            {
                int numCPs = (int)state.m_VtxIn.Topology - (int)PrimitiveTopology.PatchList + 1;

                topology.Text = string.Format("PatchList ({0} Control Points)", numCPs);
            }

            switch (state.m_VtxIn.Topology)
            {
            case PrimitiveTopology.PointList:
                topologyDiagram.Image = global::renderdocui.Properties.Resources.topo_pointlist;
                break;

            case PrimitiveTopology.LineList:
                topologyDiagram.Image = global::renderdocui.Properties.Resources.topo_linelist;
                break;

            case PrimitiveTopology.LineStrip:
                topologyDiagram.Image = global::renderdocui.Properties.Resources.topo_linestrip;
                break;

            case PrimitiveTopology.TriangleList:
                topologyDiagram.Image = global::renderdocui.Properties.Resources.topo_trilist;
                break;

            case PrimitiveTopology.TriangleStrip:
                topologyDiagram.Image = global::renderdocui.Properties.Resources.topo_tristrip;
                break;

            case PrimitiveTopology.LineList_Adj:
                topologyDiagram.Image = global::renderdocui.Properties.Resources.topo_linelist_adj;
                break;

            case PrimitiveTopology.LineStrip_Adj:
                topologyDiagram.Image = global::renderdocui.Properties.Resources.topo_linestrip_adj;
                break;

            case PrimitiveTopology.TriangleList_Adj:
                topologyDiagram.Image = global::renderdocui.Properties.Resources.topo_trilist_adj;
                break;

            case PrimitiveTopology.TriangleStrip_Adj:
                topologyDiagram.Image = global::renderdocui.Properties.Resources.topo_tristrip_adj;
                break;

            default:
                topologyDiagram.Image = global::renderdocui.Properties.Resources.topo_patch;
                break;
            }

            iabuffers.Nodes.Clear();
            iabuffers.BeginUpdate();

            bool ibufferUsed = draw != null && (draw.flags & DrawcallFlags.UseIBuffer) != 0;

            if (state.m_VtxIn.ibuffer != null)
            {
                if (ibufferUsed || showDisabled.Checked)
                {
                    string ptr    = "Buffer " + state.m_VtxIn.ibuffer.Buffer.ToString();
                    string name   = ptr;
                    UInt32 length = 1;

                    if (!ibufferUsed)
                    {
                        length = 0;
                    }

                    for (int t = 0; t < bufs.Length; t++)
                    {
                        if (bufs[t].ID == state.m_VtxIn.ibuffer.Buffer)
                        {
                            name   = bufs[t].name;
                            length = bufs[t].length;
                        }
                    }

                    var node = iabuffers.Nodes.Add(new object[] { "Index", name, state.m_VtxIn.ibuffer.Format.compByteWidth, state.m_VtxIn.ibuffer.Offset, length });

                    node.Image      = global::renderdocui.Properties.Resources.action;
                    node.HoverImage = global::renderdocui.Properties.Resources.action_hover;
                    node.Tag        = state.m_VtxIn.ibuffer.Buffer;

                    if (!ibufferUsed)
                    {
                        InactiveRow(node);
                    }

                    if (state.m_VtxIn.ibuffer.Buffer == ResourceId.Null)
                    {
                        EmptyRow(node);
                    }
                }
            }
            else
            {
                if (showEmpty.Checked &&
                    (ibufferUsed || showDisabled.Checked))
                {
                    var node = iabuffers.Nodes.Add(new object[] { "Index", "-", "-", "-", "-" });

                    node.Image      = global::renderdocui.Properties.Resources.action;
                    node.HoverImage = global::renderdocui.Properties.Resources.action_hover;
                    node.Tag        = state.m_VtxIn.ibuffer.Buffer;

                    EmptyRow(node);

                    if (!ibufferUsed)
                    {
                        InactiveRow(node);
                    }
                }
            }

            m_VBNodes.Clear();

            if (state.m_VtxIn.vbuffers != null)
            {
                int i = 0;
                foreach (var v in state.m_VtxIn.vbuffers)
                {
                    bool filledSlot = (v.Buffer != ResourceId.Null);
                    bool usedSlot   = (usedVBuffers[i]);

                    // show if
                    if (usedSlot ||                                          // it's referenced by the shader - regardless of empty or not
                        (showDisabled.Checked && !usedSlot && filledSlot) || // it's bound, but not referenced, and we have "show disabled"
                        (showEmpty.Checked && !filledSlot)                   // it's empty, and we have "show empty"
                        )
                    {
                        string name   = "Buffer " + v.Buffer.ToString();
                        UInt32 length = 1;

                        if (!filledSlot)
                        {
                            name   = "Empty";
                            length = 0;
                        }

                        for (int t = 0; t < bufs.Length; t++)
                        {
                            if (bufs[t].ID == v.Buffer)
                            {
                                name   = bufs[t].name;
                                length = bufs[t].length;
                            }
                        }

                        var node = iabuffers.Nodes.Add(new object[] { i, name, v.Stride, v.Offset, length });

                        node.Image      = global::renderdocui.Properties.Resources.action;
                        node.HoverImage = global::renderdocui.Properties.Resources.action_hover;
                        node.Tag        = v.Buffer;

                        if (!filledSlot)
                        {
                            EmptyRow(node);
                        }

                        if (!usedSlot)
                        {
                            InactiveRow(node);
                        }

                        m_VBNodes.Add(node);
                    }

                    i++;
                }
            }
            iabuffers.NodesSelection.Clear();
            iabuffers.EndUpdate();

            SetShaderState(texs, bufs, state, state.m_VS, vsShader, vsResources, vsSamplers, vsCBuffers, vsClasses);
            SetShaderState(texs, bufs, state, state.m_GS, gsShader, gsResources, gsSamplers, gsCBuffers, gsClasses);
            SetShaderState(texs, bufs, state, state.m_TES, tesShader, tesResources, tesSamplers, tesCBuffers, tesClasses);
            SetShaderState(texs, bufs, state, state.m_TCS, tcsShader, tcsResources, tcsSamplers, tcsCBuffers, tcsClasses);
            SetShaderState(texs, bufs, state, state.m_FS, fsShader, fsResources, fsSamplers, fsCBuffers, fsClasses);
            SetShaderState(texs, bufs, state, state.m_CS, csShader, csResources, csSamplers, csCBuffers, csClasses);

            fsResources.BeginUpdate();
            fsResources.Nodes.Clear();
            if (state.Textures != null)
            {
                var shaderDetails = state.m_FS.ShaderDetails;
                var mapping       = state.m_FS.BindpointMapping;

                int i = 0;
                foreach (var r in state.Textures)
                {
                    ShaderResource shaderInput = null;
                    BindpointMap   map         = null;

                    if (shaderDetails != null)
                    {
                        foreach (var bind in shaderDetails.Resources)
                        {
                            if (bind.IsSRV && mapping.Resources[bind.bindPoint].bind == i)
                            {
                                shaderInput = bind;
                                map         = mapping.Resources[bind.bindPoint];
                            }
                        }
                    }

                    bool filledSlot = (r.Resource != ResourceId.Null);
                    bool usedSlot   = (shaderInput != null && map.used);

                    // show if
                    if (usedSlot ||                                          // it's referenced by the shader - regardless of empty or not
                        (showDisabled.Checked && !usedSlot && filledSlot) || // it's bound, but not referenced, and we have "show disabled"
                        (showEmpty.Checked && !filledSlot)                   // it's empty, and we have "show empty"
                        )
                    {
                        string slotname = i.ToString();

                        if (shaderInput != null && shaderInput.name != "")
                        {
                            slotname += ": " + shaderInput.name;
                        }

                        UInt32 w = 1, h = 1, d = 1;
                        UInt32 a        = 1;
                        string format   = "Unknown";
                        string name     = "Shader Resource " + r.Resource.ToString();
                        string typename = "Unknown";
                        object tag      = null;

                        if (!filledSlot)
                        {
                            name     = "Empty";
                            format   = "-";
                            typename = "-";
                            w        = h = d = a = 0;
                        }

                        // check to see if it's a texture
                        for (int t = 0; t < texs.Length; t++)
                        {
                            if (texs[t].ID == r.Resource)
                            {
                                w        = texs[t].width;
                                h        = texs[t].height;
                                d        = texs[t].depth;
                                a        = texs[t].arraysize;
                                format   = texs[t].format.ToString();
                                name     = texs[t].name;
                                typename = string.Format("Texture{0}D", texs[t].dimension);
                                if (texs[t].cubemap)
                                {
                                    typename = "TexCube";
                                }

                                tag = texs[t];
                            }
                        }

                        // if not a texture, it must be a buffer
                        for (int t = 0; t < bufs.Length; t++)
                        {
                            if (bufs[t].ID == r.Resource)
                            {
                                w        = bufs[t].length;
                                h        = 0;
                                d        = 0;
                                a        = 0;
                                format   = "";
                                name     = bufs[t].name;
                                typename = "Buffer";

                                // for structured buffers, display how many 'elements' there are in the buffer
                                if (bufs[t].structureSize > 0)
                                {
                                    typename = "StructuredBuffer[" + (bufs[t].length / bufs[t].structureSize) + "]";
                                }

                                tag = bufs[t];
                            }
                        }

                        var node = fsResources.Nodes.Add(new object[] { slotname, name, typename, w, h, d, a, format });

                        node.Image      = global::renderdocui.Properties.Resources.action;
                        node.HoverImage = global::renderdocui.Properties.Resources.action_hover;
                        node.Tag        = tag;

                        if (!filledSlot)
                        {
                            EmptyRow(node);
                        }

                        if (!usedSlot)
                        {
                            InactiveRow(node);
                        }
                    }
                    i++;
                }
            }
            fsResources.EndUpdate();
            fsResources.NodesSelection.Clear();

            csUAVs.Nodes.Clear();
            csUAVs.BeginUpdate();

            csUAVs.NodesSelection.Clear();
            csUAVs.EndUpdate();

            gsStreams.BeginUpdate();
            gsStreams.Nodes.Clear();
            gsStreams.EndUpdate();
            gsStreams.NodesSelection.Clear();

            ////////////////////////////////////////////////
            // Rasterizer

            viewports.BeginUpdate();
            viewports.Nodes.Clear();
            viewports.NodesSelection.Clear();
            viewports.EndUpdate();

            scissors.BeginUpdate();
            scissors.Nodes.Clear();
            scissors.NodesSelection.Clear();
            scissors.EndUpdate();

            ////////////////////////////////////////////////
            // Output Merger

            bool[] targets = new bool[8];

            for (int i = 0; i < 8; i++)
            {
                targets[i] = false;
            }

            targetOutputs.BeginUpdate();
            targetOutputs.Nodes.Clear();
            {
                int i = 0;
                foreach (var p in state.m_FB.Color)
                {
                    if (p != ResourceId.Null || showEmpty.Checked)
                    {
                        UInt32 w = 1, h = 1, d = 1;
                        UInt32 a        = 1;
                        string format   = "Unknown";
                        string name     = "Texture " + p.ToString();
                        string typename = "Unknown";
                        object tag      = null;

                        if (p == ResourceId.Null)
                        {
                            name     = "Empty";
                            format   = "-";
                            typename = "-";
                            w        = h = d = a = 0;
                        }

                        for (int t = 0; t < texs.Length; t++)
                        {
                            if (texs[t].ID == p)
                            {
                                w        = texs[t].width;
                                h        = texs[t].height;
                                d        = texs[t].depth;
                                a        = texs[t].arraysize;
                                format   = texs[t].format.ToString();
                                name     = texs[t].name;
                                typename = string.Format("Texture{0}D", texs[t].dimension);
                                if (texs[t].cubemap)
                                {
                                    typename = "TexCube";
                                }

                                tag = texs[t];
                            }
                        }

                        var node = targetOutputs.Nodes.Add(new object[] { i, name, typename, w, h, d, a, format });

                        node.Image      = global::renderdocui.Properties.Resources.action;
                        node.HoverImage = global::renderdocui.Properties.Resources.action_hover;
                        node.Tag        = tag;

                        if (p == ResourceId.Null)
                        {
                            EmptyRow(node);
                        }
                        else
                        {
                            targets[i] = true;
                        }
                    }

                    i++;
                }
            }

            {
                int i = 0;
                foreach (ResourceId depthstencil in new ResourceId[] { state.m_FB.Depth, state.m_FB.Stencil })
                {
                    if (depthstencil != ResourceId.Null || showEmpty.Checked)
                    {
                        UInt32 w = 1, h = 1, d = 1;
                        UInt32 a        = 1;
                        string format   = "Unknown";
                        string name     = "Depth Target " + depthstencil.ToString();
                        string typename = "Unknown";
                        object tag      = null;

                        if (depthstencil == ResourceId.Null)
                        {
                            name     = "Empty";
                            format   = "-";
                            typename = "-";
                            w        = h = d = a = 0;
                        }

                        for (int t = 0; t < texs.Length; t++)
                        {
                            if (texs[t].ID == depthstencil)
                            {
                                w        = texs[t].width;
                                h        = texs[t].height;
                                d        = texs[t].depth;
                                a        = texs[t].arraysize;
                                format   = texs[t].format.ToString();
                                name     = texs[t].name;
                                typename = string.Format("Texture{0}D", texs[t].dimension);
                                if (texs[t].cubemap)
                                {
                                    typename = "TexCube";
                                }

                                tag = texs[t];
                            }
                        }

                        string slot = "Depth";
                        if (i == 1)
                        {
                            slot = "Stencil";
                        }

                        var node = targetOutputs.Nodes.Add(new object[] { slot, name, typename, w, h, d, a, format });

                        node.Image      = global::renderdocui.Properties.Resources.action;
                        node.HoverImage = global::renderdocui.Properties.Resources.action_hover;
                        node.Tag        = tag;

                        if (depthstencil == ResourceId.Null)
                        {
                            EmptyRow(node);
                        }
                    }

                    i++;
                }
            }
            targetOutputs.EndUpdate();
            targetOutputs.NodesSelection.Clear();

            blendOperations.BeginUpdate();
            blendOperations.Nodes.Clear();
            blendOperations.NodesSelection.Clear();
            blendOperations.EndUpdate();

            stencilFuncs.BeginUpdate();
            stencilFuncs.Nodes.Clear();
            stencilFuncs.Nodes.Add(new object[] { "Front", "", "",
                                                  "", "" });
            stencilFuncs.Nodes.Add(new object[] { "Back", "", "",
                                                  "", "" });
            stencilFuncs.EndUpdate();
            stencilFuncs.NodesSelection.Clear();

            // highlight the appropriate stages in the flowchart
            if (draw == null)
            {
                pipeFlow.SetStagesEnabled(new bool[] { true, true, true, true, true, true, true, true, true });
            }
            else if ((draw.flags & DrawcallFlags.Dispatch) != 0)
            {
                pipeFlow.SetStagesEnabled(new bool[] { false, false, false, false, false, false, false, false, true });
            }
            else
            {
                pipeFlow.SetStagesEnabled(new bool[] {
                    true,
                    true,
                    state.m_TES.Shader != ResourceId.Null,
                    state.m_TCS.Shader != ResourceId.Null,
                    state.m_GS.Shader != ResourceId.Null,
                    true,
                    state.m_FS.Shader != ResourceId.Null,
                    true,
                    false
                });

                // if(streamout only)
                //{
                //    pipeFlow.Rasterizer = false;
                //    pipeFlow.OutputMerger = false;
                //}
            }
        }
コード例 #22
0
        private void ExportDrawcall(StreamWriter sw, int maxNameLength, int indent, bool firstchild, FetchDrawcall drawcall)
        {
            string eidString = drawcall.children.Length > 0 ? "" : drawcall.eventID.ToString();

            string nameString = GetExportDrawcallString(indent, firstchild, drawcall);

            string line = String.Format("{0,-5} | {1,-" + maxNameLength + "} | {2,-6}", eidString, nameString, drawcall.drawcallID);

            if (m_Times.Count > 0)
            {
                if (m_Core.Config.EventBrowser_TimeUnit != m_TimeUnit)
                {
                    UpdateDurationColumn();
                }

                double f = GetDrawTime(drawcall);

                if (f >= 0)
                {
                    if (m_Core.Config.EventBrowser_TimeUnit == PersistantConfig.TimeUnit.Milliseconds)
                    {
                        f *= 1000.0;
                    }
                    else if (m_Core.Config.EventBrowser_TimeUnit == PersistantConfig.TimeUnit.Microseconds)
                    {
                        f *= 1000000.0;
                    }
                    else if (m_Core.Config.EventBrowser_TimeUnit == PersistantConfig.TimeUnit.Nanoseconds)
                    {
                        f *= 1000000000.0;
                    }

                    line += String.Format(" | {0}", Formatter.Format(f));
                }
                else
                {
                    line += " |";
                }
            }

            sw.WriteLine(line);

            for (int i = 0; i < drawcall.children.Length; i++)
            {
                ExportDrawcall(sw, maxNameLength, indent + 1, i == 0, drawcall.children[i]);
            }
        }
コード例 #23
0
        private void export_Click(object sender, EventArgs e)
        {
            // Zhen: reuse export button to dump per-draw images in batch.
            FetchDrawcall draw = m_Core.CurDrawcall;

            if (draw != null && draw.eventID == 1)
            {
                FetchDrawcall d    = m_Core.CurDrawcall;
                string        path = Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.Desktop)).FullName;
                path += "\\Desktop\\RenderDocPerDrawImages\\";
                Directory.CreateDirectory(path);
                while (true)
                {
                    string FileName = path + d.drawcallID + ".png";
                    m_Core.GetTextureViewer().saveTex_auto(FileName);
                    if (d.next != null)
                    {
                        SelectEvent(d.next.eventID);
                        d = m_Core.CurDrawcall;
                    }
                    else
                    {
                        break;
                    }
                }

                return;
            }

            DialogResult res = exportDialog.ShowDialog();

            if (res == DialogResult.OK)
            {
                try
                {
                    using (Stream s = new FileStream(exportDialog.FileName, FileMode.Create))
                    {
                        StreamWriter sw = new StreamWriter(s);

                        sw.WriteLine(String.Format("{0} - Frame #{1}", m_Core.LogFileName, m_Core.FrameInfo.frameNumber));
                        sw.WriteLine("");

                        int maxNameLength = 0;

                        foreach (FetchDrawcall d in m_Core.GetDrawcalls())
                        {
                            GetMaxNameLength(ref maxNameLength, 0, false, d);
                        }

                        string line = String.Format(" EID  | {0,-" + maxNameLength + "} | Draw #", "Event");

                        if (m_Times.Count > 0)
                        {
                            if (m_Core.Config.EventBrowser_TimeUnit != m_TimeUnit)
                            {
                                UpdateDurationColumn();
                            }

                            line += String.Format(" | {0}", eventView.Columns["Duration"].Caption);
                        }

                        sw.WriteLine(line);

                        line = String.Format("--------{0}-----------", new string('-', maxNameLength));

                        if (m_Times.Count > 0)
                        {
                            int maxDurationLength = 0;
                            maxDurationLength = Math.Max(maxDurationLength, Formatter.Format(1.0).Length);
                            maxDurationLength = Math.Max(maxDurationLength, Formatter.Format(1.2345e-200).Length);
                            maxDurationLength = Math.Max(maxDurationLength, Formatter.Format(123456.7890123456789).Length);
                            line += new string('-', 3 + maxDurationLength); // 3 extra for " | "
                        }

                        sw.WriteLine(line);

                        foreach (FetchDrawcall d in m_Core.GetDrawcalls())
                        {
                            ExportDrawcall(sw, maxNameLength, 0, false, d);
                        }

                        sw.Dispose();
                    }
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show("Couldn't save to " + exportDialog.FileName + Environment.NewLine + ex.ToString(), "Cannot save",
                                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
コード例 #24
0
ファイル: Core.cs プロジェクト: trs-jimmy-lee/renderdoc
        // generally logFile == origFilename, but if the log was transferred remotely then origFilename
        // is the log locally before being copied we can present to the user in dialogs, etc.
        public void LoadLogfile(string logFile, string origFilename, bool temporary, bool local)
        {
            m_LogFile = origFilename;

            m_LogLocal = local;

            m_LogLoadingInProgress = true;

            if (File.Exists(Core.ConfigFilename))
            {
                m_Config.Serialize(Core.ConfigFilename);
            }

            float postloadProgress = 0.0f;

            bool progressThread = true;

            // start a modal dialog to prevent the user interacting with the form while the log is loading.
            // We'll close it down when log loading finishes (whether it succeeds or fails)
            ProgressPopup modal = new ProgressPopup(LogLoadCallback, true);

            Thread modalThread = Helpers.NewThread(new ThreadStart(() =>
            {
                modal.SetModalText(string.Format("Loading Log: {0}", origFilename));

                AppWindow.BeginInvoke(new Action(() =>
                {
                    modal.ShowDialog(AppWindow);
                }));
            }));

            modalThread.Start();

            // this thread continually ticks and notifies any threads of the progress, through a float
            // that is updated by the main loading code
            Thread thread = Helpers.NewThread(new ThreadStart(() =>
            {
                modal.LogfileProgressBegin();

                foreach (var p in m_ProgressListeners)
                {
                    p.LogfileProgressBegin();
                }

                while (progressThread)
                {
                    Thread.Sleep(2);

                    float progress = 0.8f * m_Renderer.LoadProgress + 0.19f * postloadProgress + 0.01f;

                    modal.LogfileProgress(progress);

                    foreach (var p in m_ProgressListeners)
                    {
                        p.LogfileProgress(progress);
                    }
                }
            }));

            thread.Start();

            // this function call will block until the log is either loaded, or there's some failure
            m_Renderer.OpenCapture(logFile);

            // if the renderer isn't running, we hit a failure case so display an error message
            if (!m_Renderer.Running)
            {
                string errmsg = m_Renderer.InitException.Status.Str();

                MessageBox.Show(String.Format("{0}\nFailed to open file for replay: {1}.\n\n" +
                                              "Check diagnostic log in Help menu for more details.", origFilename, errmsg),
                                "Error opening log", MessageBoxButtons.OK, MessageBoxIcon.Error);

                progressThread = false;
                thread.Join();

                m_LogLoadingInProgress = false;

                modal.LogfileProgress(-1.0f);

                foreach (var p in m_ProgressListeners)
                {
                    p.LogfileProgress(-1.0f);
                }

                return;
            }

            if (!temporary)
            {
                m_Config.AddRecentFile(m_Config.RecentLogFiles, origFilename, 10);

                if (File.Exists(Core.ConfigFilename))
                {
                    m_Config.Serialize(Core.ConfigFilename);
                }
            }

            m_EventID = 0;

            m_FrameInfo     = null;
            m_APIProperties = null;

            // fetch initial data like drawcalls, textures and buffers
            m_Renderer.Invoke((ReplayRenderer r) =>
            {
                m_FrameInfo = r.GetFrameInfo();

                m_APIProperties = r.GetAPIProperties();

                postloadProgress = 0.2f;

                m_DrawCalls = FakeProfileMarkers(r.GetDrawcalls());

                bool valid = HasValidMarkerColors(m_DrawCalls);

                if (!valid)
                {
                    RemoveMarkerColors(m_DrawCalls);
                }

                postloadProgress = 0.4f;

                m_Buffers = r.GetBuffers();

                postloadProgress = 0.7f;
                var texs         = new List <FetchTexture>(r.GetTextures());
                m_Textures       = texs.OrderBy(o => o.name).ToArray();

                postloadProgress = 0.9f;

                m_D3D11PipelineState  = r.GetD3D11PipelineState();
                m_D3D12PipelineState  = r.GetD3D12PipelineState();
                m_GLPipelineState     = r.GetGLPipelineState();
                m_VulkanPipelineState = r.GetVulkanPipelineState();
                m_PipelineState.SetStates(m_APIProperties, m_D3D11PipelineState, m_D3D12PipelineState, m_GLPipelineState, m_VulkanPipelineState);

                UnreadMessageCount = 0;
                AddMessages(m_FrameInfo.debugMessages);

                postloadProgress = 1.0f;
            });

            Thread.Sleep(20);

            DateTime today   = DateTime.Now;
            DateTime compare = today.AddDays(-21);

            if (compare.CompareTo(Config.DegradedLog_LastUpdate) >= 0 && m_APIProperties.degraded)
            {
                Config.DegradedLog_LastUpdate = today;

                MessageBox.Show(String.Format("{0}\nThis log opened with degraded support - " +
                                              "this could mean missing hardware support caused a fallback to software rendering.\n\n" +
                                              "This warning will not appear every time this happens, " +
                                              "check debug errors/warnings window for more details.", origFilename),
                                "Degraded support of log", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }

            m_LogLoaded    = true;
            progressThread = false;

            if (local)
            {
                try
                {
                    m_LogWatcher = new FileSystemWatcher(Path.GetDirectoryName(m_LogFile), Path.GetFileName(m_LogFile));
                    m_LogWatcher.EnableRaisingEvents = true;
                    m_LogWatcher.NotifyFilter        = NotifyFilters.Size | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite;
                    m_LogWatcher.Created            += new FileSystemEventHandler(OnLogfileChanged);
                    m_LogWatcher.Changed            += new FileSystemEventHandler(OnLogfileChanged);
                    m_LogWatcher.SynchronizingObject = m_MainWindow; // callbacks on UI thread please
                }
                catch (ArgumentException)
                {
                    // likely an "invalid" directory name - FileSystemWatcher doesn't support UNC paths properly
                }
            }

            List <ILogViewerForm> logviewers = new List <ILogViewerForm>();

            logviewers.AddRange(m_LogViewers);

            // make sure we're on a consistent event before invoking log viewer forms
            FetchDrawcall draw = m_DrawCalls.Last();

            while (draw.children != null && draw.children.Length > 0)
            {
                draw = draw.children.Last();
            }

            SetEventID(logviewers.ToArray(), draw.eventID, true);

            // notify all the registers log viewers that a log has been loaded
            foreach (var logviewer in logviewers)
            {
                if (logviewer == null || !(logviewer is Control))
                {
                    continue;
                }

                Control c = (Control)logviewer;
                if (c.InvokeRequired)
                {
                    if (!c.IsDisposed)
                    {
                        c.Invoke(new Action(() => {
                            try
                            {
                                logviewer.OnLogfileLoaded();
                            }
                            catch (Exception ex)
                            {
                                throw new AccessViolationException("Rethrown from Invoke:\n" + ex.ToString());
                            }
                        }));
                    }
                }
                else if (!c.IsDisposed)
                {
                    logviewer.OnLogfileLoaded();
                }
            }

            m_LogLoadingInProgress = false;

            modal.LogfileProgress(1.0f);

            foreach (var p in m_ProgressListeners)
            {
                p.LogfileProgress(1.0f);
            }
        }
コード例 #25
0
        public static bool ShouldHide(Core core, FetchDrawcall drawcall)
        {
            if (drawcall.flags.HasFlag(DrawcallFlags.PushMarker))
            {
                if (core.Config.EventBrowser_HideEmpty)
                {
                    if (drawcall.children == null || drawcall.children.Length == 0)
                    {
                        return(true);
                    }

                    bool allhidden = true;

                    foreach (FetchDrawcall child in drawcall.children)
                    {
                        if (ShouldHide(core, child))
                        {
                            continue;
                        }

                        allhidden = false;
                        break;
                    }

                    if (allhidden)
                    {
                        return(true);
                    }
                }

                if (core.Config.EventBrowser_HideAPICalls)
                {
                    if (drawcall.children == null || drawcall.children.Length == 0)
                    {
                        return(false);
                    }

                    bool onlyapi = true;

                    foreach (FetchDrawcall child in drawcall.children)
                    {
                        if (ShouldHide(core, child))
                        {
                            continue;
                        }

                        if (!child.flags.HasFlag(DrawcallFlags.APICalls))
                        {
                            onlyapi = false;
                            break;
                        }
                    }

                    if (onlyapi)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
コード例 #26
0
ファイル: Core.cs プロジェクト: UIKit0/renderdoc
        // if a log doesn't contain any markers specified at all by the user, then we can
        // fake some up by determining batches of draws that are similar and giving them a
        // pass number
        private FetchDrawcall[] FakeProfileMarkers(int frameID, FetchDrawcall[] draws)
        {
            if (ContainsMarker(draws))
            {
                return(draws);
            }

            var ret = new List <FetchDrawcall>();

            int depthpassID   = 1;
            int computepassID = 1;
            int passID        = 1;

            int start = 0;

            int counter = 1;

            for (int i = 1; i < draws.Length; i++)
            {
                if (PassEquivalent(draws[i], draws[start]) && i + 1 < draws.Length)
                {
                    continue;
                }

                int end = i - 1;

                if (i == draws.Length - 1)
                {
                    end = i;
                }

                if (end - start < 2 ||
                    draws[i].children.Length > 0 || draws[start].children.Length > 0 ||
                    draws[i].context != m_FrameInfo[frameID].immContextId ||
                    draws[start].context != m_FrameInfo[frameID].immContextId)
                {
                    for (int j = start; j <= end; j++)
                    {
                        ret.Add(draws[j]);
                        counter++;
                    }

                    start = i;
                    continue;
                }

                int minOutCount = 100;
                int maxOutCount = 0;

                for (int j = start; j <= end; j++)
                {
                    int outCount = 0;
                    foreach (var o in draws[j].outputs)
                    {
                        if (o != ResourceId.Null)
                        {
                            outCount++;
                        }
                    }
                    minOutCount = Math.Min(minOutCount, outCount);
                    maxOutCount = Math.Max(maxOutCount, outCount);
                }

                FetchDrawcall mark = new FetchDrawcall();

                mark.eventID    = draws[end].eventID;
                mark.drawcallID = draws[end].drawcallID;

                mark.context  = draws[end].context;
                mark.flags    = DrawcallFlags.PushMarker;
                mark.outputs  = draws[end].outputs;
                mark.depthOut = draws[end].depthOut;

                mark.name = "Guessed Pass";

                if ((draws[end].flags & DrawcallFlags.Dispatch) != 0)
                {
                    mark.name = String.Format("Compute Pass #{0}", computepassID++);
                }
                else if (maxOutCount == 0)
                {
                    mark.name = String.Format("Depth-only Pass #{0}", depthpassID++);
                }
                else if (minOutCount == maxOutCount)
                {
                    mark.name = String.Format("Colour Pass #{0} ({1} Targets{2})", passID++, minOutCount, draws[end].depthOut == ResourceId.Null ? "" : " + Depth");
                }
                else
                {
                    mark.name = String.Format("Colour Pass #{0} ({1}-{2} Targets{3})", passID++, minOutCount, maxOutCount, draws[end].depthOut == ResourceId.Null ? "" : " + Depth");
                }

                mark.children = new FetchDrawcall[end - start + 1];

                for (int j = start; j <= end; j++)
                {
                    mark.children[j - start] = draws[j];
                    draws[j].parent          = mark;
                }

                ret.Add(mark);

                start = i;
                counter++;
            }

            return(ret.ToArray());
        }
コード例 #27
0
ファイル: EventBrowser.cs プロジェクト: Paxi1337/renderdoc
        private TreelistView.Node AddDrawcall(TreelistView.Node existing, FetchDrawcall drawcall, TreelistView.Node root, Dictionary <uint, List <CounterResult> > times)
        {
            if (m_Core.Config.EventBrowser_HideEmpty)
            {
                if ((drawcall.children == null || drawcall.children.Length == 0) && (drawcall.flags & DrawcallFlags.PushMarker) != 0)
                {
                    return(null);
                }
            }

            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);
            }

            DeferredEvent def = new DeferredEvent();

            def.frameID = m_Core.CurFrame;
            def.eventID = eventNum;
            def.marker  = (drawcall.flags & DrawcallFlags.SetMarker) != 0;

            if (drawcall.context != m_Core.FrameInfo[m_Core.CurFrame].immContextId)
            {
                def.defCtx    = drawcall.context;
                def.lastDefEv = drawcall.eventID;

                FetchDrawcall parent = drawcall.parent;
                while (!parent.name.Contains("ExecuteCommand"))
                {
                    parent = parent.parent;
                }

                def.eventID = parent.eventID - 1;

                def.firstDefEv = parent.children[0].eventID;
                if (parent.children[0].events.Length > 0)
                {
                    def.firstDefEv = parent.children[0].events[0].eventID;
                }
            }

            drawNode.Tag = def;

            if (drawcall.children != null && drawcall.children.Length > 0)
            {
                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);

                    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;

                for (int i = drawNode.Nodes.Count - 1; i >= 0; i--)
                {
                    DeferredEvent t = drawNode.Nodes[i].Tag as DeferredEvent;
                    if (t != null && !t.marker)
                    {
                        drawNode.Tag = drawNode.Nodes[i].Tag;
                        found        = true;
                        break;
                    }
                }

                if (!found)
                {
                    drawNode.Tag = drawNode.Nodes.LastNode.Tag;
                }
            }

            return(drawNode);
        }