Пример #1
0
        public void AddDebugMessages(FetchDrawcall[] drawcalls)
        {
            foreach (var draw in drawcalls)
            {
                if (draw.context != m_Core.FrameInfo[m_Core.CurFrame].immContextId)
                    continue;

                if(draw.children.Length > 0)
                    AddDebugMessages(draw.children);

                if (draw.debugMessages != null)
                {
                    foreach (var msg in draw.debugMessages)
                    {
                        int i = m_Messages.Count;
                        m_VisibleMessages.Add(i);
                        m_Messages.Add(new DebugMessage(i, draw.eventID, msg));
                    }
                }
            }
        }
Пример #2
0
        // 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 present with anything
            if ((a.flags & DrawcallFlags.Present) != (b.flags & DrawcallFlags.Present))
                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;
        }
Пример #3
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);

            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();
                        if (drawcall.ShouldUseWhiteText())
                            drawNode.ForeColor = Color.White;
                    }
                }
            }

            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;
        }
Пример #4
0
        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;
            }
        }
Пример #5
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 = MakeNode(eventNum, drawcall.drawcallID, drawcall.name, 0.0);

            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++)
                {
                    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;
        }
Пример #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
        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;
        }
Пример #8
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)
                    {
                        DeferredEvent markerTag = drawNode.Nodes[drawNode.Nodes.Count - 2].Tag as DeferredEvent;
                        DeferredEvent drawTag = drawNode.Nodes.LastNode.Tag as DeferredEvent;
                        markerTag.eventID = drawTag.eventID;
                    }
                }

                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;
        }
Пример #9
0
        private void RemoveMarkerColors(FetchDrawcall[] draws)
        {
            for (int i = 0; i < draws.Length; i++)
            {
                draws[i].markerColour[0] = 0.0f;
                draws[i].markerColour[1] = 0.0f;
                draws[i].markerColour[2] = 0.0f;
                draws[i].markerColour[3] = 0.0f;

                RemoveMarkerColors(draws[i].children);
            }
        }
Пример #10
0
        // because some engines (*cough*unreal*cough*) provide a valid marker colour of
        // opaque black for every marker, instead of transparent black (i.e. just 0) we
        // want to check for that case and remove the colors, instead of displaying all
        // the markers as black which is not what's intended.
        //
        // Valid marker colors = has at least one color somewhere that isn't (0.0, 0.0, 0.0, 1.0)
        //                       or (0.0, 0.0, 0.0, 0.0)
        //
        // This will fail if no marker colors are set anyway, but then removing them is
        // harmless.
        private bool HasValidMarkerColors(FetchDrawcall[] draws)
        {
            if (draws.Length == 0)
                return false;

            foreach (var d in draws)
            {
                if (d.markerColour[0] != 0.0f ||
                     d.markerColour[1] != 0.0f ||
                     d.markerColour[2] != 0.0f ||
                     (d.markerColour[3] != 1.0f && d.markerColour[3] != 0.0f))
                {
                    return true;
                }

                if (HasValidMarkerColors(d.children))
                    return true;
            }

            return false;
        }
Пример #11
0
        private void AddFrameDrawcalls(TreelistView.Node frame, FetchDrawcall[] drawcalls)
        {
            eventView.BeginUpdate();

            frame["Duration"] = -1.0;

            DeferredEvent startEv = new DeferredEvent();
            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;

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

                if (newD != null)
                {
                    d = newD;

                    if ((double)d["Duration"] > 0.0)
                        frame["Duration"] = Math.Max(0.0, (double)frame["Duration"]) + (double)d["Duration"];
                }
            }

            frame.Tag = frame.Nodes.LastNode.Tag;

            eventView.EndUpdate();
        }
Пример #12
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;
        }
Пример #13
0
        private void PopulateDraws(ref Dictionary<Int64, FetchDrawcall> map, FetchDrawcall[] draws)
        {
            if (draws.Length == 0) return;

            foreach (var d in draws)
            {
                map.Add((Int64)d.eventID, d);
                PopulateDraws(ref map, d.children);
            }
        }
Пример #14
0
        private void FixupDraws(Dictionary<Int64, FetchDrawcall> map, FetchDrawcall[] draws)
        {
            if (draws.Length == 0) return;

            foreach (var d in draws)
            {
                if (d.previousDrawcall != 0 && map.ContainsKey(d.previousDrawcall)) d.previous = map[d.previousDrawcall];
                if (d.nextDrawcall != 0 && map.ContainsKey(d.nextDrawcall)) d.next = map[d.nextDrawcall];
                if (d.parentDrawcall != 0 && map.ContainsKey(d.parentDrawcall)) d.parent = map[d.parentDrawcall];

                FixupDraws(map, d.children);
            }
        }
Пример #15
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);
            }
        }
Пример #16
0
        private void CountDrawsDispatches(FetchDrawcall draw, ref int numDraws, ref int numDispatches)
        {
            if ((draw.flags & DrawcallFlags.Drawcall) != 0)
            {
                numDraws++;
            }
            if ((draw.flags & DrawcallFlags.Dispatch) != 0)
            {
                numDraws++;
                numDispatches++;
            }

            if(draw.children != null)
            {
                foreach (var d in draw.children)
                    CountDrawsDispatches(d, ref numDraws, ref numDispatches);
            }
        }
Пример #17
0
        // used for the mesh view, to get the format of the mesh input from whichever stage that
        // we're looking at
        private Input GetCurrentMeshInput(FetchDrawcall draw, MeshDataStage type)
        {
            if (!MeshView)
                return null;

            FormatElement[] f = null;
            Input ret = new Input();
            ret.Drawcall = draw;
            ret.Topology = m_Core.CurPipelineState.DrawTopology;

            if (type != MeshDataStage.VSIn)
            {
                ShaderReflection details = null;

                if (type == MeshDataStage.VSOut)
                    details = m_Core.CurPipelineState.GetShaderReflection(ShaderStageType.Vertex);
                else if (type == MeshDataStage.GSOut)
                {
                    details = m_Core.CurPipelineState.GetShaderReflection(ShaderStageType.Geometry);
                    if (details == null)
                        details = m_Core.CurPipelineState.GetShaderReflection(ShaderStageType.Domain);
                }

                if (details == null)
                    return null;

                f = new FormatElement[details.OutputSig.Length];

                uint offset = 0;
                for (int i = 0; i < details.OutputSig.Length; i++)
                {
                    var sig = details.OutputSig[i];

                    f[i] = new FormatElement();

                    f[i].buffer = 0;
                    f[i].name = details.OutputSig[i].varName != "" ? details.OutputSig[i].varName : details.OutputSig[i].semanticIdxName;
                    f[i].format.compByteWidth = sizeof(float);
                    f[i].format.compCount = sig.compCount;
                    f[i].format.compType = sig.compType;
                    f[i].format.special = false;
                    f[i].format.rawType = 0;
                    f[i].offset = offset;
                    f[i].perinstance = false;
                    f[i].rowmajor = false;
                    f[i].matrixdim = 1;

                    offset += details.OutputSig[i].compCount * sizeof(float);
                }

                ret.BufferFormats = f;
                ret.Strides = new uint[] { offset };
                ret.Offsets = new uint[] { 0 };
                ret.Buffers = null;
                ret.IndexBuffer = ResourceId.Null;

                return ret;
            }

            CommonPipelineState.VBuffer[] vbs = m_Core.CurPipelineState.GetVBuffers();

            ResourceId[] bs = new ResourceId[vbs.Length];
            uint[] s = new uint[vbs.Length];
            uint[] o = new uint[vbs.Length];

            for (int i = 0; i < vbs.Length; i++)
            {
                bs[i] = vbs[i].Buffer;
                s[i] = vbs[i].ByteStride;
                o[i] = vbs[i].ByteOffset;
            }

            {
                var vinputs = m_Core.CurPipelineState.GetVertexInputs();
                f = new FormatElement[vinputs.Length];

                int i = 0;
                foreach (var a in vinputs)
                {
                    f[i] = new FormatElement(a.Name,
                                             a.VertexBuffer,
                                             a.RelativeByteOffset,
                                             a.PerInstance,
                                             false, // row major matrix
                                             1, // matrix dimension
                                             a.Format);
                    i++;
                }
            }

            ResourceId ibuffer = ResourceId.Null;
            uint ioffset = 0;
            ResourceFormat ifmt = null;

            m_Core.CurPipelineState.GetIBuffer(out ibuffer, out ioffset, out ifmt);

            if (draw != null && (draw.flags & DrawcallFlags.UseIBuffer) == 0)
            {
                ibuffer = ResourceId.Null;
                ioffset = 0;
            }

            ret.BufferFormats = f;
            ret.Strides = s;
            ret.Offsets = o;
            ret.Buffers = bs;

            ret.IndexFormat = new FormatElement("", 0, 0, false, false, 1, ifmt);
            ret.IndexBuffer = ibuffer;
            ret.IndexOffset = ioffset;

            return ret;
        }
Пример #18
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]);
        }
Пример #19
0
        // used for the mesh view, to get the format of the mesh input from whichever stage that
        // we're looking at
        private Input GetCurrentMeshInput(FetchDrawcall draw, MeshDataStage type)
        {
            if (!MeshView)
                return null;

            Input ret = new Input();
            ret.Drawcall = draw;
            ret.Topology = draw.topology;

            ResourceId ibuffer = ResourceId.Null;
            ulong ioffset = 0;

            m_Core.CurPipelineState.GetIBuffer(out ibuffer, out ioffset);

            if (draw != null && (draw.flags & DrawcallFlags.UseIBuffer) == 0)
            {
                ibuffer = ResourceId.Null;
                ioffset = 0;
            }

            ret.IndexBuffer = ibuffer;
            ret.IndexOffset = ioffset;
            ret.IndexRestart = m_Core.CurPipelineState.IsStripRestartEnabled();
            ret.IndexRestartValue = m_Core.CurPipelineState.GetStripRestartIndex(draw != null ? draw.indexByteWidth : 0);

            if (type != MeshDataStage.VSIn)
            {
                ShaderReflection details = null;

                if (type == MeshDataStage.VSOut)
                    details = m_Core.CurPipelineState.GetShaderReflection(ShaderStageType.Vertex);
                else if (type == MeshDataStage.GSOut)
                {
                    details = m_Core.CurPipelineState.GetShaderReflection(ShaderStageType.Geometry);
                    if (details == null)
                        details = m_Core.CurPipelineState.GetShaderReflection(ShaderStageType.Domain);
                }

                if (details == null)
                    return null;

                List<FormatElement> f = new List<FormatElement>();

                int posidx = -1;
                for (int i = 0; i < details.OutputSig.Length; i++)
                {
                    var sig = details.OutputSig[i];

                    f.Add(new FormatElement());

                    f[i].buffer = 0;
                    f[i].name = details.OutputSig[i].varName.Length > 0 ? details.OutputSig[i].varName : details.OutputSig[i].semanticIdxName;
                    f[i].format.compByteWidth = sizeof(float);
                    f[i].format.compCount = sig.compCount;
                    f[i].format.compType = sig.compType;
                    f[i].format.special = false;
                    f[i].format.rawType = 0;
                    f[i].perinstance = false;
                    f[i].instancerate = 1;
                    f[i].rowmajor = false;
                    f[i].matrixdim = 1;
                    f[i].systemValue = sig.systemValue;

                    if(f[i].systemValue == SystemAttribute.Position)
                        posidx = i;
                }

                // shift position attribute up to first, keeping order otherwise
                // the same
                if (posidx > 0)
                {
                    FormatElement pos = f[posidx];
                    f.RemoveAt(posidx);
                    f.Insert(0, pos);
                }

                uint offset = 0;
                for (int i = 0; i < details.OutputSig.Length; i++)
                {
                    uint numComps = f[i].format.compCount;
                    uint elemSize = f[i].format.compType == FormatComponentType.Double ? 8U : 4U;

                    if (m_Core.CurPipelineState.HasAlignedPostVSData)
                    {
                        if (numComps == 2)
                            offset = offset.AlignUp(2U * elemSize);
                        else if (numComps > 2)
                            offset = offset.AlignUp(4U * elemSize);
                    }

                    f[i].offset = offset;

                    offset += numComps * elemSize;
                }

                ret.BufferFormats = f.ToArray();
                ret.Strides = new uint[] { offset };
                ret.Offsets = new ulong[] { 0 };
                ret.Buffers = null;

                return ret;
            }

            BoundVBuffer[] vbs = m_Core.CurPipelineState.GetVBuffers();

            ResourceId[] bs = new ResourceId[vbs.Length];
            uint[] s = new uint[vbs.Length];
            ulong[] o = new ulong[vbs.Length];

            for (int i = 0; i < vbs.Length; i++)
            {
                bs[i] = vbs[i].Buffer;
                s[i] = vbs[i].ByteStride;
                o[i] = vbs[i].ByteOffset;
            }

            {
                FormatElement[] f = null;

                var vinputs = m_Core.CurPipelineState.GetVertexInputs();
                f = new FormatElement[vinputs.Length];

                ret.GenericValues = new object[vinputs.Length][];

                int numinputs = vinputs.Length;

                int i = 0;
                foreach (var a in vinputs)
                {
                    if (!a.Used)
                    {
                        numinputs--;
                        Array.Resize(ref f, numinputs);
                        Array.Resize(ref ret.GenericValues, numinputs);
                        continue;
                    }

                    f[i] = new FormatElement(a.Name,
                                             a.VertexBuffer,
                                             a.RelativeByteOffset,
                                             a.PerInstance,
                                             a.InstanceRate,
                                             false, // row major matrix
                                             1, // matrix dimension
                                             a.Format,
                                             false);
                    ret.GenericValues[i] = a.GenericValue;
                    i++;
                }

                ret.BufferFormats = f;
                ret.Strides = s;
                ret.Offsets = o;
                ret.Buffers = bs;
            }

            return ret;
        }
Пример #20
0
        private uint GetEndEventID(FetchDrawcall drawcall)
        {
            if (drawcall.children.Length == 0)
                return drawcall.eventID;

            return GetEndEventID(drawcall.children.Last());
        }
Пример #21
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]);
        }
Пример #22
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]);
        }
Пример #23
0
        private bool ContainsMarker(FetchDrawcall[] draws)
        {
            bool ret = false;

            foreach (var d in draws)
            {
                ret |= (d.flags & (DrawcallFlags.PushMarker | DrawcallFlags.SetMarker)) > 0 && (d.flags & DrawcallFlags.CmdList) == 0;
                ret |= ContainsMarker(d.children);
            }

            return ret;
        }
Пример #24
0
        private void AddFrameDrawcalls(TreelistView.Node frame, FetchDrawcall[] drawcalls)
        {
            eventView.BeginUpdate();

            frame["Duration"] = -1.0;

            DeferredEvent startEv = new DeferredEvent();
            startEv.frameID = m_Core.CurFrame;
            startEv.eventID = 0;

            frame.Nodes.Clear();
            frame.Nodes.Add(MakeNode(0, 0, "Frame Start", -1.0)).Tag = startEv;

            for (int i = 0; i < drawcalls.Length; i++)
                AddDrawcall(drawcalls[i], frame);

            frame.Tag = frame.Nodes.LastNode.Tag;

            eventView.EndUpdate();
        }
Пример #25
0
        // 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]))
                    continue;

                int end = i-1;

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

            if (start < draws.Length)
                ret.Add(draws[start]);

            return ret.ToArray();
        }
Пример #26
0
        private Section GatherEvents(FetchDrawcall[] draws)
        {
            var sections = new List<List<FetchDrawcall>>();

            foreach (var d in draws)
            {
                if ((d.flags & (DrawcallFlags.SetMarker | DrawcallFlags.Present)) > 0)
                    continue;

                if (m_Core.Config.EventBrowser_HideEmpty)
                {
                    if ((d.children == null || d.children.Length == 0) && (d.flags & (DrawcallFlags.PushMarker | DrawcallFlags.MultiDraw)) != 0)
                        continue;
                }

                bool newSection = ((d.flags & (DrawcallFlags.PushMarker|DrawcallFlags.MultiDraw)) > 0 || sections.Count == 0);
                if (!newSection)
                {
                    var lastSection = sections.Last();

                    if (lastSection.Count == 1 && (lastSection[0].flags & (DrawcallFlags.PushMarker | DrawcallFlags.MultiDraw)) > 0)
                        newSection = true;
                }

                if (newSection)
                    sections.Add(new List<FetchDrawcall>());

                sections.Last().Add(d);
            }

            Section ret = new Section();
            ret.subsections = new List<Section>();

            foreach (var s in sections)
            {
                Section sec = null;

                if (s.Count == 1 && (s[0].flags & (DrawcallFlags.PushMarker | DrawcallFlags.MultiDraw)) > 0)
                {
                    sec = GatherEvents(s[0].children);
                    if (m_Core.Config.EventBrowser_ApplyColours)
                    {
                        sec.color = s[0].GetColor();
                        sec.textcolor = s[0].GetTextColor(Color.Black);
                    }
                    else
                    {
                        sec.color = Color.Transparent;
                        sec.textcolor = Color.Black;
                    }
                    sec.Name = s[0].name;
                }
                else
                {
                    sec = new Section();
                    sec.draws = s;
                    for (int i = 0; i < sec.draws.Count; i++)
                    {
                        sec.lastPoss.Add(0.0f);
                        sec.lastUsage.Add(false);
                        sec.lastVisible.Add(false);
                    }
                }

                ret.subsections.Add(sec);
            }

            return ret;
        }
Пример #27
0
        private FetchDrawcall GetDrawcall(FetchDrawcall[] draws, UInt32 eventID)
        {
            foreach (var d in draws)
            {
                if (d.children != null && d.children.Length > 0)
                {
                    var draw = GetDrawcall(d.children, eventID);
                    if (draw != null) return draw;
                }

                if (d.eventID == eventID)
                    return d;
            }

            return null;
        }