diff --git a/renderdoc/api/replay/d3d12_pipestate.h b/renderdoc/api/replay/d3d12_pipestate.h index dc6733ae5..4dfb2b48e 100644 --- a/renderdoc/api/replay/d3d12_pipestate.h +++ b/renderdoc/api/replay/d3d12_pipestate.h @@ -359,4 +359,16 @@ struct D3D12PipelineState uint32_t multiSampleCount; uint32_t multiSampleQuality; } m_OM; + + struct ResourceData + { + ResourceId id; + + struct ResourceState + { + rdctype::str name; + }; + rdctype::array states; + }; + rdctype::array Resources; }; diff --git a/renderdoc/driver/d3d12/d3d12_device.h b/renderdoc/driver/d3d12/d3d12_device.h index a73c270ae..1d9902d1b 100644 --- a/renderdoc/driver/d3d12/d3d12_device.h +++ b/renderdoc/driver/d3d12/d3d12_device.h @@ -329,7 +329,7 @@ public: { return m_ResourceStates[id]; } - + const map &GetSubresourceStates() { return m_ResourceStates; } const pair GetBackbufferFormat() { return m_BackbufferFormat; } void SetLogFile(const char *logfile); void SetLogVersion(uint32_t fileversion) { m_InitParams.SerialiseVersion = fileversion; } diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index b99f2c194..fa62fdcaf 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -1033,6 +1033,25 @@ void D3D12Replay::MakePipelineState() state.m_OM.m_State.m_BackFace.FailOp = ToStr::Get(src.BackFace.StencilFailOp); } } + + // resource states + { + const map &states = m_pDevice->GetSubresourceStates(); + create_array_uninit(state.Resources, states.size()); + size_t i = 0; + for(auto it = states.begin(); it != states.end(); ++it) + { + D3D12PipelineState::ResourceData &res = state.Resources[i]; + + res.id = rm->GetOriginalID(it->first); + + create_array_uninit(res.states, it->second.size()); + for(size_t l = 0; l < it->second.size(); l++) + res.states[l].name = ToStr::Get(it->second[l]); + + i++; + } + } } void D3D12Replay::RenderCheckerboard(Vec3f light, Vec3f dark) diff --git a/renderdocui/Code/CommonPipelineState.cs b/renderdocui/Code/CommonPipelineState.cs index 5fa526280..bc1d4eb41 100644 --- a/renderdocui/Code/CommonPipelineState.cs +++ b/renderdocui/Code/CommonPipelineState.cs @@ -191,8 +191,8 @@ namespace renderdocui.Code if (IsLogVK && m_Vulkan.Images.ContainsKey(id)) return m_Vulkan.Images[id].layouts[0].name; - if (IsLogD3D12) - return "TODO"; + if (IsLogD3D12 && m_D3D12.Resources.ContainsKey(id)) + return m_D3D12.Resources[id].states[0].name; } return "Unknown"; diff --git a/renderdocui/Interop/D3D12PipelineState.cs b/renderdocui/Interop/D3D12PipelineState.cs index f052c4782..109c55332 100644 --- a/renderdocui/Interop/D3D12PipelineState.cs +++ b/renderdocui/Interop/D3D12PipelineState.cs @@ -25,6 +25,7 @@ using System; using System.Runtime.InteropServices; +using System.Collections.Generic; namespace renderdoc { @@ -353,5 +354,36 @@ namespace renderdoc }; [CustomMarshalAs(CustomUnmanagedType.CustomClass)] public OutputMerger m_OM; + + [StructLayout(LayoutKind.Sequential)] + public class ResourceData + { + public ResourceId id; + + [StructLayout(LayoutKind.Sequential)] + public class ResourceState + { + [CustomMarshalAs(CustomUnmanagedType.UTF8TemplatedString)] + public string name; + }; + + [CustomMarshalAs(CustomUnmanagedType.TemplatedArray)] + public ResourceState[] states; + }; + + [CustomMarshalAs(CustomUnmanagedType.TemplatedArray)] + private ResourceData[] Resources_; + + // add to dictionary for convenience + private void PostMarshal() + { + Resources = new Dictionary(); + + foreach (ResourceData i in Resources_) + Resources.Add(i.id, i); + } + + [CustomMarshalAs(CustomUnmanagedType.Skip)] + public Dictionary Resources; }; } diff --git a/renderdocui/Windows/PipelineState/D3D12PipelineStateViewer.cs b/renderdocui/Windows/PipelineState/D3D12PipelineStateViewer.cs index 62f727a67..6c5cae098 100644 --- a/renderdocui/Windows/PipelineState/D3D12PipelineStateViewer.cs +++ b/renderdocui/Windows/PipelineState/D3D12PipelineStateViewer.cs @@ -246,10 +246,13 @@ namespace renderdocui.Windows.PipelineState node.Italic = true; } - private void ViewDetailsRow(TreelistView.Node node) + private void ViewDetailsRow(TreelistView.Node node, bool highlight) { - node.BackColor = Color.Aquamarine; - node.ForeColor = Color.Black; + if (highlight) + { + node.BackColor = Color.Aquamarine; + node.ForeColor = Color.Black; + } m_ViewDetailNodes.Add(node); } @@ -460,8 +463,7 @@ namespace renderdocui.Windows.PipelineState if (!usedSlot) InactiveRow(node); - if (viewDetails) - ViewDetailsRow(node); + ViewDetailsRow(node, viewDetails); } } @@ -1254,8 +1256,7 @@ namespace renderdocui.Windows.PipelineState { targets[i] = true; - if (viewDetails) - ViewDetailsRow(node); + ViewDetailsRow(node, viewDetails); } } @@ -1318,8 +1319,7 @@ namespace renderdocui.Windows.PipelineState node.HoverImage = global::renderdocui.Properties.Resources.action_hover; node.Tag = tag; - if (viewDetails) - ViewDetailsRow(node); + ViewDetailsRow(node, viewDetails); if (state.m_OM.DepthTarget.Resource == ResourceId.Null) EmptyRow(node); @@ -1517,8 +1517,8 @@ namespace renderdocui.Windows.PipelineState if (tex != null) { - //if (m_Core.CurD3D12PipelineState.ResourceStates.ContainsKey(tex.tex.ID)) - //text += String.Format("Texture is in the '{0}' state\n\n", m_Core.CurVulkanPipelineState.ResourceStates[tex.tex.ID].states[0].name); + if (m_Core.CurD3D12PipelineState.Resources.ContainsKey(tex.tex.ID)) + text += String.Format("Texture is in the '{0}' state\n\n", m_Core.CurD3D12PipelineState.Resources[tex.tex.ID].states[0].name); if (tex.tex.format != tex.view.Format) text += String.Format("The texture is format {0}, the view treats it as {1}.\n", @@ -1549,8 +1549,8 @@ namespace renderdocui.Windows.PipelineState } else if (buf != null) { - //if (m_Core.CurD3D12PipelineState.ResourceStates.ContainsKey(buf.tex.ID)) - //text += String.Format("Texture is in the '{0}' state\n\n", m_Core.CurVulkanPipelineState.ResourceStates[buf.tex.ID].states[0].name); + if (m_Core.CurD3D12PipelineState.Resources.ContainsKey(buf.buf.ID)) + text += String.Format("Texture is in the '{0}' state\n\n", m_Core.CurD3D12PipelineState.Resources[buf.buf.ID].states[0].name); text += String.Format("The view covers bytes {0}-{1} ({2} elements).\nThe buffer is {3} bytes in length ({4} elements).", buf.view.FirstElement * buf.view.ElementSize, diff --git a/renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.cs b/renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.cs index 8cd32df1e..ca4062cd7 100644 --- a/renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.cs +++ b/renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.cs @@ -255,8 +255,11 @@ namespace renderdocui.Windows.PipelineState private void ViewDetailsRow(TreelistView.Node node, bool highlight) { - if(highlight) + if (highlight) + { node.BackColor = Color.Aquamarine; + node.ForeColor = Color.Black; + } m_ViewDetailNodes.Add(node); }