mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-29 13:20:54 +00:00
Add warning if dispatch has 0 dimension, and bounds-check on debugging
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -208,6 +208,8 @@ struct ShaderReflection
|
||||
ShaderDebugChunk DebugInfo;
|
||||
rdctype::str Disassembly;
|
||||
|
||||
uint32_t DispatchThreadsDimension[3];
|
||||
|
||||
rdctype::array<SigParameter> InputSig;
|
||||
rdctype::array<SigParameter> OutputSig;
|
||||
|
||||
|
||||
@@ -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<>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user