Add warning if dispatch has 0 dimension, and bounds-check on debugging

This commit is contained in:
baldurk
2015-07-09 20:42:34 +02:00
parent fa800936ad
commit ddd432f678
12 changed files with 134 additions and 7 deletions
+7
View File
@@ -188,6 +188,10 @@ struct FetchDrawcall
parent = 0;
previous = 0;
next = 0;
dispatchDimension[0] = dispatchDimension[1] = dispatchDimension[2] = 0;
dispatchThreadsDimension[0] = dispatchThreadsDimension[1] = dispatchThreadsDimension[2] = 0;
for(int i=0; i < 8; i++)
outputs[i] = ResourceId();
}
@@ -203,6 +207,9 @@ struct FetchDrawcall
uint32_t indexOffset;
uint32_t vertexOffset;
uint32_t instanceOffset;
uint32_t dispatchDimension[3];
uint32_t dispatchThreadsDimension[3];
uint32_t indexByteWidth;
PrimitiveTopology topology;
+2
View File
@@ -208,6 +208,8 @@ struct ShaderReflection
ShaderDebugChunk DebugInfo;
rdctype::str Disassembly;
uint32_t DispatchThreadsDimension[3];
rdctype::array<SigParameter> InputSig;
rdctype::array<SigParameter> OutputSig;
+8 -3
View File
@@ -201,6 +201,8 @@ void Serialiser::Serialise(const char *name, ShaderReflection &el)
Serialise("", el.DebugInfo.entryFunc);
Serialise("", el.DebugInfo.files);
Serialise<3>("", el.DispatchThreadsDimension);
Serialise("", el.Disassembly);
Serialise("", el.InputSig);
@@ -212,7 +214,7 @@ void Serialiser::Serialise(const char *name, ShaderReflection &el)
Serialise("", el.Interfaces);
SIZE_CHECK(ShaderReflection, 72);
SIZE_CHECK(ShaderReflection, 84);
}
template<>
@@ -764,7 +766,10 @@ void Serialiser::Serialise(const char *name, FetchDrawcall &el)
Serialise("", el.indexOffset);
Serialise("", el.vertexOffset);
Serialise("", el.instanceOffset);
Serialise<3>("", el.dispatchDimension);
Serialise<3>("", el.dispatchThreadsDimension);
Serialise("", el.indexByteWidth);
Serialise("", el.topology);
@@ -780,7 +785,7 @@ void Serialiser::Serialise(const char *name, FetchDrawcall &el)
Serialise("", el.events);
Serialise("", el.children);
SIZE_CHECK(FetchDrawcall, 168);
SIZE_CHECK(FetchDrawcall, 192);
}
template<>
+4
View File
@@ -904,6 +904,10 @@ ShaderReflection *MakeShaderReflection(DXBC::DXBCFile *dxbc)
}
}
ret->DispatchThreadsDimension[0] = dxbc->DispatchThreadsDimension[0];
ret->DispatchThreadsDimension[1] = dxbc->DispatchThreadsDimension[1];
ret->DispatchThreadsDimension[2] = dxbc->DispatchThreadsDimension[2];
ret->Disassembly = dxbc->m_Disassembly;
ret->InputSig = dxbc->m_InputSig;
@@ -4509,6 +4509,20 @@ bool WrappedID3D11DeviceContext::Serialise_Dispatch(UINT ThreadGroupCountX_, UIN
draw.name = name;
draw.flags |= eDraw_Dispatch;
draw.dispatchDimension[0] = ThreadGroupCountX;
draw.dispatchDimension[1] = ThreadGroupCountY;
draw.dispatchDimension[2] = ThreadGroupCountZ;
if(ThreadGroupCountX == 0)
m_pDevice->AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse,
"Dispatch call has ThreadGroup count X=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean X=1?");
if(ThreadGroupCountY == 0)
m_pDevice->AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse,
"Dispatch call has ThreadGroup count Y=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean Y=1?");
if(ThreadGroupCountZ == 0)
m_pDevice->AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse,
"Dispatch call has ThreadGroup count Z=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean Z=1?");
AddDrawcall(draw, true);
}
@@ -4570,6 +4584,10 @@ bool WrappedID3D11DeviceContext::Serialise_DispatchIndirect(ID3D11Buffer *pBuffe
name = "DispatchIndirect(<" + ToStr::Get(uargs[0])
+ ", " + ToStr::Get(uargs[1]) +
+ ", " + ToStr::Get(uargs[2]) + ">)";
draw.dispatchDimension[0] = uargs[0];
draw.dispatchDimension[1] = uargs[1];
draw.dispatchDimension[2] = uargs[2];
}
draw.name = name;
+9
View File
@@ -753,6 +753,15 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
refl.Disassembly = "";
if(shadType == eGL_COMPUTE_SHADER)
{
gl.glGetProgramiv(sepProg, eGL_COMPUTE_WORK_GROUP_SIZE, (GLint *)refl.DispatchThreadsDimension);
}
else
{
RDCEraseEl(refl.DispatchThreadsDimension);
}
vector<ShaderResource> resources;
GLint numUniforms = 0;
+47 -2
View File
@@ -53,6 +53,20 @@ bool WrappedOpenGL::Serialise_glDispatchCompute(GLuint num_groups_x, GLuint num_
draw.name = name;
draw.flags |= eDraw_Dispatch;
draw.dispatchDimension[0] = X;
draw.dispatchDimension[1] = Y;
draw.dispatchDimension[2] = Z;
if(X == 0)
AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse,
"Dispatch call has Num Groups X=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean X=1?");
if(Y == 0)
AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse,
"Dispatch call has Num Groups Y=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean Y=1?");
if(Z == 0)
AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse,
"Dispatch call has Num Groups Z=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean Z=1?");
AddDrawcall(draw, true);
}
@@ -107,6 +121,33 @@ bool WrappedOpenGL::Serialise_glDispatchComputeGroupSizeARB(GLuint num_groups_x,
draw.name = name;
draw.flags |= eDraw_Dispatch;
draw.dispatchDimension[0] = X;
draw.dispatchDimension[1] = Y;
draw.dispatchDimension[2] = Z;
draw.dispatchThreadsDimension[0] = sX;
draw.dispatchThreadsDimension[1] = sY;
draw.dispatchThreadsDimension[2] = sZ;
if(X == 0)
AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse,
"Dispatch call has Num Groups X=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean X=1?");
if(Y == 0)
AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse,
"Dispatch call has Num Groups Y=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean Y=1?");
if(Z == 0)
AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse,
"Dispatch call has Num Groups Z=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean Z=1?");
if(sX == 0)
AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse,
"Dispatch call has Group Size X=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean X=1?");
if(sY == 0)
AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse,
"Dispatch call has Group Size Y=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean Y=1?");
if(sZ == 0)
AddDebugMessage(eDbgCategory_Execution, eDbgSeverity_Medium, eDbgSource_IncorrectAPIUse,
"Dispatch call has Group Size Z=0. This will do nothing, which is unusual for a non-indirect Dispatch. Did you mean Z=1?");
AddDrawcall(draw, true);
}
@@ -147,15 +188,19 @@ bool WrappedOpenGL::Serialise_glDispatchComputeIndirect(GLintptr indirect)
m_Real.glGetBufferSubData(eGL_DISPATCH_INDIRECT_BUFFER, (GLintptr)offs, sizeof(uint32_t)*3, groupSizes);
AddEvent(DISPATCH_COMPUTE_INDIRECT, desc);
string name = "glDispatchComputeIndirect(" +
string name = "glDispatchComputeIndirect(<" +
ToStr::Get(groupSizes[0]) + ", " +
ToStr::Get(groupSizes[1]) + ", " +
ToStr::Get(groupSizes[2]) + ")";
ToStr::Get(groupSizes[2]) + ">)";
FetchDrawcall draw;
draw.name = name;
draw.flags |= eDraw_Dispatch|eDraw_Indirect;
draw.dispatchDimension[0] = groupSizes[0];
draw.dispatchDimension[1] = groupSizes[1];
draw.dispatchDimension[2] = groupSizes[2];
AddDrawcall(draw, true);
}
@@ -1287,6 +1287,10 @@ bool DXBCFile::ExtractDecl(uint32_t *&tokenStream, ASMDecl &retDecl)
retDecl.groupSize[2] = tokenStream[0];
tokenStream++;
DispatchThreadsDimension[0] = retDecl.groupSize[0];
DispatchThreadsDimension[1] = retDecl.groupSize[1];
DispatchThreadsDimension[2] = retDecl.groupSize[2];
char buf[64] = {0};
StringFormat::snprintf(buf, 63, "%u", retDecl.groupSize[0]);
retDecl.str += buf;
@@ -344,6 +344,8 @@ class DXBCFile
vector<ASMOperation> m_Instructions;
string m_Disassembly;
uint32_t DispatchThreadsDimension[3];
vector<uint32_t> m_HexDump;
vector<byte> m_ShaderBlob;
+5
View File
@@ -331,6 +331,11 @@ namespace renderdoc
public UInt32 vertexOffset;
public UInt32 instanceOffset;
[CustomMarshalAs(CustomUnmanagedType.FixedArray, FixedLength = 3)]
public UInt32[] dispatchDimension;
[CustomMarshalAs(CustomUnmanagedType.FixedArray, FixedLength = 3)]
public UInt32[] dispatchThreadsDimension;
public UInt32 indexByteWidth;
public PrimitiveTopology topology;
+3
View File
@@ -386,6 +386,9 @@ namespace renderdoc
[CustomMarshalAs(CustomUnmanagedType.UTF8TemplatedString)]
public string Disassembly;
[CustomMarshalAs(CustomUnmanagedType.FixedArray, FixedLength = 3)]
public UInt32[] DispatchThreadsDimension;
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public SigParameter[] InputSig;
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
@@ -2255,6 +2255,31 @@ namespace renderdocui.Windows.PipelineState
uint.TryParse(threadY.Text, out ty) &&
uint.TryParse(threadZ.Text, out tz))
{
uint[] groupdim = m_Core.CurDrawcall.dispatchDimension;
uint[] threadsdim = m_Core.CurDrawcall.dispatchThreadsDimension;
for (int i = 0; i < 3; i++)
if (threadsdim[i] == 0)
threadsdim[i] = m_Core.CurD3D11PipelineState.m_CS.ShaderDetails.DispatchThreadsDimension[i];
string debugContext = String.Format("Group [{0},{1},{2}] Thread [{3},{4},{5}]", gx, gy, gz, tx, ty, tz);
if (gx >= groupdim[0] ||
gy >= groupdim[1] ||
gz >= groupdim[2] ||
tx >= threadsdim[0] ||
ty >= threadsdim[1] ||
tz >= threadsdim[2])
{
string bounds = String.Format("Group Dimensions [{0},{1},{2}] Thread Dimensions [{3},{4},{5}]",
groupdim[0], groupdim[1], groupdim[2],
threadsdim[0], threadsdim[1], threadsdim[2]);
MessageBox.Show(String.Format("{0} is out of bounds\n{1}", debugContext, bounds), "Couldn't debug compute shader.",
MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
ShaderDebugTrace trace = null;
ShaderReflection shaderDetails = m_Core.CurD3D11PipelineState.m_CS.ShaderDetails;
@@ -2273,8 +2298,6 @@ namespace renderdocui.Windows.PipelineState
this.BeginInvoke(new Action(() =>
{
string debugContext = String.Format("Group [{0},{1},{2}] Thread [{3},{4},{5}]", gx, gy, gz, tx, ty, tz);
ShaderViewer s = new ShaderViewer(m_Core, shaderDetails, ShaderStageType.Compute, trace, debugContext);
s.Show(m_DockContent.DockPanel);