예제 #1
0
        public Dictionary <BindpointMap, BoundResource[]> GetReadOnlyResources(ShaderStageType stage)
        {
            var ret = new Dictionary <BindpointMap, BoundResource[]>();

            if (LogLoaded)
            {
                if (IsLogD3D11)
                {
                    D3D11PipelineState.ShaderStage s = null;

                    switch (stage)
                    {
                    case ShaderStageType.Vertex: s = m_D3D11.m_VS; break;

                    case ShaderStageType.Domain: s = m_D3D11.m_DS; break;

                    case ShaderStageType.Hull: s = m_D3D11.m_HS; break;

                    case ShaderStageType.Geometry: s = m_D3D11.m_GS; break;

                    case ShaderStageType.Pixel: s = m_D3D11.m_PS; break;

                    case ShaderStageType.Compute: s = m_D3D11.m_CS; break;
                    }

                    for (int i = 0; i < s.SRVs.Length; i++)
                    {
                        var key = new BindpointMap(0, i);
                        var val = new BoundResource();

                        val.Id         = s.SRVs[i].Resource;
                        val.HighestMip = (int)s.SRVs[i].HighestMip;
                        val.FirstSlice = (int)s.SRVs[i].FirstArraySlice;

                        ret.Add(key, new BoundResource[] { val });
                    }

                    return(ret);
                }
                else if (IsLogGL)
                {
                    for (int i = 0; i < m_GL.Textures.Length; i++)
                    {
                        var key = new BindpointMap(0, i);
                        var val = new BoundResource();

                        val.Id         = m_GL.Textures[i].Resource;
                        val.HighestMip = (int)m_GL.Textures[i].HighestMip;
                        val.FirstSlice = (int)m_GL.Textures[i].FirstSlice;

                        ret.Add(key, new BoundResource[] { val });
                    }

                    return(ret);
                }
                else if (IsLogVK)
                {
                    VulkanPipelineState.Pipeline.DescriptorSet[] descsets = m_Vulkan.graphics.DescSets;

                    if (stage == ShaderStageType.Compute)
                    {
                        descsets = m_Vulkan.compute.DescSets;
                    }

                    ShaderStageBits mask = (ShaderStageBits)(1 << (int)stage);

                    for (int set = 0; set < m_Vulkan.graphics.DescSets.Length; set++)
                    {
                        var descset = m_Vulkan.graphics.DescSets[set];
                        for (int slot = 0; slot < descset.bindings.Length; slot++)
                        {
                            var bind = descset.bindings[slot];
                            if ((bind.type == ShaderBindType.ImageSampler ||
                                 bind.type == ShaderBindType.InputAttachment ||
                                 bind.type == ShaderBindType.ReadOnlyImage ||
                                 bind.type == ShaderBindType.ReadOnlyTBuffer
                                 ) && (bind.stageFlags & mask) == mask)
                            {
                                var key = new BindpointMap(set, slot);
                                var val = new BoundResource[bind.descriptorCount];

                                for (UInt32 i = 0; i < bind.descriptorCount; i++)
                                {
                                    val[i]            = new BoundResource();
                                    val[i].Id         = bind.binds[i].res;
                                    val[i].HighestMip = (int)bind.binds[i].baseMip;
                                    val[i].FirstSlice = (int)bind.binds[i].baseLayer;
                                }

                                ret.Add(key, val);
                            }
                        }
                    }

                    return(ret);
                }
            }

            return(ret);
        }
예제 #2
0
        public Dictionary <BindpointMap, BoundResource[]> GetReadWriteResources(ShaderStageType stage)
        {
            var ret = new Dictionary <BindpointMap, BoundResource[]>();

            if (LogLoaded)
            {
                if (IsLogD3D11)
                {
                    if (stage == ShaderStageType.Compute)
                    {
                        for (int i = 0; i < m_D3D11.m_CS.UAVs.Length; i++)
                        {
                            var key = new BindpointMap(0, i);
                            var val = new BoundResource();

                            val.Id         = m_D3D11.m_CS.UAVs[i].Resource;
                            val.HighestMip = (int)m_D3D11.m_CS.UAVs[i].HighestMip;
                            val.FirstSlice = (int)m_D3D11.m_CS.UAVs[i].FirstArraySlice;

                            ret.Add(key, new BoundResource[] { val });
                        }
                    }
                    else
                    {
                        for (int i = 0; i < m_D3D11.m_OM.UAVs.Length; i++)
                        {
                            var key = new BindpointMap(0, i);
                            var val = new BoundResource();

                            val.Id         = m_D3D11.m_OM.UAVs[i].Resource;
                            val.HighestMip = (int)m_D3D11.m_OM.UAVs[i].HighestMip;
                            val.FirstSlice = (int)m_D3D11.m_OM.UAVs[i].FirstArraySlice;

                            ret.Add(key, new BoundResource[] { val });
                        }
                    }

                    return(ret);
                }
                else if (IsLogGL)
                {
                    for (int i = 0; i < m_GL.Images.Length; i++)
                    {
                        var key = new BindpointMap(0, i);
                        var val = new BoundResource();

                        val.Id         = m_GL.Images[i].Resource;
                        val.HighestMip = (int)m_GL.Images[i].Level;
                        val.FirstSlice = (int)m_GL.Images[i].Layer;

                        ret.Add(key, new BoundResource[] { val });
                    }

                    return(ret);
                }
                else if (IsLogVK)
                {
                    VulkanPipelineState.Pipeline.DescriptorSet[] descsets = m_Vulkan.graphics.DescSets;

                    if (stage == ShaderStageType.Compute)
                    {
                        descsets = m_Vulkan.compute.DescSets;
                    }

                    ShaderStageBits mask = (ShaderStageBits)(1 << (int)stage);
                    for (int set = 0; set < descsets.Length; set++)
                    {
                        var descset = descsets[set];
                        for (int slot = 0; slot < descset.bindings.Length; slot++)
                        {
                            var bind = descset.bindings[slot];

                            if ((bind.type == ShaderBindType.ReadWriteBuffer ||
                                 bind.type == ShaderBindType.ReadWriteImage ||
                                 bind.type == ShaderBindType.ReadWriteTBuffer
                                 ) && (bind.stageFlags & mask) == mask)
                            {
                                var key = new BindpointMap(set, slot);
                                var val = new BoundResource[bind.descriptorCount];

                                for (UInt32 i = 0; i < bind.descriptorCount; i++)
                                {
                                    val[i]            = new BoundResource();
                                    val[i].Id         = bind.binds[i].res;
                                    val[i].HighestMip = (int)bind.binds[i].baseMip;
                                    val[i].FirstSlice = (int)bind.binds[i].baseLayer;
                                }

                                ret.Add(key, val);
                            }
                        }
                    }

                    return(ret);
                }
            }

            return(ret);
        }
예제 #3
0
        private void UpdateState()
        {
            if (!m_Core.LogLoaded)
            {
                return;
            }

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

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

            bool[] usedVBuffers = new bool[128];

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

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

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

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

                        usedVBuffers[l.BufferSlot] = true;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                    if (!ibufferUsed)
                    {
                        length = 0;
                    }

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

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

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

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

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

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

                    EmptyRow(node);

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

            m_VBNodes.Clear();

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

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

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

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

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

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

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

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

                        m_VBNodes.Add(node);
                    }

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

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

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

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

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

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

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

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

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

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

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

                                tag = texs[t];
                            }
                        }

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

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

                                tag = bufs[t];
                            }
                        }

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

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

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

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

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

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

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

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

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

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

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

            bool[] targets = new bool[8];

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

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

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

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

                                tag = texs[t];
                            }
                        }

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

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

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

                    i++;
                }
            }

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

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

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

                                tag = texs[t];
                            }
                        }

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

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

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

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

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

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

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

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

                // if(streamout only)
                //{
                //    pipeFlow.Rasterizer = false;
                //    pipeFlow.OutputMerger = false;
                //}
            }
        }