Exemplo n.º 1
0
 public void SetStates(APIProperties props, D3D11PipelineState d3d11, D3D12PipelineState d3d12, GLPipelineState gl, VulkanPipelineState vk)
 {
     m_APIProps = props;
     m_D3D11 = d3d11;
     m_D3D12 = d3d12;
     m_GL = gl;
     m_Vulkan = vk;
 }
Exemplo n.º 2
0
        public void CloseLogfile()
        {
            if (!m_LogLoaded) return;

            m_LogFile = "";

            m_Renderer.CloseThreadSync();

            m_APIProperties = null;
            m_FrameInfo = null;
            m_DrawCalls = null;
            m_Buffers = null;
            m_Textures = null;

            m_D3D11PipelineState = null;
            m_D3D12PipelineState = null;
            m_GLPipelineState = null;
            m_VulkanPipelineState = null;
            m_PipelineState.SetStates(null, null,null, null, null);

            DebugMessages.Clear();
            UnreadMessageCount = 0;

            m_LogLoaded = false;

            if (m_LogWatcher != null)
                m_LogWatcher.EnableRaisingEvents = false;
            m_LogWatcher = null;

            foreach (var logviewer in m_LogViewers)
            {
                Control c = (Control)logviewer;
                if (c.InvokeRequired)
                    c.Invoke(new Action(() => logviewer.OnLogfileClosed()));
                else
                    logviewer.OnLogfileClosed();
            }
        }
        private void ExportHTML(XmlTextWriter writer, D3D12PipelineState.Rasterizer rs)
        {
            {
                writer.WriteStartElement("h3");
                writer.WriteString("States");
                writer.WriteEndElement();

                ExportHTMLTable(writer,
                    new string[] { "Fill Mode", "Cull Mode", "Front CCW" },
                    new object[] { rs.m_State.FillMode, rs.m_State.CullMode, rs.m_State.FrontCCW ? "Yes" : "No" });

                writer.WriteStartElement("p");
                writer.WriteEndElement();

                ExportHTMLTable(writer,
                    new string[] { "Line AA Enable", "Multisample Enable", "Forced Sample Count", "Conservative Raster" },
                    new object[] { rs.m_State.AntialiasedLineEnable ? "Yes" : "No",
                                   rs.m_State.MultisampleEnable ? "Yes" : "No", rs.m_State.ForcedSampleCount,
                                   rs.m_State.ConservativeRasterization ? "Yes" : "No" });

                writer.WriteStartElement("p");
                writer.WriteEndElement();

                ExportHTMLTable(writer,
                    new string[] { "Depth Clip", "Depth Bias", "Depth Bias Clamp", "Slope Scaled Bias" },
                    new object[] { rs.m_State.DepthClip ? "Yes" : "No", rs.m_State.DepthBias,
                                   Formatter.Format(rs.m_State.DepthBiasClamp), Formatter.Format(rs.m_State.SlopeScaledDepthBias)});
            }

            {
                writer.WriteStartElement("h3");
                writer.WriteString("Viewports");
                writer.WriteEndElement();

                List<object[]> rows = new List<object[]>();

                int i = 0;
                foreach (var v in rs.Viewports)
                {
                    if (v.Width == v.Height && v.Width == 0 && v.Height == 0) continue;

                    rows.Add(new object[] { i, v.TopLeft[0], v.TopLeft[1], v.Width, v.Height, v.MinDepth, v.MaxDepth });

                    i++;
                }

                ExportHTMLTable(writer, new string[] { "Slot", "X", "Y", "Width", "Height", "Min Depth", "Max Depth" }, rows.ToArray());
            }

            {
                writer.WriteStartElement("h3");
                writer.WriteString("Scissors");
                writer.WriteEndElement();

                List<object[]> rows = new List<object[]>();

                int i = 0;
                foreach (var s in rs.Scissors)
                {
                    if (s.right == 0 && s.bottom == 0) continue;

                    rows.Add(new object[] { i, s.left, s.top, s.right - s.left, s.bottom - s.top });

                    i++;
                }

                ExportHTMLTable(writer, new string[] { "Slot", "X", "Y", "Width", "Height" }, rows.ToArray());
            }
        }
        private void ExportHTML(XmlTextWriter writer, D3D12PipelineState.OutputMerger om)
        {
            {
                writer.WriteStartElement("h3");
                writer.WriteString("Blend State");
                writer.WriteEndElement();

                var blendFactor = om.m_BlendState.BlendFactor[0].ToString("F2") + ", " +
                                    om.m_BlendState.BlendFactor[1].ToString("F2") + ", " +
                                    om.m_BlendState.BlendFactor[2].ToString("F2") + ", " +
                                    om.m_BlendState.BlendFactor[3].ToString("F2");

                ExportHTMLTable(writer,
                    new string[] { "Independent Blend Enable", "Alpha to Coverage", "Blend Factor" },
                    new object[] { om.m_BlendState.IndependentBlend ? "Yes" : "No", om.m_BlendState.AlphaToCoverage ? "Yes" : "No",
                                   blendFactor, });

                writer.WriteStartElement("h3");
                writer.WriteString("Target Blends");
                writer.WriteEndElement();

                List<object[]> rows = new List<object[]>();

                int i = 0;
                foreach (var b in om.m_BlendState.Blends)
                {
                    if (!b.Enabled) continue;

                    rows.Add(new object[] {
                        i,
                        b.Enabled ? "Yes" : "No", b.LogicEnabled ? "Yes" : "No",
                        b.m_Blend.Source, b.m_Blend.Destination, b.m_Blend.Operation,
                        b.m_AlphaBlend.Source, b.m_AlphaBlend.Destination, b.m_AlphaBlend.Operation,
                        b.LogicOp,
                        ((b.WriteMask & 0x1) == 0 ? "_" : "R") +
                        ((b.WriteMask & 0x2) == 0 ? "_" : "G") +
                        ((b.WriteMask & 0x4) == 0 ? "_" : "B") +
                        ((b.WriteMask & 0x8) == 0 ? "_" : "A")  });

                    i++;
                }

                ExportHTMLTable(writer,
                    new string[] {
                        "Slot",
                        "Blend Enable", "Logic Enable",
                        "Blend Source", "Blend Destination", "Blend Operation",
                        "Alpha Blend Source", "Alpha Blend Destination", "Alpha Blend Operation",
                        "Logic Operation", "Write Mask",
                    },
                    rows.ToArray());
            }

            {
                writer.WriteStartElement("h3");
                writer.WriteString("Depth State");
                writer.WriteEndElement();

                ExportHTMLTable(writer,
                    new string[] { "Depth Test Enable", "Depth Writes Enable", "Depth Function" },
                    new object[] { om.m_State.DepthEnable ? "Yes" : "No", om.m_State.DepthWrites ? "Yes" : "No", om.m_State.DepthFunc });
            }

            {
                writer.WriteStartElement("h3");
                writer.WriteString("Stencil State");
                writer.WriteEndElement();

                ExportHTMLTable(writer,
                    new string[] { "Stencil Test Enable", "Stencil Read Mask", "Stencil Write Mask" },
                    new object[] { om.m_State.StencilEnable ? "Yes" : "No", om.m_State.StencilReadMask.ToString("X2"), om.m_State.StencilWriteMask.ToString("X2") });

                writer.WriteStartElement("p");
                writer.WriteEndElement();

                ExportHTMLTable(writer,
                    new string[] { "Face", "Function", "Pass Operation", "Fail Operation", "Depth Fail Operation" },
                    new object[][] {
                        new object[] { "Front", om.m_State.m_FrontFace.Func, om.m_State.m_FrontFace.PassOp, om.m_State.m_FrontFace.FailOp, om.m_State.m_FrontFace.DepthFailOp },
                        new object[] { "Back", om.m_State.m_BackFace.Func, om.m_State.m_BackFace.PassOp, om.m_State.m_BackFace.FailOp, om.m_State.m_BackFace.DepthFailOp },
                    });
            }

            {
                writer.WriteStartElement("h3");
                writer.WriteString("Render targets");
                writer.WriteEndElement();

                List<object[]> rows = new List<object[]>();

                for (int i = 0; i < om.RenderTargets.Length; i++)
                {
                    if (om.RenderTargets[i].Resource == ResourceId.Null) continue;

                    rows.Add(ExportViewHTML(om.RenderTargets[i], i, null, ""));
                }

                ExportHTMLTable(writer,
                    new string[] {
                        "Slot", "Name",
                        "View Type", "Resource Type",
                        "Width", "Height", "Depth", "Array Size",
                        "View Format", "Resource Format",
                        "View Parameters",
                    },
                    rows.ToArray());
            }

            {
                writer.WriteStartElement("h3");
                writer.WriteString("Depth target");
                writer.WriteEndElement();

                List<object[]> rows = new List<object[]>();

                string extra = "";

                if(om.DepthReadOnly && om.StencilReadOnly)
                    extra = "Depth & Stencil Read-Only";
                else if (om.DepthReadOnly)
                    extra = "Depth Read-Only";
                else if (om.StencilReadOnly)
                    extra = "Stencil Read-Only";

                rows.Add(ExportViewHTML(om.DepthTarget, 0, null, extra));

                ExportHTMLTable(writer,
                    new string[] {
                        "Slot", "Name",
                        "View Type", "Resource Type",
                        "Width", "Height", "Depth", "Array Size",
                        "View Format", "Resource Format",
                        "View Parameters",
                    },
                    rows.ToArray());
            }
        }
        private void ExportHTML(XmlTextWriter writer, D3D12PipelineState.ShaderStage sh)
        {
            FetchBuffer[] bufs = m_Core.CurBuffers;

            {
                writer.WriteStartElement("h3");
                writer.WriteString("Shader");
                writer.WriteEndElement();

                ShaderReflection shaderDetails = sh.ShaderDetails;
                D3D12PipelineState state = m_Core.CurD3D12PipelineState;

                string shadername = "Unknown";

                if (sh.Shader == ResourceId.Null)
                    shadername = "Unbound";
                else if (state.customName)
                    shadername = state.PipelineName + " - " + m_Core.CurPipelineState.Abbrev(sh.stage);
                else
                    shadername = sh.stage.Str(GraphicsAPI.D3D12);

                if (shaderDetails != null && shaderDetails.DebugInfo.entryFunc.Length > 0 && shaderDetails.DebugInfo.files.Length > 0)
                    shadername = shaderDetails.DebugInfo.entryFunc + "()" + " - " +
                                    shaderDetails.DebugInfo.files[0].BaseFilename;

                writer.WriteStartElement("p");
                writer.WriteString(shadername);
                writer.WriteEndElement();

                if (sh.Shader == ResourceId.Null)
                    return;
            }
        }
        private void ExportHTML(XmlTextWriter writer, D3D12PipelineState.Streamout so)
        {
            FetchBuffer[] bufs = m_Core.CurBuffers;

            {
                writer.WriteStartElement("h3");
                writer.WriteString("Stream Out Targets");
                writer.WriteEndElement();

                List<object[]> rows = new List<object[]>();

                int i = 0;
                foreach (var o in so.Outputs)
                {
                    string name = "Buffer " + o.Buffer.ToString();
                    UInt64 length = 0;

                    if (o.Buffer == ResourceId.Null)
                    {
                        name = "Empty";
                    }
                    else
                    {
                        for (int t = 0; t < bufs.Length; t++)
                        {
                            if (bufs[t].ID == o.Buffer)
                            {
                                name = bufs[t].name;
                                length = bufs[t].length;
                            }
                        }
                    }

                    rows.Add(new object[] { i, name, o.Offset, length });

                    i++;
                }

                ExportHTMLTable(writer, new string[] { "Slot", "Buffer", "Offset", "Byte Length" }, rows.ToArray());
            }
        }
 public ViewTexTag(D3D12PipelineState.ResourceView v, FetchTexture t, bool u, ShaderResource r)
 {
     view = v;
     tex = t;
     uav = u;
     res = r;
 }
        private bool HasImportantViewParams(D3D12PipelineState.ResourceView view, FetchTexture tex)
        {
            // we don't count 'upgrade typeless to typed' as important, we just display the typed format
            // in the row since there's no real hidden important information there. The formats can't be
            // different for any other reason (if the SRV format differs from the texture format, the
            // texture must have been typeless.
            if (view.HighestMip > 0 || view.FirstArraySlice > 0 ||
                (view.NumMipLevels < tex.mips && tex.mips > 1) ||
                (view.ArraySize < tex.arraysize && tex.arraysize > 1))
                return true;

            // in the case of the swapchain case, types can be different and it won't have shown
            // up as taking the view's format because the swapchain already has one. Make sure to mark it
            // as important
            if (view.Format.compType != FormatComponentType.None && view.Format != tex.format)
                return true;

            return false;
        }
        private void ShowCBuffer(D3D12PipelineState.ShaderStage stage, CBufTag tag)
        {
            if (tag.idx == uint.MaxValue)
            {
                // unused cbuffer, open regular buffer viewer
                var viewer = new BufferViewer(m_Core, false);

                var buf = stage.Spaces[tag.space].ConstantBuffers[tag.reg];
                viewer.ViewRawBuffer(true, buf.Offset, buf.ByteSize, buf.Buffer);
                viewer.Show(m_DockContent.DockPanel);

                return;
            }

            var existing = ConstantBufferPreviewer.Has(stage.stage, tag.idx, 0);
            if (existing != null)
            {
                existing.Show();
                return;
            }

            var prev = new ConstantBufferPreviewer(m_Core, stage.stage, tag.idx, 0);

            prev.ShowDock(m_DockContent.Pane, DockAlignment.Right, 0.3);
        }
Exemplo n.º 10
0
 public ViewBufTag(D3D12PipelineState.ResourceView v, FetchBuffer b, bool u, ShaderResource r)
 {
     view = v;
     buf = b;
     uav = u;
     res = r;
 }
Exemplo n.º 11
0
        private void AddResourceRow(D3D12PipelineState.ShaderStage stage,
            TreelistView.TreeListView list,
            int space, int reg, bool uav)
        {
            D3D12PipelineState state = m_Core.CurD3D12PipelineState;
            FetchTexture[] texs = m_Core.CurTextures;
            FetchBuffer[] bufs = m_Core.CurBuffers;

            BindpointMap bind = null;
            ShaderResource shaderInput = null;

            D3D12PipelineState.ResourceView r = uav ? stage.Spaces[space].UAVs[reg] : stage.Spaces[space].SRVs[reg];

            // consider this register to not exist - it's in a gap defined by sparse root signature elements
            if (r.RootElement == uint.MaxValue)
                return;

            if (stage.BindpointMapping != null && stage.ShaderDetails != null)
            {
                BindpointMap[] binds = uav ? stage.BindpointMapping.ReadWriteResources : stage.BindpointMapping.ReadOnlyResources;
                ShaderResource[] resources = uav ? stage.ShaderDetails.ReadWriteResources : stage.ShaderDetails.ReadOnlyResources;
                for (int i=0; i < binds.Length; i++)
                {
                    var b = binds[i];
                    var res = resources[i];

                    bool regMatch = b.bind == reg;

                    // handle unbounded arrays specially. It's illegal to have an unbounded array with
                    // anything after it
                    if (b.bind <= reg)
                        regMatch = (b.arraySize == UInt32.MaxValue) || (b.bind + b.arraySize > reg);

                    if (b.bindset == space && regMatch && !res.IsSampler)
                    {
                        bind = b;
                        shaderInput = res;
                        break;
                    }
                }
            }

            TreelistView.NodeCollection parent = list.Nodes;

            string rootel = r.Immediate ? String.Format("#{0} Direct", r.RootElement) : rootel = String.Format("#{0} Table[{1}]", r.RootElement, r.TableIndex);

            bool filledSlot = r.Resource != ResourceId.Null;
            bool usedSlot = (bind != null && bind.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 regname = reg.ToString();

                if (shaderInput != null && shaderInput.name.Length > 0)
                    regname += ": " + shaderInput.name;

                UInt64 w = 1;
                UInt32 h = 1, d = 1;
                UInt32 a = 1;
                string format = "Unknown";
                string name = "Unbound";
                string typename = "Unknown";
                object tag = null;
                bool viewDetails = false;

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

                if (r != null)
                {
                    name = "Shader Resource " + r.Resource.ToString();

                    // 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 = texs[t].resType.Str();

                            if (texs[t].resType == ShaderResourceType.Texture2DMS ||
                                texs[t].resType == ShaderResourceType.Texture2DMSArray)
                            {
                                typename += String.Format(" {0}x", texs[t].msSamp);
                            }

                            // if it's a typeless format, show the format of the view
                            if (texs[t].format != r.Format)
                            {
                                format = "Viewed as " + r.Format.ToString();
                            }

                            tag = new ViewTexTag(r, texs[t], true, shaderInput);

                            if (HasImportantViewParams(r, texs[t]))
                                viewDetails = true;
                        }
                    }

                    // 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 = 1;
                            d = 1;
                            a = 1;
                            format = "";
                            name = bufs[t].name;
                            typename = uav ? "RWBuffer" : "Buffer";

                            if (r.BufferFlags.HasFlag(D3DBufferViewFlags.Raw))
                            {
                                typename = uav ? "RWByteAddressBuffer" : "ByteAddressBuffer";
                            }
                            else if (r.ElementSize > 0)
                            {
                                // for structured buffers, display how many 'elements' there are in the buffer
                                typename = (uav ? "RWStructuredBuffer" : "StructuredBuffer");
                                a = (uint)(bufs[t].length / r.ElementSize);
                            }

                            if (r.CounterResource != ResourceId.Null)
                            {
                                typename += " (Count: " + r.BufferStructCount + ")";
                            }

                            // get the buffer type, whether it's just a basic type or a complex struct
                            if (shaderInput != null && !shaderInput.IsTexture)
                            {
                                if (shaderInput.variableType.members.Length > 0)
                                    format = "struct " + shaderInput.variableType.Name;
                                else if (r.Format.compType == FormatComponentType.None)
                                    format = shaderInput.variableType.Name;
                                else
                                    format = r.Format.ToString();
                            }

                            tag = new ViewBufTag(r, bufs[t], true, shaderInput);

                            if (HasImportantViewParams(r, bufs[t]))
                                viewDetails = true;
                        }
                    }
                }

                var node = parent.Add(new object[] { rootel, space, regname, 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);

                ViewDetailsRow(node, viewDetails);
            }
        }
Exemplo n.º 12
0
        // Set a shader stage's resources and values
        private void SetShaderState(D3D12PipelineState.ShaderStage stage,
            Label shader, TreelistView.TreeListView resources, TreelistView.TreeListView samplers,
            TreelistView.TreeListView cbuffers, TreelistView.TreeListView uavs)
        {
            FetchTexture[] texs = m_Core.CurTextures;
            FetchBuffer[] bufs = m_Core.CurBuffers;

            D3D12PipelineState state = m_Core.CurD3D12PipelineState;
            ShaderReflection shaderDetails = stage.ShaderDetails;
            ShaderBindpointMapping bindpointMapping = stage.BindpointMapping;

            if (stage.Shader == ResourceId.Null)
                shader.Text = "Unbound";
            else if (state.customName)
                shader.Text = state.PipelineName + " - " + m_Core.CurPipelineState.Abbrev(stage.stage);
            else
                shader.Text = state.PipelineName + " - " + stage.stage.Str(GraphicsAPI.D3D12) + " Shader";

            if (shaderDetails != null && shaderDetails.DebugInfo.entryFunc.Length > 0 && shaderDetails.DebugInfo.files.Length > 0)
            {
                string shaderfn = "";

                int entryFile = shaderDetails.DebugInfo.entryFile;
                if (entryFile < 0 || entryFile >= shaderDetails.DebugInfo.files.Length)
                    entryFile = 0;

                shaderfn = shaderDetails.DebugInfo.files[entryFile].BaseFilename;

                shader.Text = shaderDetails.DebugInfo.entryFunc + "()" + " - " + shaderfn;
            }

            int vs = 0;

            vs = resources.VScrollValue();
            resources.BeginUpdate();
            resources.Nodes.Clear();
            for (int space = 0; space < stage.Spaces.Length; space++)
            {
                for (int reg = 0; reg < stage.Spaces[space].SRVs.Length; reg++)
                {
                    AddResourceRow(stage, resources, space, reg, false);
                }
            }
            resources.EndUpdate();
            resources.NodesSelection.Clear();
            resources.SetVScrollValue(vs);

            vs = uavs.VScrollValue();
            uavs.BeginUpdate();
            uavs.Nodes.Clear();
            for (int space = 0; space < stage.Spaces.Length; space++)
            {
                for (int reg = 0; reg < stage.Spaces[space].UAVs.Length; reg++)
                {
                    AddResourceRow(stage, uavs, space, reg, true);
                }
            }
            uavs.EndUpdate();
            uavs.NodesSelection.Clear();
            uavs.SetVScrollValue(vs);

            vs = samplers.VScrollValue();
            samplers.BeginUpdate();
            samplers.Nodes.Clear();
            for (int space = 0; space < stage.Spaces.Length; space++)
            {
                for (int reg = 0; reg < stage.Spaces[space].Samplers.Length; reg++)
                {
                    D3D12PipelineState.Sampler s = stage.Spaces[space].Samplers[reg];

                    // consider this register to not exist - it's in a gap defined by sparse root signature elements
                    if (s.RootElement == uint.MaxValue)
                        continue;

                    BindpointMap bind = null;
                    ShaderResource shaderInput = null;

                    if (stage.BindpointMapping != null && stage.ShaderDetails != null)
                    {
                        for (int i = 0; i < stage.BindpointMapping.ReadOnlyResources.Length; i++)
                        {
                            var b = stage.BindpointMapping.ReadOnlyResources[i];
                            var res = stage.ShaderDetails.ReadOnlyResources[i];

                            bool regMatch = b.bind == reg;

                            // handle unbounded arrays specially. It's illegal to have an unbounded array with
                            // anything after it
                            if (b.bind <= reg)
                                regMatch = (b.arraySize == UInt32.MaxValue) || (b.bind + b.arraySize > reg);

                            if (b.bindset == space && regMatch && res.IsSampler)
                            {
                                bind = b;
                                shaderInput = res;
                                break;
                            }
                        }
                    }

                    string rootel = s.Immediate ? String.Format("#{0} Static", s.RootElement) : String.Format("#{0} Table[{1}]", s.RootElement, s.TableIndex);

                    bool filledSlot = (s.AddressU.Length > 0);
                    bool usedSlot = (bind != null && bind.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 regname = reg.ToString();

                        if (shaderInput != null && shaderInput.name.Length > 0)
                            regname += ": " + shaderInput.name;

                        string borderColor = "";

                        string addressing = "";

                        string addPrefix = "";
                        string addVal = "";

                        string[] addr = { "", "", "" };

                        if (s != null)
                        {
                            borderColor = s.BorderColor[0].ToString() + ", " +
                                          s.BorderColor[1].ToString() + ", " +
                                          s.BorderColor[2].ToString() + ", " +
                                          s.BorderColor[3].ToString();

                            addr[0] = s.AddressU;
                            addr[1] = s.AddressV;
                            addr[2] = s.AddressW;
                        }

                        // arrange like either UVW: WRAP or UV: WRAP, W: CLAMP
                        for (int a = 0; a < 3; a++)
                        {
                            string prefix = "" + "UVW"[a];

                            if (a == 0 || addr[a] == addr[a - 1])
                            {
                                addPrefix += prefix;
                            }
                            else
                            {
                                addressing += addPrefix + ": " + addVal + ", ";

                                addPrefix = prefix;
                            }
                            addVal = addr[a];
                        }

                        addressing += addPrefix + ": " + addVal;

                        string filter = "";
                        string lodclamp = "";
                        float lodbias = 0.0f;

                        if (s != null)
                        {
                            if (s.UseBorder)
                                addressing += String.Format("<{0}>", borderColor);

                            filter = s.Filter;

                            if (s.MaxAniso > 0)
                                filter += String.Format(" {0}x", s.MaxAniso);

                            if (s.UseComparison)
                                filter += String.Format(" ({0})", s.Comparison);

                            lodclamp = (s.MinLOD == -float.MaxValue ? "0" : s.MinLOD.ToString()) + " - " +
                                       (s.MaxLOD == float.MaxValue ? "FLT_MAX" : s.MaxLOD.ToString());

                            lodbias = s.MipLODBias;
                        }

                        var node = samplers.Nodes.Add(new object[] { rootel, space, regname, addressing,
                                                                     filter, lodclamp, lodbias.ToString() });

                        if (!filledSlot)
                            EmptyRow(node);

                        if (!usedSlot)
                            InactiveRow(node);
                    }
                }
            }
            samplers.EndUpdate();
            samplers.NodesSelection.Clear();
            samplers.SetVScrollValue(vs);

            vs = cbuffers.VScrollValue();
            cbuffers.BeginUpdate();
            cbuffers.Nodes.Clear();
            for (int space = 0; space < stage.Spaces.Length; space++)
            {
                for (int reg = 0; reg < stage.Spaces[space].ConstantBuffers.Length; reg++)
                {
                    D3D12PipelineState.CBuffer b = stage.Spaces[space].ConstantBuffers[reg];

                    // consider this register to not exist - it's in a gap defined by sparse root signature elements
                    if (b.RootElement == uint.MaxValue)
                        continue;

                    BindpointMap bind = null;
                    ConstantBlock shaderCBuf = null;

                    object tag = null;

                    if (stage.BindpointMapping != null && stage.ShaderDetails != null)
                    {
                        for (int i = 0; i < stage.BindpointMapping.ConstantBlocks.Length; i++)
                        {
                            var bd = stage.BindpointMapping.ConstantBlocks[i];
                            var res = stage.ShaderDetails.ConstantBlocks[i];

                            bool regMatch = bd.bind == reg;

                            // handle unbounded arrays specially. It's illegal to have an unbounded array with
                            // anything after it
                            if (bd.bind <= reg)
                                regMatch = (bd.arraySize == UInt32.MaxValue) || (bd.bind + bd.arraySize > reg);

                            if (bd.bindset == space && regMatch)
                            {
                                bind = bd;
                                shaderCBuf = res;
                                tag = new CBufTag((uint)i);
                                break;
                            }
                        }
                    }

                    if(tag == null)
                        tag = new CBufTag(space, reg);

                    string rootel;

                    if (b.Immediate)
                    {
                        if (b.RootValues.Length > 0)
                            rootel = String.Format("#{0} Consts", b.RootElement);
                        else
                            rootel = String.Format("#{0} Direct", b.RootElement);
                    }
                    else
                    {
                        rootel = String.Format("#{0} Table[{1}]", b.RootElement, b.TableIndex);
                    }

                    bool filledSlot = (b.Buffer != ResourceId.Null);
                    if (b.Immediate && b.RootValues.Length > 0)
                        filledSlot = true;

                    bool usedSlot = (bind != null && bind.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 name = "Constant Buffer " + b.Buffer.ToString();
                        UInt64 length = 0;
                        UInt64 offset = 0;
                        int numvars = shaderCBuf != null ? shaderCBuf.variables.Length : 0;
                        UInt32 byteSize = shaderCBuf != null ? shaderCBuf.byteSize : 0;

                        if (b.Immediate && b.RootValues.Length > 0)
                            byteSize = (UInt32)(b.RootValues.Length * 4);

                        if (!filledSlot)
                            name = "Empty";

                        if (b != null)
                        {
                            offset = b.Offset;
                            length = b.ByteSize;

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

                        string regname = reg.ToString();

                        if (shaderCBuf != null && shaderCBuf.name.Length > 0)
                            regname += ": " + shaderCBuf.name;

                        string sizestr;
                        if (byteSize == length)
                            sizestr = String.Format("{0} Variables, {1} bytes", numvars, length);
                        else
                            sizestr = String.Format("{0} Variables, {1} bytes needed, {2} provided", numvars, byteSize, length);

                        if (length < byteSize)
                            filledSlot = false;

                        var node = cbuffers.Nodes.Add(new object[] { rootel, space, regname, name, offset, sizestr });

                        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);
                    }
                }
            }
            cbuffers.EndUpdate();
            cbuffers.NodesSelection.Clear();
            cbuffers.SetVScrollValue(vs);
        }
Exemplo n.º 13
0
        private bool HasImportantViewParams(D3D12PipelineState.ResourceView view, FetchBuffer buf)
        {
            if (view.FirstElement > 0 || view.NumElements*view.ElementSize < buf.length)
                return true;

            return false;
        }
Exemplo n.º 14
0
        // 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)
            {
                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
            }

            List<ILogViewerForm> logviewers = new List<ILogViewerForm>();
            logviewers.AddRange(m_LogViewers);

            // 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);
        }
Exemplo n.º 15
0
        private void ExportHTML(XmlTextWriter writer, D3D12PipelineState.InputAssembler ia)
        {
            FetchBuffer[] bufs = m_Core.CurBuffers;

            {
                writer.WriteStartElement("h3");
                writer.WriteString("Input Layouts");
                writer.WriteEndElement();

                List<object[]> rows = new List<object[]>();

                int i = 0;
                foreach (var l in ia.layouts)
                {
                    rows.Add(new object[] { i, l.SemanticName, l.SemanticIndex, l.Format, l.InputSlot, l.ByteOffset, l.PerInstance, l.InstanceDataStepRate });

                    i++;
                }

                ExportHTMLTable(writer, new string[] { "Slot", "Semantic Name", "Semantic Index", "Format", "Input Slot", "Byte Offset", "Per Instance", "Instance Data Step Rate" }, rows.ToArray());
            }

            {
                writer.WriteStartElement("h3");
                writer.WriteString("Vertex Buffers");
                writer.WriteEndElement();

                List<object[]> rows = new List<object[]>();

                int i = 0;
                foreach (var vb in ia.vbuffers)
                {
                    string name = "Buffer " + vb.Buffer.ToString();
                    UInt64 length = 0;

                    if (vb.Buffer == ResourceId.Null)
                    {
                        continue;
                    }
                    else
                    {
                        for (int t = 0; t < bufs.Length; t++)
                        {
                            if (bufs[t].ID == vb.Buffer)
                            {
                                name = bufs[t].name;
                                length = bufs[t].length;
                            }
                        }
                    }

                    rows.Add(new object[] { i, name, vb.Stride, vb.Offset, length });

                    i++;
                }

                ExportHTMLTable(writer, new string[] { "Slot", "Buffer", "Stride", "Offset", "Byte Length" }, rows.ToArray());
            }

            {
                writer.WriteStartElement("h3");
                writer.WriteString("Index Buffer");
                writer.WriteEndElement();

                string name = "Buffer " + ia.ibuffer.Buffer.ToString();
                UInt64 length = 0;

                if (ia.ibuffer.Buffer == ResourceId.Null)
                {
                    name = "Empty";
                }
                else
                {
                    for (int t = 0; t < bufs.Length; t++)
                    {
                        if (bufs[t].ID == ia.ibuffer.Buffer)
                        {
                            name = bufs[t].name;
                            length = bufs[t].length;
                        }
                    }
                }

                string ifmt = "UNKNOWN";
                if (m_Core.CurDrawcall.indexByteWidth == 2)
                    ifmt = "R16_UINT";
                if (m_Core.CurDrawcall.indexByteWidth == 4)
                    ifmt = "R32_UINT";

                ExportHTMLTable(writer, new string[] { "Buffer", "Format", "Offset", "Byte Length" },
                    new object[] { name, ifmt, ia.ibuffer.Offset.ToString(), length.ToString() });
            }

            writer.WriteStartElement("p");
            writer.WriteEndElement();

            ExportHTMLTable(writer, new string[] { "Primitive Topology" }, new object[] { m_Core.CurDrawcall.topology.Str() });
        }
Exemplo n.º 16
0
        private void SetEventID(ILogViewerForm exclude, UInt32 eventID, bool force)
        {
            m_EventID = eventID;

            m_Renderer.Invoke((ReplayRenderer r) =>
            {
                r.SetFrameEvent(m_EventID, force);
                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);
            });

            foreach (var logviewer in m_LogViewers)
            {
                if(logviewer == exclude)
                    continue;

                Control c = (Control)logviewer;
                if (c.InvokeRequired)
                    c.Invoke(new Action(() => logviewer.OnEventSelected(eventID)));
                else
                    logviewer.OnEventSelected(eventID);
            }
        }
Exemplo n.º 17
0
        private object[] ExportViewHTML(D3D12PipelineState.ResourceView view, int i, ShaderReflection refl, string extraParams)
        {
            FetchTexture[] texs = m_Core.CurTextures;
            FetchBuffer[] bufs = m_Core.CurBuffers;

            ShaderResource shaderInput = null;

            bool rw = false;

            if (refl != null)
            {
                foreach (var bind in refl.ReadOnlyResources)
                {
                    if (bind.bindPoint == i)
                    {
                        shaderInput = bind;
                        break;
                    }
                }
                foreach (var bind in refl.ReadWriteResources)
                {
                    if (bind.bindPoint == i)
                    {
                        shaderInput = bind;
                        rw = true;
                        break;
                    }
                }
            }

            string name = "Empty";
            string typename = "Unknown";
            string format = "Unknown";
            UInt64 w = 1;
            UInt32 h = 1, d = 1;
            UInt32 a = 0;

            string viewFormat = view.Format.ToString();

            FetchTexture tex = null;
            FetchBuffer buf = null;

            // check to see if it's a texture
            for (int t = 0; t < texs.Length; t++)
            {
                if (texs[t].ID == view.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 = texs[t].resType.ToString();

                    tex = texs[t];
                }
            }

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

                    if (view.BufferFlags.HasFlag(D3DBufferViewFlags.Raw))
                    {
                        typename = rw ? "RWByteAddressBuffer" : "ByteAddressBuffer";
                    }
                    else if (view.ElementSize > 0)
                    {
                        // for structured buffers, display how many 'elements' there are in the buffer
                        typename = (rw ? "RWStructuredBuffer" : "StructuredBuffer") + "[" + (bufs[t].length / view.ElementSize) + "]";
                    }

                    if (view.CounterResource != ResourceId.Null)
                    {
                        typename += " (Count: " + view.BufferStructCount + ")";
                    }

                    if (shaderInput != null && !shaderInput.IsTexture)
                    {
                        if (view.Format.compType == FormatComponentType.None)
                        {
                            if (shaderInput.variableType.members.Length > 0)
                                viewFormat = format = "struct " + shaderInput.variableType.Name;
                            else
                                viewFormat = format = shaderInput.variableType.Name;
                        }
                        else
                        {
                            format = view.Format.ToString();
                        }
                    }

                    buf = bufs[t];
                }
            }

            string viewParams = "";

            if(buf != null)
            {
                viewParams = String.Format("First Element: {0}, Num Elements {1}, Flags {2}", view.FirstElement, view.NumElements, view.BufferFlags);
            }

            if (tex != null)
            {
                if(tex.mips > 1)
                    viewParams = String.Format("Highest Mip: {0}, Num Mips: {1}", view.HighestMip, view.NumMipLevels);

                if (tex.arraysize > 1)
                {
                    if (viewParams.Length > 0)
                        viewParams += ", ";
                    viewParams += String.Format("First Slice: {0}, Array Size: {1}", view.FirstArraySlice, view.ArraySize);
                }
            }

            if (viewParams == "")
                viewParams = extraParams;
            else
                viewParams += ", " + extraParams;

            return new object[] {
                        i, name,
                        view.Type, typename,
                        w, h, d, a,
                        viewFormat, format,
                        viewParams };
        }