From 366581fb3f1fd229803a7580a267d35280ce4e04 Mon Sep 17 00:00:00 2001 From: Michael Vance Date: Mon, 19 Dec 2016 14:52:22 -0500 Subject: [PATCH] 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. --- renderdoc/api/replay/replay_enums.h | 6 ++ renderdoc/api/replay/shader_types.h | 1 + renderdoc/core/replay_proxy.cpp | 1 + renderdoc/driver/shaders/dxbc/dxbc_debug.cpp | 46 ++++++++++++++- renderdoc/driver/shaders/dxbc/dxbc_debug.h | 5 ++ renderdocui/Interop/Enums.cs | 7 +++ renderdocui/Interop/Shader.cs | 1 + renderdocui/Properties/Resources.Designer.cs | 20 +++++++ renderdocui/Properties/Resources.resx | 6 ++ renderdocui/Resources/runnaninf.png | Bin 0 -> 457 bytes renderdocui/Resources/runsample.png | Bin 0 -> 426 bytes renderdocui/Windows/ShaderViewer.Designer.cs | 28 ++++++++++ renderdocui/Windows/ShaderViewer.cs | 56 +++++++++++++++++++ renderdocui/renderdocui.csproj | 2 + 14 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 renderdocui/Resources/runnaninf.png create mode 100644 renderdocui/Resources/runsample.png diff --git a/renderdoc/api/replay/replay_enums.h b/renderdoc/api/replay/replay_enums.h index af8c66089..6aab99f1c 100644 --- a/renderdoc/api/replay/replay_enums.h +++ b/renderdoc/api/replay/replay_enums.h @@ -345,6 +345,12 @@ enum ShaderStageBits eStageBits_Compute, }; +enum ShaderDebugStateFlags +{ + eShaderDebugStateFlags_SampleLoadGather = 0x1, + eShaderDebugStateFlags_GeneratedNanOrInf = 0x2, +}; + enum DebugMessageCategory { eDbgCategory_Application_Defined = 0, diff --git a/renderdoc/api/replay/shader_types.h b/renderdoc/api/replay/shader_types.h index 9b0752e09..8042da529 100644 --- a/renderdoc/api/replay/shader_types.h +++ b/renderdoc/api/replay/shader_types.h @@ -133,6 +133,7 @@ struct ShaderDebugState rdctype::array > indexableTemps; uint32_t nextInstruction; + uint32_t flags; }; struct ShaderDebugTrace diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index f652eb90b..92fd5de7f 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -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 > indexableTemps; diff --git a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp index 7983b42d4..ee5fb048f 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp +++ b/renderdoc/driver/shaders/dxbc/dxbc_debug.cpp @@ -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 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) diff --git a/renderdoc/driver/shaders/dxbc/dxbc_debug.h b/renderdoc/driver/shaders/dxbc/dxbc_debug.h index 41583140a..0ac836a6d 100644 --- a/renderdoc/driver/shaders/dxbc/dxbc_debug.h +++ b/renderdoc/driver/shaders/dxbc/dxbc_debug.h @@ -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, diff --git a/renderdocui/Interop/Enums.cs b/renderdocui/Interop/Enums.cs index 39d9090d7..d97b3b344 100644 --- a/renderdocui/Interop/Enums.cs +++ b/renderdocui/Interop/Enums.cs @@ -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, diff --git a/renderdocui/Interop/Shader.cs b/renderdocui/Interop/Shader.cs index 1f5fee988..d55385c3c 100644 --- a/renderdocui/Interop/Shader.cs +++ b/renderdocui/Interop/Shader.cs @@ -192,6 +192,7 @@ namespace renderdoc public IndexableTempArray[] indexableTemps; public UInt32 nextInstruction; + public ShaderDebugStateFlags flags; }; [StructLayout(LayoutKind.Sequential)] diff --git a/renderdocui/Properties/Resources.Designer.cs b/renderdocui/Properties/Resources.Designer.cs index 03a609fe6..3a5239ea4 100644 --- a/renderdocui/Properties/Resources.Designer.cs +++ b/renderdocui/Properties/Resources.Designer.cs @@ -460,6 +460,26 @@ namespace renderdocui.Properties { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap runnaninf { + get { + object obj = ResourceManager.GetObject("runnaninf", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap runsample { + get { + object obj = ResourceManager.GetObject("runsample", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/renderdocui/Properties/Resources.resx b/renderdocui/Properties/Resources.resx index 972fd251f..edfbd9a66 100644 --- a/renderdocui/Properties/Resources.resx +++ b/renderdocui/Properties/Resources.resx @@ -304,4 +304,10 @@ ..\Resources\upfolder.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\runsample.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\runnaninf.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/renderdocui/Resources/runnaninf.png b/renderdocui/Resources/runnaninf.png new file mode 100644 index 0000000000000000000000000000000000000000..e993104244283271c0c5dd718acbd2f00bb58038 GIT binary patch literal 457 zcmV;)0XF`LP)PWd*^V^<=p$;1^yv&zs|grujUGs1@QEpCLzdWEWNnb z>-98%HvoGJ&K1H?L`Jn*H8)nfx*djbtcX$o+A(ZM+qU94sW_PHgdPra0KfoXC?Yt_ zA()4*5c?yoXAX0iurdw8O~xz$U?KqM0mzTEo;%Fp+6>;OI-zuhNC7wo5Z+WO%Qhls z>q8ujXD@>ZM literal 0 HcmV?d00001 diff --git a/renderdocui/Resources/runsample.png b/renderdocui/Resources/runsample.png new file mode 100644 index 0000000000000000000000000000000000000000..99d324fca0e4213fb32ab9ab096289e035b272d2 GIT binary patch literal 426 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE)4%caKYZ?lYt_f1s;*b z3=DjSK$uZf!>a)($X?><>&pIsho6y0=3l8PBLf4Yxu=U`h{fsT1c{IZ*~hijg1#=u z5O|RCk2`t#^y$Shj~=bMfBxJ*du!|2il(Mh8ISSv@jW}3b*ts>`v1zGzi;0B|Ng<_ z-{r;S53~ONx9EhS#lJr%cNkgB5KSwdKU+F^ek@_t<>= 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(); diff --git a/renderdocui/renderdocui.csproj b/renderdocui/renderdocui.csproj index c21dd55c4..c52ca1753 100644 --- a/renderdocui/renderdocui.csproj +++ b/renderdocui/renderdocui.csproj @@ -607,6 +607,8 @@ + +