private void inputLayouts_NodeDoubleClick(TreelistView.Node node) { (new BufferViewer(m_Core, true)).Show(m_DockContent.DockPanel); }
private void cbuffers_NodeDoubleClicked(TreelistView.Node node) { D3D11PipelineState.ShaderStage stage = GetStageForSender(node.OwnerView); if (stage != null && node.Tag is UInt32) { ShowCBuffer(stage, (UInt32)node.Tag); } }
private void ViewDetailsRow(TreelistView.Node node) { node.BackColor = Color.Aquamarine; m_ViewDetailNodes.Add(node); }
private void InactiveRow(TreelistView.Node node) { node.Italic = true; }
// Set a shader stage's resources and values private void SetShaderState(FetchTexture[] texs, FetchBuffer[] bufs, D3D11PipelineState.ShaderStage stage, Label shader, TreelistView.TreeListView resources, TreelistView.TreeListView samplers, TreelistView.TreeListView cbuffers, TreelistView.TreeListView classes) { ShaderReflection shaderDetails = stage.ShaderDetails; if (stage.Shader == ResourceId.Null) shader.Text = "Unbound"; else shader.Text = stage.ShaderName; 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(); if (stage.SRVs != null) { int i = 0; foreach (var r in stage.SRVs) { ShaderResource shaderInput = null; if (shaderDetails != null) { foreach (var bind in shaderDetails.ReadOnlyResources) { if (bind.IsSRV && bind.bindPoint == i) { shaderInput = bind; break; } } } bool filledSlot = (r.Resource != ResourceId.Null); bool usedSlot = (shaderInput != null); // 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.Length > 0) slotname += ": " + shaderInput.name; UInt64 w = 1; UInt32 h = 1, d = 1; UInt32 a = 1; string format = "Unknown"; string name = "Shader Resource " + r.Resource.ToString(); string typename = "Unknown"; object tag = null; bool viewDetails = false; 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 = 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]); 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 = 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 (r.ElementSize > 0) { typename = "StructuredBuffer[" + (bufs[t].length / r.ElementSize) + "]"; } else if (r.Flags.HasFlag(D3D11BufferViewFlags.Raw)) { typename = "ByteAddressBuffer"; } if (r.Flags.HasFlag(D3D11BufferViewFlags.Append) || r.Flags.HasFlag(D3D11BufferViewFlags.Counter)) { 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 (r.Format.compType == FormatComponentType.None) { if (shaderInput.variableType.members.Length > 0) format = "struct " + shaderInput.variableType.Name; else format = shaderInput.variableType.Name; } else { format = r.Format.ToString(); } } tag = new ViewBufTag(r, bufs[t]); if (HasImportantViewParams(r, bufs[t])) viewDetails = true; } } var node = resources.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); if (viewDetails) ViewDetailsRow(node); } i++; } } resources.EndUpdate(); resources.NodesSelection.Clear(); resources.SetVScrollValue(vs); vs = samplers.VScrollValue(); samplers.BeginUpdate(); samplers.Nodes.Clear(); if (stage.Samplers != null) { int i = 0; foreach (var s in stage.Samplers) { ShaderResource shaderInput = null; if (shaderDetails != null) { foreach (var bind in shaderDetails.ReadOnlyResources) { if (bind.IsSampler && bind.bindPoint == i) { shaderInput = bind; break; } } } bool filledSlot = (s.AddressU.Length > 0); bool usedSlot = (shaderInput != null); // 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.Length > 0) slotname += ": " + shaderInput.name; if (s.customSamplerName) slotname += "(" + s.SamplerName + ")"; string borderColor = s.BorderColor[0].ToString() + ", " + s.BorderColor[1].ToString() + ", " + s.BorderColor[2].ToString() + ", " + s.BorderColor[3].ToString(); string addressing = ""; string addPrefix = ""; string addVal = ""; string[] addr = { s.AddressU, s.AddressV, 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; if(s.UseBorder) addressing += String.Format("<{0}>", borderColor); string filter = s.Filter; if (s.MaxAniso > 0) filter += String.Format(" {0}x", s.MaxAniso); if (s.UseComparison) filter += String.Format(" ({0})", s.Comparison); var node = samplers.Nodes.Add(new object[] { slotname, addressing, filter, (s.MinLOD == -float.MaxValue ? "0" : s.MinLOD.ToString()) + " - " + (s.MaxLOD == float.MaxValue ? "FLT_MAX" : s.MaxLOD.ToString()), s.MipLODBias.ToString() }); if (!filledSlot) EmptyRow(node); if (!usedSlot) InactiveRow(node); } i++; } } samplers.EndUpdate(); samplers.NodesSelection.Clear(); samplers.SetVScrollValue(vs); vs = cbuffers.VScrollValue(); cbuffers.BeginUpdate(); cbuffers.Nodes.Clear(); if (stage.ConstantBuffers != null) { UInt32 i = 0; foreach (var b in stage.ConstantBuffers) { ConstantBlock shaderCBuf = null; if (shaderDetails != null && i < shaderDetails.ConstantBlocks.Length && shaderDetails.ConstantBlocks[i].name.Length > 0) shaderCBuf = shaderDetails.ConstantBlocks[i]; bool filledSlot = (b.Buffer != ResourceId.Null); bool usedSlot = (shaderCBuf != null); // 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 = 1; int numvars = shaderCBuf != null ? shaderCBuf.variables.Length : 0; UInt32 byteSize = shaderCBuf != null ? shaderCBuf.byteSize : 0; if (!filledSlot) { name = "Empty"; length = 0; } for (int t = 0; t < bufs.Length; t++) { if (bufs[t].ID == b.Buffer) { name = bufs[t].name; length = bufs[t].length; } } string slotname = i.ToString(); if (shaderCBuf != null && shaderCBuf.name.Length > 0) slotname += ": " + 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; string vecrange = String.Format("{0} - {1}", b.VecOffset, b.VecOffset + b.VecCount); var node = cbuffers.Nodes.Add(new object[] { slotname, name, vecrange, sizestr }); node.Image = global::renderdocui.Properties.Resources.action; node.HoverImage = global::renderdocui.Properties.Resources.action_hover; node.Tag = i; if (!filledSlot) EmptyRow(node); if (!usedSlot) InactiveRow(node); } i++; } } cbuffers.EndUpdate(); cbuffers.NodesSelection.Clear(); cbuffers.SetVScrollValue(vs); vs = classes.VScrollValue(); classes.BeginUpdate(); classes.Nodes.Clear(); { UInt32 i = 0; foreach (var inst in stage.ClassInstances) { string interfaceName = String.Format("Interface {0}", i); if (shaderDetails != null && i < shaderDetails.Interfaces.Length) interfaceName = shaderDetails.Interfaces[i].Name; classes.Nodes.Add(new object[] { i.ToString(), interfaceName, inst }); i++; } } classes.EndUpdate(); classes.NodesSelection.Clear(); classes.SetVScrollValue(vs); classes.Visible = classes.Parent.Visible = (stage.ClassInstances.Length > 0); }
private int SetFindIcons(TreelistView.NodeCollection nodes, string filter) { int results = 0; foreach (var n in nodes) { if (n.Tag is DeferredEvent) { if (n["Name"].ToString().ToUpperInvariant().Contains(filter)) { if (!IsBookmarked((UInt32)n["EID"])) n.Image = global::renderdocui.Properties.Resources.find; results++; } } if (n.Nodes.Count > 0) { results += SetFindIcons(n.Nodes, filter); } } return results; }
private int FindEvent(TreelistView.NodeCollection nodes, string filter, UInt32 after, bool forward) { if(nodes == null) return -1; for (int i = forward ? 0 : nodes.Count - 1; i >= 0 && i < nodes.Count; i += forward ? 1 : -1) { var n = nodes[i]; if (n.Tag is DeferredEvent) { DeferredEvent def = n.Tag as DeferredEvent; bool matchesAfter = (forward && def.eventID > after) || (!forward && def.eventID < after); if (matchesAfter && n["Name"].ToString().ToUpperInvariant().Contains(filter)) return (int)def.eventID; } if (n.Nodes.Count > 0) { int found = FindEvent(n.Nodes, filter, after, forward); if (found > 0) return found; } } return -1; }
private void ClearFindIcons(TreelistView.NodeCollection nodes) { foreach (var n in nodes) { if (!IsBookmarked(GetNodeEventID(n))) n.Image = null; if (n.Nodes.Count > 0) { ClearFindIcons(n.Nodes); } } }
private uint GetNodeEventID(TreelistView.Node n) { DeferredEvent def = n.Tag as DeferredEvent; if (def != null) return def.eventID; return 0; }
private void hosts_NodeDoubleClicked(TreelistView.Node node) { ConnectToHost(node); }
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; }
private void ConnectToHost(TreelistView.Node node) { if (node != null && node.Tag != null) { var connect = node.Tag as RemoteConnect; var live = new LiveCapture(m_Core, connect.host, connect.ident, m_Main); m_Main.ShowLiveCapture(live); Close(); } }
private void AddVariables(TreelistView.NodeCollection root, ShaderVariable[] vars) { foreach (var v in vars) { TreelistView.Node n = root.Add(new TreelistView.Node(new object[] { v.name, v, v.TypeString() })); if (v.rows > 1) { for (int i = 0; i < v.rows; i++) { n.Nodes.Add(new TreelistView.Node(new object[] { String.Format("{0}.row{1}", v.name, i), v.Row(i), v.RowTypeString() })); } } if (v.members.Length > 0) { AddVariables(n.Nodes, v.members); } } }
// Set a shader stage's resources and values private void SetShaderState(FetchTexture[] texs, FetchBuffer[] bufs, GLPipelineState state, GLPipelineState.ShaderStage stage, TableLayoutPanel table, Label shader, TreelistView.TreeListView textures, TreelistView.TreeListView samplers, TreelistView.TreeListView cbuffers, TreelistView.TreeListView subs, TreelistView.TreeListView readwrites) { ShaderReflection shaderDetails = stage.ShaderDetails; var mapping = stage.BindpointMapping; if (stage.Shader == ResourceId.Null) shader.Text = "Unbound"; else shader.Text = stage.stage.Str(APIPipelineStateType.OpenGL) + " Shader " + stage.Shader.ToString(); // disabled since entry function is always main, and filenames have no names, so this is useless. /* if (shaderDetails != null && shaderDetails.DebugInfo.entryFunc != "" && shaderDetails.DebugInfo.files.Length > 0) shader.Text = shaderDetails.DebugInfo.entryFunc + "()" + " - " + Path.GetFileName(shaderDetails.DebugInfo.files[0].filename); */ int vs = 0; int vs2 = 0; // simultaneous update of resources and samplers vs = textures.VScrollValue(); textures.BeginUpdate(); textures.Nodes.Clear(); vs2 = samplers.VScrollValue(); samplers.BeginUpdate(); samplers.Nodes.Clear(); if (state.Textures != null) { for (int i = 0; i < state.Textures.Length; i++) { var r = state.Textures[i]; var s = state.Samplers[i]; ShaderResource shaderInput = null; BindpointMap map = null; if (shaderDetails != null) { foreach (var bind in shaderDetails.Resources) { if (bind.IsSRV && !bind.IsReadWrite && 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" ) { // do texture { 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 = texs[t].resType.Str(); if (texs[t].format.special && (texs[t].format.specialFormat == SpecialFormat.D24S8 || texs[t].format.specialFormat == SpecialFormat.D32S8) ) { if (r.DepthReadChannel == 0) format += " Depth-Read"; else if (r.DepthReadChannel == 1) format += " Stencil-Read"; } else if ( r.Swizzle[0] != TextureSwizzle.Red || r.Swizzle[1] != TextureSwizzle.Green || r.Swizzle[2] != TextureSwizzle.Blue || r.Swizzle[3] != TextureSwizzle.Alpha) { format += String.Format(" swizzle[{0}{1}{2}{3}]", r.Swizzle[0].Str(), r.Swizzle[1].Str(), r.Swizzle[2].Str(), r.Swizzle[3].Str()); } tag = texs[t]; } } var node = textures.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); } // do sampler { string slotname = i.ToString(); if (shaderInput != null && shaderInput.name.Length > 0) slotname += ": " + shaderInput.name; string borderColor = s.BorderColor[0].ToString() + ", " + s.BorderColor[1].ToString() + ", " + s.BorderColor[2].ToString() + ", " + s.BorderColor[3].ToString(); string addressing = ""; string addPrefix = ""; string addVal = ""; string[] addr = { s.AddressS, s.AddressT, s.AddressR }; // arrange like either STR: WRAP or ST: WRAP, R: CLAMP for (int a = 0; a < 3; a++) { string prefix = "" + "STR"[a]; if (a == 0 || addr[a] == addr[a - 1]) { addPrefix += prefix; } else { addressing += addPrefix + ": " + addVal + ", "; addPrefix = prefix; } addVal = addr[a]; } addressing += addPrefix + ": " + addVal; if (s.UseBorder) addressing += String.Format("<{0}>", borderColor); if (r.ResType == ShaderResourceType.TextureCube || r.ResType == ShaderResourceType.TextureCubeArray) { addressing += s.SeamlessCube ? " Seamless" : " Non-Seamless"; } string minfilter = s.MinFilter; if (s.MaxAniso > 1) minfilter += String.Format(" Aniso{0}x", s.MaxAniso); if (s.UseComparison) minfilter = String.Format("{0}", s.Comparison); var node = samplers.Nodes.Add(new object[] { slotname, addressing, minfilter, s.MagFilter, (s.MinLOD == -float.MaxValue ? "0" : s.MinLOD.ToString()) + " - " + (s.MaxLOD == float.MaxValue ? "FLT_MAX" : s.MaxLOD.ToString()), s.MipLODBias.ToString() }); if (!filledSlot) EmptyRow(node); if (!usedSlot) InactiveRow(node); } } } } textures.EndUpdate(); textures.NodesSelection.Clear(); textures.SetVScrollValue(vs); samplers.EndUpdate(); samplers.NodesSelection.Clear(); samplers.SetVScrollValue(vs2); vs = cbuffers.VScrollValue(); cbuffers.BeginUpdate(); cbuffers.Nodes.Clear(); if (shaderDetails != null) { UInt32 i = 0; foreach (var shaderCBuf in shaderDetails.ConstantBlocks) { int bindPoint = stage.BindpointMapping.ConstantBlocks[i].bind; GLPipelineState.Buffer b = null; if (bindPoint >= 0 && bindPoint < state.UniformBuffers.Length) b = state.UniformBuffers[bindPoint]; bool filledSlot = !shaderCBuf.bufferBacked || (b != null && b.Resource != ResourceId.Null); bool usedSlot = stage.BindpointMapping.ConstantBlocks[i].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" ) { ulong offset = 0; ulong length = 0; int numvars = shaderCBuf.variables.Length; string slotname = "Uniforms"; string name = ""; string sizestr = String.Format("{0} Variables", numvars); string byterange = ""; if (!filledSlot) { name = "Empty"; length = 0; } if (b != null) { slotname = String.Format("{0}: {1}", bindPoint, shaderCBuf.name); name = "UBO " + b.Resource.ToString(); offset = b.Offset; length = b.Size; for (int t = 0; t < bufs.Length; t++) { if (bufs[t].ID == b.Resource) { name = bufs[t].name; if (length == 0) length = bufs[t].length; } } sizestr = String.Format("{0} Variables, {1} bytes", numvars, length); byterange = String.Format("{0} - {1}", offset, offset + length); } var node = cbuffers.Nodes.Add(new object[] { slotname, name, byterange, sizestr }); node.Image = global::renderdocui.Properties.Resources.action; node.HoverImage = global::renderdocui.Properties.Resources.action_hover; node.Tag = i; if (!filledSlot) EmptyRow(node); if (!usedSlot) InactiveRow(node); } i++; } } cbuffers.EndUpdate(); cbuffers.NodesSelection.Clear(); cbuffers.SetVScrollValue(vs); vs = subs.VScrollValue(); subs.BeginUpdate(); subs.Nodes.Clear(); { UInt32 i = 0; foreach (var subval in stage.Subroutines) { subs.Nodes.Add(new object[] { i.ToString(), subval.ToString() }); i++; } } subs.EndUpdate(); subs.NodesSelection.Clear(); subs.SetVScrollValue(vs); { subs.Visible = subs.Parent.Visible = (stage.Subroutines.Length > 0); int row = table.GetRow(subs.Parent); if (row >= 0 && row < table.RowStyles.Count) { if (stage.Subroutines.Length > 0) table.RowStyles[row].Height = table.RowStyles[1].Height; else table.RowStyles[row].Height = 0; } } vs = readwrites.VScrollValue(); readwrites.BeginUpdate(); readwrites.Nodes.Clear(); if (shaderDetails != null) { UInt32 i = 0; foreach (var res in shaderDetails.Resources) { int bindPoint = stage.BindpointMapping.Resources[i].bind; bool atomic = false; bool ssbo = false; bool image = false; if (!res.IsReadWrite) { i++; continue; } GLPipelineState.Buffer bf = null; GLPipelineState.ImageLoadStore im = null; ResourceId id = ResourceId.Null; if (res.IsTexture) { image = true; if (bindPoint >= 0 && bindPoint < state.Images.Length) { im = state.Images[bindPoint]; id = state.Images[bindPoint].Resource; } } else { if (res.variableType.descriptor.rows == 1 && res.variableType.descriptor.cols == 1 && res.variableType.descriptor.type == VarType.UInt) { atomic = true; if (bindPoint >= 0 && bindPoint < state.AtomicBuffers.Length) { bf = state.AtomicBuffers[bindPoint]; id = state.AtomicBuffers[bindPoint].Resource; } } else { ssbo = true; if (bindPoint >= 0 && bindPoint < state.ShaderStorageBuffers.Length) { bf = state.ShaderStorageBuffers[bindPoint]; id = state.ShaderStorageBuffers[bindPoint].Resource; } } } bool filledSlot = id != ResourceId.Null; bool usedSlot = stage.BindpointMapping.Resources[i].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 binding = image ? "Image" : atomic ? "Atomic" : ssbo ? "SSBO" : "Unknown"; string slotname = String.Format("{0}: {1}", bindPoint, res.name); string name = ""; string dimensions = ""; string format = "-"; string access = "Read/Write"; if (im != null) { if (im.readAllowed && !im.writeAllowed) access = "Read-Only"; if (!im.readAllowed && im.writeAllowed) access = "Write-Only"; format = im.Format.ToString(); } object tag = null; // check to see if it's a texture for (int t = 0; t < texs.Length; t++) { if (texs[t].ID == id) { if (texs[t].dimension == 1) { if(texs[t].arraysize > 1) dimensions = String.Format("{0}[{1}]", texs[t].width, texs[t].arraysize); else dimensions = String.Format("{0}", texs[t].width); } else if (texs[t].dimension == 2) { if (texs[t].arraysize > 1) dimensions = String.Format("{0}x{1}[{2}]", texs[t].width, texs[t].height, texs[t].arraysize); else dimensions = String.Format("{0}x{1}", texs[t].width, texs[t].height); } else if (texs[t].dimension == 3) { dimensions = String.Format("{0}x{1}x{2}", texs[t].width, texs[t].height, texs[t].depth); } name = texs[t].name; tag = texs[t]; } } // if not a texture, it must be a buffer for (int t = 0; t < bufs.Length; t++) { if (bufs[t].ID == id) { ulong offset = 0; ulong length = bufs[t].length; if (bf != null && bf.Size > 0) { offset = bf.Offset; length = bf.Size; } if(offset > 0) dimensions = String.Format("{0} bytes at offset {1} bytes", length, offset); else dimensions = String.Format("{0} bytes", length); name = bufs[t].name; tag = new ReadWriteTag(i, bufs[t]); } } if (!filledSlot) { name = "Empty"; dimensions = "-"; access = "-"; } var node = readwrites.Nodes.Add(new object[] { binding, slotname, name, dimensions, format, access }); 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++; } } readwrites.EndUpdate(); readwrites.NodesSelection.Clear(); readwrites.SetVScrollValue(vs); { readwrites.Visible = readwrites.Parent.Visible = (readwrites.Nodes.Count > 0); int row = table.GetRow(readwrites.Parent); if (row >= 0 && row < table.RowStyles.Count) { if (readwrites.Nodes.Count > 0) table.RowStyles[row].Height = table.RowStyles[1].Height; else table.RowStyles[row].Height = 0; } } }
private bool FindEventNode(ref TreelistView.Node found, UInt32 frameID, UInt32 eventID) { bool ret = FindEventNode(ref found, eventView.Nodes[0].Nodes, frameID, eventID); while (found != null && found.NextSibling != null && found.NextSibling.Tag is DeferredEvent) { DeferredEvent def = found.NextSibling.Tag as DeferredEvent; if (def.eventID == eventID) found = found.NextSibling; else break; } return ret; }
public static PersistData GetDefaults(TreelistView.TreeListView view) { PersistData data = new PersistData(); foreach (var c in view.Columns) { ColumnArrangement a = new ColumnArrangement(); a.fieldname = c.Fieldname; a.visibleindex = c.VisibleIndex; a.width = c.Width; data.visibleColumns.Add(a); } return data; }
private void ClearFindIcons(TreelistView.NodeCollection nodes) { foreach (var n in nodes) { if (!IsBookmarked((UInt32)n["EID"])) n.Image = null; if (n.Nodes.Count > 0) { ClearFindIcons(n.Nodes); } } }
private string DataToString(TreelistView.TreeListColumn column, object data) { if (column.Fieldname == "Duration") { double f = (double)data; if (f < 0.0) return ""; if (m_Core.Config.EventBrowser_TimeUnit != m_TimeUnit) UpdateDurationColumn(); 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; return Formatter.Format(f); } return data.ToString(); }
private TreelistView.Node FindNode(TreelistView.NodeCollection nodes, string filter, UInt32 after) { foreach (var n in nodes) { if (n.Tag is DeferredEvent) { if ((UInt32)n["EID"] > after && n["Name"].ToString().ToUpperInvariant().Contains(filter)) return n; } if (n.Nodes.Count > 0) { TreelistView.Node found = FindNode(n.Nodes, filter, after); if (found != null) return found; } } return null; }
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; }
private void iabuffers_NodeDoubleClicked(TreelistView.Node node) { if (node.Tag is IABufferTag) { IABufferTag tag = (IABufferTag)node.Tag; if (tag.id != ResourceId.Null) { var viewer = new BufferViewer(m_Core, false); viewer.ViewRawBuffer(true, tag.offset, ulong.MaxValue, tag.id); viewer.Show(m_DockContent.DockPanel); } } }
private void SetDrawcallTimes(TreelistView.Node n, Dictionary<uint, List<CounterResult>> times) { if (n == null || times == null) return; // parent nodes take the value of the sum of their children double duration = 0.0; // look up leaf nodes in the dictionary if (n.Nodes.IsEmpty()) { uint eid = (uint)n["EID"]; if (times.ContainsKey(eid)) duration = times[eid][0].value.d; else duration = -1.0; n["Duration"] = duration; return; } for (int i = 0; i < n.Nodes.Count; i++) { SetDrawcallTimes(n.Nodes[i], times); double nd = (double)n.Nodes[i]["Duration"]; if(nd > 0.0) duration += nd; } n["Duration"] = duration; }
private void inputLayouts_NodeDoubleClick(TreelistView.Node node) { var viewer = m_Core.GetMeshViewer(); viewer.Show(m_DockContent.DockPanel); }
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(); }
// launch the appropriate kind of viewer, depending on the type of resource that's in this node private void textureCell_CellDoubleClick(TreelistView.Node node) { object tag = node.Tag; D3D11PipelineState.ShaderStage stage = GetStageForSender(node.OwnerView); if (stage == null) return; D3D11PipelineState.ShaderStage.ResourceView view = null; if (tag is ViewTexTag) { view = (tag as ViewTexTag).view; tag = (tag as ViewTexTag).tex; } if (tag is ViewBufTag) { view = (tag as ViewBufTag).view; tag = (tag as ViewBufTag).buf; } if (tag is FetchTexture) { FetchTexture tex = (FetchTexture)tag; if (tex.resType == ShaderResourceType.Buffer) { var viewer = new BufferViewer(m_Core, false); viewer.ViewRawBuffer(false, view.FirstElement, view.NumElements*view.ElementSize, tex.ID); viewer.Show(m_DockContent.DockPanel); } else { var viewer = m_Core.GetTextureViewer(); viewer.Show(m_DockContent.DockPanel); if (!viewer.IsDisposed) viewer.ViewTexture(tex.ID, true); } } else if(tag is FetchBuffer) { FetchBuffer buf = (FetchBuffer)tag; string format = ""; var deets = stage.ShaderDetails; int bind = -1; bool uav = false; for (int i = 0; i < stage.SRVs.Length; i++) { if (stage.SRVs[i].Resource == buf.ID) { bind = i; view = stage.SRVs[i]; break; } } for (int i = 0; i < stage.UAVs.Length; i++) { if (stage.UAVs[i].Resource == buf.ID) { bind = i; uav = true; view = stage.UAVs[i]; break; } if (stage == m_Core.CurD3D11PipelineState.m_PS && m_Core.CurD3D11PipelineState.m_OM.UAVs[i].Resource == buf.ID) { bind = i + (int)m_Core.CurD3D11PipelineState.m_OM.UAVStartSlot; uav = true; view = m_Core.CurD3D11PipelineState.m_OM.UAVs[i]; break; } } if (deets != null) { ShaderResource[] resources = uav ? deets.ReadWriteResources : deets.ReadOnlyResources; foreach (var r in resources) { if (r.IsTexture) continue; if (r.bindPoint == bind) { if (r.variableType.members.Length == 0) { if (view != null) { if (view.Format.special && view.Format.specialFormat == SpecialFormat.R10G10B10A2) { if (view.Format.compType == FormatComponentType.UInt) format = "uintten"; if (view.Format.compType == FormatComponentType.UNorm) format = "unormten"; } else if (!view.Format.special) { switch (view.Format.compByteWidth) { case 1: { if (view.Format.compType == FormatComponentType.UNorm) format = "unormb"; if (view.Format.compType == FormatComponentType.SNorm) format = "snormb"; if (view.Format.compType == FormatComponentType.UInt) format = "ubyte"; if (view.Format.compType == FormatComponentType.SInt) format = "byte"; break; } case 2: { if (view.Format.compType == FormatComponentType.UNorm) format = "unormh"; if (view.Format.compType == FormatComponentType.SNorm) format = "snormh"; if (view.Format.compType == FormatComponentType.UInt) format = "ushort"; if (view.Format.compType == FormatComponentType.SInt) format = "short"; if (view.Format.compType == FormatComponentType.Float) format = "half"; break; } case 4: { if (view.Format.compType == FormatComponentType.UNorm) format = "unormf"; if (view.Format.compType == FormatComponentType.SNorm) format = "snormf"; if (view.Format.compType == FormatComponentType.UInt) format = "uint"; if (view.Format.compType == FormatComponentType.SInt) format = "int"; if (view.Format.compType == FormatComponentType.Float) format = "float"; break; } } if (view.Flags.HasFlag(D3D11BufferViewFlags.Raw)) format = "xint"; format += view.Format.compCount; } } // if view format is unknown, use the variable type if (!view.Format.special && view.Format.compCount == 0 && view.Format.compByteWidth == 0 && r.variableType.Name.Length > 0) format = r.variableType.Name; format += " " + r.name + ";"; } else { format = "// struct " + r.variableType.Name + Environment.NewLine + "{" + Environment.NewLine + FormatMembers(1, "", r.variableType.members) + "}"; } break; } } } if (buf.ID != ResourceId.Null) { var viewer = new BufferViewer(m_Core, false); if (format.Length == 0) viewer.ViewRawBuffer(true, view.FirstElement * view.ElementSize, view.NumElements * view.ElementSize, buf.ID); else viewer.ViewRawBuffer(true, view.FirstElement * view.ElementSize, view.NumElements * view.ElementSize, buf.ID, format); viewer.Show(m_DockContent.DockPanel); } } }
public void ExpandNode(TreelistView.Node node) { var n = node; while (node != null) { node.Expand(); node = node.Parent; } eventView.EnsureVisible(n); }
private void ClearShaderState(Label shader, TreelistView.TreeListView resources, TreelistView.TreeListView samplers, TreelistView.TreeListView cbuffers, TreelistView.TreeListView classes) { shader.Text = "Unbound"; resources.Nodes.Clear(); samplers.Nodes.Clear(); cbuffers.Nodes.Clear(); classes.Nodes.Clear(); }
private bool FindEventNode(ref TreelistView.Node found, TreelistView.NodeCollection nodes, UInt32 frameID, UInt32 eventID) { foreach (var n in nodes) { DeferredEvent ndef = n.Tag is DeferredEvent ? n.Tag as DeferredEvent : null; DeferredEvent fdef = found != null && found.Tag is DeferredEvent ? found.Tag as DeferredEvent : null; if (ndef != null) { if (ndef.eventID >= eventID && (found == null || ndef.eventID <= fdef.eventID)) found = n; if (ndef.eventID == eventID && n.Nodes.Count == 0) return true; } if (n.Nodes.Count > 0) { bool exact = FindEventNode(ref found, n.Nodes, frameID, eventID); if (exact) return true; } } return false; }
private void EmptyRow(TreelistView.Node node) { node.BackColor = Color.FromArgb(255, 70, 70); }
private void iabuffers_NodeDoubleClicked(TreelistView.Node node) { if (node.Tag is ResourceId) { ResourceId id = (ResourceId)node.Tag; if (id != ResourceId.Null) { var viewer = new BufferViewer(m_Core, false); viewer.ViewRawBuffer(true, id); viewer.Show(m_DockContent.DockPanel); } } }