Add 'run to sample/load/gather' and 'run to generated inf/nan'.

- ShaderDebugState now carries a 'flags' that can be updated when the interpreter is run. Currently supported flags are 'sample/load/gather insn' or 'insn generated nan/inf'.
- DXBC interpreter now pushes operation type into results for simple intrinsics. This avoids the situation where temp decls are by default uint-typed, and any arithmetic operation on float or double operands would result in a uint shader variable. Other intrinsics are largely correct because they create temporaries with appropriate typed constructors.
- Provide icons for user interface elements, based on the existing 'run to' icons with modifications by myself.
This commit is contained in:
Michael Vance
2016-12-29 17:11:55 +00:00
committed by Baldur Karlsson
parent d249faacd3
commit 366581fb3f
14 changed files with 176 additions and 3 deletions
+6
View File
@@ -345,6 +345,12 @@ enum ShaderStageBits
eStageBits_Compute,
};
enum ShaderDebugStateFlags
{
eShaderDebugStateFlags_SampleLoadGather = 0x1,
eShaderDebugStateFlags_GeneratedNanOrInf = 0x2,
};
enum DebugMessageCategory
{
eDbgCategory_Application_Defined = 0,
+1
View File
@@ -133,6 +133,7 @@ struct ShaderDebugState
rdctype::array<rdctype::array<ShaderVariable> > indexableTemps;
uint32_t nextInstruction;
uint32_t flags;
};
struct ShaderDebugTrace
+1
View File
@@ -260,6 +260,7 @@ void Serialiser::Serialise(const char *name, ShaderDebugState &el)
Serialise("", el.registers);
Serialise("", el.outputs);
Serialise("", el.nextInstruction);
Serialise("", el.flags);
vector<vector<ShaderVariable> > indexableTemps;
+43 -3
View File
@@ -276,6 +276,8 @@ ShaderVariable sat(const ShaderVariable &v, const VarType type)
type);
}
r.type = type;
return r;
}
@@ -319,6 +321,8 @@ ShaderVariable abs(const ShaderVariable &v, const VarType type)
type);
}
r.type = type;
return r;
}
@@ -362,6 +366,8 @@ ShaderVariable neg(const ShaderVariable &v, const VarType type)
type);
}
r.type = type;
return r;
}
@@ -410,6 +416,8 @@ ShaderVariable mul(const ShaderVariable &a, const ShaderVariable &b, const VarTy
type);
}
r.type = type;
return r;
}
@@ -458,6 +466,8 @@ ShaderVariable div(const ShaderVariable &a, const ShaderVariable &b, const VarTy
type);
}
r.type = type;
return r;
}
@@ -506,6 +516,8 @@ ShaderVariable add(const ShaderVariable &a, const ShaderVariable &b, const VarTy
type);
}
r.type = type;
return r;
}
@@ -573,6 +585,25 @@ bool State::Finished() const
return dxbc && (done || nextInstruction >= (int)dxbc->GetNumInstructions());
}
void State::AssignValue(ShaderVariable &dst, uint32_t dstIndex, const ShaderVariable &src,
uint32_t srcIndex)
{
if(src.type == eVar_Float)
{
float ft = src.value.fv[srcIndex];
if(isinf(ft) || isnan(ft))
flags |= eShaderDebugStateFlags_GeneratedNanOrInf;
}
else if(src.type == eVar_Double)
{
double dt = src.value.dv[srcIndex];
if(isinf(dt) || isnan(dt))
flags |= eShaderDebugStateFlags_GeneratedNanOrInf;
}
dst.value.uv[dstIndex] = src.value.uv[srcIndex];
}
void State::SetDst(const ASMOperand &dstoper, const ASMOperation &op, const ShaderVariable &val)
{
ShaderVariable *v = NULL;
@@ -689,7 +720,7 @@ void State::SetDst(const ASMOperand &dstoper, const ASMOperation &op, const Shad
{
RDCASSERT(dstoper.comps[0] != 0xff);
v->value.uv[dstoper.comps[0]] = right.value.u.x;
AssignValue(*v, dstoper.comps[0], right, 0);
}
else
{
@@ -700,13 +731,13 @@ void State::SetDst(const ASMOperand &dstoper, const ASMOperation &op, const Shad
if(dstoper.comps[i] != 0xff)
{
RDCASSERT(dstoper.comps[i] < v->columns);
v->value.uv[dstoper.comps[i]] = right.value.uv[dstoper.comps[i]];
AssignValue(*v, dstoper.comps[i], right, dstoper.comps[i]);
compsWritten++;
}
}
if(compsWritten == 0)
v->value.uv[0] = right.value.uv[0];
AssignValue(*v, 0, right, 0);
}
}
}
@@ -1070,6 +1101,7 @@ State State::GetNext(GlobalState &global, State quad[4]) const
const ASMOperation &op = s.dxbc->GetInstruction((size_t)s.nextInstruction);
s.nextInstruction++;
s.flags = 0;
vector<ShaderVariable> srcOpers;
@@ -2334,6 +2366,9 @@ State State::GetNext(GlobalState &global, State quad[4]) const
load = false;
}
if(load)
s.flags = eShaderDebugStateFlags_SampleLoadGather;
if(op.operation == OPCODE_LD_STRUCTURED || op.operation == OPCODE_STORE_STRUCTURED)
{
if(load)
@@ -3396,6 +3431,11 @@ State State::GetNext(GlobalState &global, State quad[4]) const
string funcRet = "";
DXGI_FORMAT retFmt = DXGI_FORMAT_UNKNOWN;
if(op.operation != OPCODE_LOD)
{
s.flags = eShaderDebugStateFlags_SampleLoadGather;
}
if(op.operation == OPCODE_SAMPLE_C || op.operation == OPCODE_SAMPLE_C_LZ ||
op.operation == OPCODE_GATHER4_C || op.operation == OPCODE_GATHER4_PO_C ||
op.operation == OPCODE_LOD)
@@ -121,6 +121,7 @@ public:
{
quadIndex = 0;
nextInstruction = 0;
flags = 0;
done = false;
trace = NULL;
dxbc = NULL;
@@ -131,6 +132,7 @@ public:
{
quadIndex = quadIdx;
nextInstruction = 0;
flags = 0;
done = false;
trace = t;
dxbc = f;
@@ -165,6 +167,9 @@ private:
bool done;
// validates assignment for generation of non-normal values
void AssignValue(ShaderVariable &dst, uint32_t dstIndex, const ShaderVariable &src,
uint32_t srcIndex);
// sets the destination operand by looking up in the register
// file and applying any masking or swizzling
void SetDst(const DXBC::ASMOperand &dstoper, const DXBC::ASMOperation &op,
+7
View File
@@ -350,6 +350,13 @@ namespace renderdoc
All = (Vertex | Hull | Domain | Geometry | Pixel | Fragment | Compute),
};
[Flags]
public enum ShaderDebugStateFlags
{
SampleLoadGather = 0x1,
GeneratedNanOrInf = 0x2,
};
public enum DebugMessageSource
{
API = 0,
+1
View File
@@ -192,6 +192,7 @@ namespace renderdoc
public IndexableTempArray[] indexableTemps;
public UInt32 nextInstruction;
public ShaderDebugStateFlags flags;
};
[StructLayout(LayoutKind.Sequential)]
+20
View File
@@ -460,6 +460,26 @@ namespace renderdocui.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap runnaninf {
get {
object obj = ResourceManager.GetObject("runnaninf", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap runsample {
get {
object obj = ResourceManager.GetObject("runsample", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
+6
View File
@@ -304,4 +304,10 @@
<data name="upfolder" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\upfolder.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="runsample" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\runsample.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="runnaninf" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\runnaninf.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>
Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

+28
View File
@@ -78,6 +78,8 @@
this.stepBack = new System.Windows.Forms.ToolStripButton();
this.stepNext = new System.Windows.Forms.ToolStripButton();
this.runToCursor = new System.Windows.Forms.ToolStripButton();
this.runToSample = new System.Windows.Forms.ToolStripButton();
this.runToNanOrInf = new System.Windows.Forms.ToolStripButton();
this.runBack = new System.Windows.Forms.ToolStripButton();
this.run = new System.Windows.Forms.ToolStripButton();
this.displayInts = new System.Windows.Forms.ToolStripButton();
@@ -299,6 +301,8 @@
this.stepBack,
this.stepNext,
this.runToCursor,
this.runToSample,
this.runToNanOrInf,
this.runBack,
this.run,
this.showWindows,
@@ -344,6 +348,28 @@
this.runToCursor.ToolTipText = "Run to Cursor (Ctrl-F10)";
this.runToCursor.Click += new System.EventHandler(this.runToCursor_Click);
//
// runToSample
//
this.runToSample.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.runToSample.Image = global::renderdocui.Properties.Resources.runsample;
this.runToSample.ImageTransparentColor = System.Drawing.Color.Magenta;
this.runToSample.Name = "runToSample";
this.runToSample.Size = new System.Drawing.Size(23, 22);
this.runToSample.Text = "Run to Sample/Load/Gather";
this.runToSample.ToolTipText = "Run to Sample/Load/Gather";
this.runToSample.Click += new System.EventHandler(this.runToSample_Click);
//
// runToNanOrInf
//
this.runToNanOrInf.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.runToNanOrInf.Image = global::renderdocui.Properties.Resources.runnaninf;
this.runToNanOrInf.ImageTransparentColor = System.Drawing.Color.Magenta;
this.runToNanOrInf.Name = "runToNanOrInf";
this.runToNanOrInf.Size = new System.Drawing.Size(23, 22);
this.runToNanOrInf.Text = "Run to NaN or Inf";
this.runToNanOrInf.ToolTipText = "Run to NaN or Inf";
this.runToNanOrInf.Click += new System.EventHandler(this.runToNanOrInf_Click);
//
// runBack
//
this.runBack.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
@@ -766,6 +792,8 @@
private System.Windows.Forms.ToolStripButton stepBack;
private System.Windows.Forms.ToolStripButton stepNext;
private System.Windows.Forms.ToolStripButton runToCursor;
private System.Windows.Forms.ToolStripButton runToSample;
private System.Windows.Forms.ToolStripButton runToNanOrInf;
private System.Windows.Forms.ToolStripButton runBack;
private System.Windows.Forms.ToolStripButton run;
private System.Windows.Forms.ToolStripDropDownButton showWindows;
+56
View File
@@ -1864,6 +1864,22 @@ namespace renderdocui.Windows
RunToCursor();
}
private void runToSample_Click(object sender, EventArgs e)
{
if (m_Trace == null || m_Trace.states == null)
return;
RunToSample();
}
private void runToNanOrInf_Click(object sender, EventArgs e)
{
if (m_Trace == null || m_Trace.states == null)
return;
RunToNanOrInf();
}
private bool StepBack()
{
if (m_Trace == null || m_Trace.states == null)
@@ -1966,6 +1982,46 @@ namespace renderdocui.Windows
}
}
private void RunToCondition(ShaderDebugStateFlags condition)
{
if (m_Trace == null || m_Trace.states == null)
return;
int step = CurrentStep;
bool firstStep = true;
while (step < m_Trace.states.Length)
{
int nextStep = step + 1;
if (nextStep >= m_Trace.states.Length)
break;
if (!firstStep && m_Trace.states[nextStep].flags.HasFlag(condition))
break;
if (!firstStep && m_Breakpoints.Contains((int)m_Trace.states[step].nextInstruction))
break;
firstStep = false;
step = nextStep;
}
CurrentStep = step;
}
private void RunToSample()
{
RunToCondition(ShaderDebugStateFlags.SampleLoadGather);
}
private void RunToNanOrInf()
{
RunToCondition(ShaderDebugStateFlags.GeneratedNanOrInf);
}
private void autosToolStripMenuItem_Click(object sender, EventArgs e)
{
ShowConstants();
+2
View File
@@ -607,6 +607,8 @@
<None Include="Resources\stepnext.png" />
<None Include="Resources\time.png" />
<None Include="Resources\timeline_marker.png" />
<None Include="Resources\runsample.png" />
<None Include="Resources\runnaninf.png" />
<Content Include="Resources\topologies\topo_linelist.png" />
<Content Include="Resources\topologies\topo_linelist_adj.png" />
<Content Include="Resources\topologies\topo_linestrip.png" />