public void UpdateDebugging() { if (m_Trace == null || m_Trace.states.Length == 0) { //curInstruction.Text = "0"; for (int i = 0; i < m_DisassemblyView.Lines.Count; i++) { m_DisassemblyView.Lines[i].DeleteMarkerSet(CurrentLineMarkers); m_DisassemblyView.Lines[i].DeleteMarkerSet(FinishedMarkers); } return; } var state = m_Trace.states[CurrentStep]; //curInstruction.Text = CurrentStep.ToString(); UInt32 nextInst = state.nextInstruction; bool done = false; if (CurrentStep == m_Trace.states.Length - 1) { nextInst--; done = true; } // add current instruction marker for (int i = 0; i < m_DisassemblyView.Lines.Count; i++) { m_DisassemblyView.Lines[i].DeleteMarkerSet(CurrentLineMarkers); m_DisassemblyView.Lines[i].DeleteMarkerSet(FinishedMarkers); if (m_DisassemblyView.Lines[i].Text.Trim().StartsWith(nextInst.ToString() + ":")) { m_DisassemblyView.Lines[i].AddMarkerSet(done ? FinishedMarkers : CurrentLineMarkers); m_DisassemblyView.Caret.LineNumber = i; if (!m_DisassemblyView.Lines[i].IsVisible) { m_DisassemblyView.Scrolling.ScrollToCaret(); } } } m_DisassemblyView.Invalidate(); if (constantRegs.Nodes.IsEmpty()) { constantRegs.BeginUpdate(); for (int i = 0; i < m_Trace.cbuffers.Length; i++) { for (int j = 0; j < m_Trace.cbuffers[i].variables.Length; j++) { if (m_Trace.cbuffers[i].variables[j].rows > 0 || m_Trace.cbuffers[i].variables[j].columns > 0) { constantRegs.Nodes.Add(new TreelistView.Node(new object[] { m_Trace.cbuffers[i].variables[j].name, "cbuffer", StringRep(m_Trace.cbuffers[i].variables[j], false) })); } } } foreach (var input in m_Trace.inputs) { constantRegs.Nodes.Add(new TreelistView.Node(new object[] { input.name, input.type.ToString() + " input", StringRep(input, true) })); } var pipestate = m_Core.CurD3D11PipelineState; foreach (var slot in m_ShaderDetails.Resources) { if (slot.IsSampler) { continue; } var res = m_Stage.SRVs[slot.bindPoint]; if (slot.IsUAV) { if (m_Stage.stage == ShaderStageType.Pixel) { res = pipestate.m_OM.UAVs[slot.bindPoint - pipestate.m_OM.UAVStartSlot]; } else { res = m_Stage.UAVs[slot.bindPoint]; } } bool found = false; var name = slot.bindPoint + " (" + slot.name + ")"; foreach (var tex in m_Core.CurTextures) { if (tex.ID == res.Resource) { constantRegs.Nodes.Add(new TreelistView.Node(new object[] { "t" + name, "Texture", tex.width + "x" + tex.height + "x" + (tex.depth > 1 ? tex.depth : tex.arraysize) + "[" + tex.mips + "] @ " + tex.format + " - " + tex.name })); found = true; break; } } if (!found) { foreach (var buf in m_Core.CurBuffers) { if (buf.ID == res.Resource) { string prefix = "u"; if (slot.IsSRV) { prefix = "t"; } constantRegs.Nodes.Add(new TreelistView.Node(new object[] { prefix + name, "Buffer", buf.length + " - " + buf.name })); found = true; break; } } } if (!found) { string prefix = "u"; if (slot.IsSRV) { prefix = "t"; } constantRegs.Nodes.Add(new TreelistView.Node(new object[] { prefix + name, "Resource", "unknown" })); } } constantRegs.EndUpdate(); } else { constantRegs.BeginUpdate(); int c = 0; for (int i = 0; i < m_Trace.cbuffers.Length; i++) { for (int j = 0; j < m_Trace.cbuffers[i].variables.Length; j++) { if (m_Trace.cbuffers[i].variables[j].rows > 0 || m_Trace.cbuffers[i].variables[j].columns > 0) { constantRegs.Nodes[c++].SetData(new object[] { m_Trace.cbuffers[i].variables[j].name, "cbuffer", StringRep(m_Trace.cbuffers[i].variables[j], false) }); } } } constantRegs.EndUpdate(); } if (variableRegs.Nodes.IsEmpty()) { for (int i = 0; i < state.registers.Length; i++) { variableRegs.Nodes.Add("a"); } for (int i = 0; i < state.outputs.Length; i++) { variableRegs.Nodes.Add("a"); } } variableRegs.BeginUpdate(); int v = 0; for (int i = 0; i < state.registers.Length; i++) { variableRegs.Nodes[v++].SetData(new object[] { state.registers[i].name, "register", StringRep(state.registers[i], false) }); } for (int i = 0; i < state.outputs.Length; i++) { variableRegs.Nodes[v++].SetData(new object[] { state.outputs[i].name, "register", StringRep(state.outputs[i], false) }); } variableRegs.EndUpdate(); watchRegs.BeginUpdate(); for (int i = 0; i < watchRegs.Items.Count - 1; i++) { ListViewItem item = watchRegs.Items[i]; item.SubItems[1].Text = "register"; string reg = item.SubItems[0].Text.Trim(); var regexp = "^([rvo])([0-9]+)(\\.[xyzwrgba]+)?(,[xfiud])?$"; var match = Regex.Match(reg, regexp); if (match.Success) { var regtype = match.Groups[1].Value; var regidx = match.Groups[2].Value; var swizzle = match.Groups[3].Value.Replace(".", ""); var regcast = match.Groups[4].Value.Replace(",", ""); if (regcast == "") { if (displayInts.Checked) { regcast = "i"; } else { regcast = "f"; } } ShaderVariable[] vars = null; if (regtype == "r") { vars = state.registers; } else if (regtype == "v") { vars = m_Trace.inputs; } else if (regtype == "o") { vars = state.outputs; } int regindex = -1; if (int.TryParse(regidx, out regindex)) { if (regindex >= 0 && regindex < vars.Length) { ShaderVariable vr = vars[regindex]; if (swizzle == "") { swizzle = "xyzw".Substring(0, (int)vr.columns); if (regcast == "d") { swizzle = "xy"; } } string val = ""; for (int s = 0; s < swizzle.Length; s++) { char swiz = swizzle[s]; int elindex = 0; if (swiz == 'x' || swiz == 'r') { elindex = 0; } if (swiz == 'y' || swiz == 'g') { elindex = 1; } if (swiz == 'z' || swiz == 'b') { elindex = 2; } if (swiz == 'w' || swiz == 'a') { elindex = 3; } if (regcast == "i") { val += vr.value.iv[elindex]; } else if (regcast == "f") { val += Formatter.Format(vr.value.fv[elindex]); } else if (regcast == "u") { val += vr.value.uv[elindex]; } else if (regcast == "x") { val += String.Format("0x{0:X8}", vr.value.uv[elindex]); } else if (regcast == "d") { if (elindex < 2) { val += vr.value.dv[elindex]; } else { val += "-"; } } if (s < swizzle.Length - 1) { val += ", "; } } item.SubItems[2].Text = val; continue; } } } item.SubItems[2].Text = "Error evaluating expression"; } watchRegs.EndUpdate(); }