mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-20 22:41:36 +00:00
Add a per-shader debuggable flag to allow finer grained status
* E.g. on D3D12 we can debug DXBC shaders but not DXIL shaders. On vulkan this will allow us to have the UI work better when encountering shaders with unsupported capabilities or extensions.
This commit is contained in:
@@ -2277,8 +2277,34 @@ void BufferViewer::stageRowMenu(MeshDataStage stage, QMenu *menu, const QPoint &
|
||||
|
||||
menu->clear();
|
||||
|
||||
if(m_MeshView && stage != MeshDataStage::GSOut && m_Ctx.APIProps().shaderDebugging)
|
||||
menu->setToolTipsVisible(true);
|
||||
|
||||
if(m_MeshView && stage != MeshDataStage::GSOut)
|
||||
{
|
||||
const ShaderReflection *shaderDetails =
|
||||
m_Ctx.CurPipelineState().GetShaderReflection(ShaderStage::Vertex);
|
||||
|
||||
m_DebugVert->setEnabled(false);
|
||||
|
||||
if(!m_Ctx.APIProps().shaderDebugging)
|
||||
{
|
||||
m_DebugVert->setToolTip(tr("This API does not support shader debugging"));
|
||||
}
|
||||
else if(!shaderDetails)
|
||||
{
|
||||
m_DebugVert->setToolTip(tr("No vertex shader bound"));
|
||||
}
|
||||
else if(!shaderDetails->debugInfo.debuggable)
|
||||
{
|
||||
m_DebugVert->setToolTip(
|
||||
tr("This shader doesn't support debugging: %1").arg(shaderDetails->debugInfo.debugStatus));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_DebugVert->setEnabled(true);
|
||||
m_DebugVert->setToolTip(QString());
|
||||
}
|
||||
|
||||
menu->addAction(m_DebugVert);
|
||||
menu->addSeparator();
|
||||
}
|
||||
|
||||
@@ -1846,7 +1846,9 @@ void D3D11PipelineStateViewer::setState()
|
||||
ui->stencils->endUpdate();
|
||||
|
||||
// set up thread debugging inputs
|
||||
if(state.computeShader.reflection && draw && (draw->flags & DrawFlags::Dispatch))
|
||||
if(m_Ctx.APIProps().shaderDebugging && state.computeShader.reflection &&
|
||||
state.computeShader.reflection->debugInfo.debuggable && draw &&
|
||||
(draw->flags & DrawFlags::Dispatch))
|
||||
{
|
||||
ui->groupX->setEnabled(true);
|
||||
ui->groupY->setEnabled(true);
|
||||
@@ -1875,6 +1877,8 @@ void D3D11PipelineStateViewer::setState()
|
||||
ui->threadY->setMaximum((int)draw->dispatchThreadsDimension[1] - 1);
|
||||
ui->threadZ->setMaximum((int)draw->dispatchThreadsDimension[2] - 1);
|
||||
}
|
||||
|
||||
ui->debugThread->setToolTip(QString());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1887,6 +1891,16 @@ void D3D11PipelineStateViewer::setState()
|
||||
ui->threadZ->setEnabled(false);
|
||||
|
||||
ui->debugThread->setEnabled(false);
|
||||
|
||||
if(!m_Ctx.APIProps().shaderDebugging)
|
||||
ui->debugThread->setToolTip(tr("This API does not support shader debugging"));
|
||||
else if(!draw || !(draw->flags & DrawFlags::Dispatch))
|
||||
ui->debugThread->setToolTip(tr("No dispatch selected"));
|
||||
else if(!state.computeShader.reflection)
|
||||
ui->debugThread->setToolTip(tr("No compute shader bound"));
|
||||
else if(!state.computeShader.reflection->debugInfo.debuggable)
|
||||
ui->debugThread->setToolTip(tr("This shader doesn't support debugging: %1")
|
||||
.arg(state.computeShader.reflection->debugInfo.debugStatus));
|
||||
}
|
||||
|
||||
// highlight the appropriate stages in the flowchart
|
||||
|
||||
@@ -1817,7 +1817,8 @@ void D3D12PipelineStateViewer::setState()
|
||||
ui->stencils->endUpdate();
|
||||
|
||||
// set up thread debugging inputs
|
||||
if(m_Ctx.APIProps().shaderDebugging && state.computeShader.reflection && draw &&
|
||||
if(m_Ctx.APIProps().shaderDebugging && state.computeShader.reflection &&
|
||||
state.computeShader.reflection->debugInfo.debuggable && draw &&
|
||||
(draw->flags & DrawFlags::Dispatch))
|
||||
{
|
||||
ui->groupX->setEnabled(true);
|
||||
@@ -1847,6 +1848,8 @@ void D3D12PipelineStateViewer::setState()
|
||||
ui->threadY->setMaximum((int)draw->dispatchThreadsDimension[1] - 1);
|
||||
ui->threadZ->setMaximum((int)draw->dispatchThreadsDimension[2] - 1);
|
||||
}
|
||||
|
||||
ui->debugThread->setToolTip(QString());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1859,6 +1862,16 @@ void D3D12PipelineStateViewer::setState()
|
||||
ui->threadZ->setEnabled(false);
|
||||
|
||||
ui->debugThread->setEnabled(false);
|
||||
|
||||
if(!m_Ctx.APIProps().shaderDebugging)
|
||||
ui->debugThread->setToolTip(tr("This API does not support shader debugging"));
|
||||
else if(!draw || !(draw->flags & DrawFlags::Dispatch))
|
||||
ui->debugThread->setToolTip(tr("No dispatch selected"));
|
||||
else if(!state.computeShader.reflection)
|
||||
ui->debugThread->setToolTip(tr("No compute shader bound"));
|
||||
else if(!state.computeShader.reflection->debugInfo.debuggable)
|
||||
ui->debugThread->setToolTip(tr("This shader doesn't support debugging: %1")
|
||||
.arg(state.computeShader.reflection->debugInfo.debugStatus));
|
||||
}
|
||||
|
||||
// highlight the appropriate stages in the flowchart
|
||||
|
||||
@@ -2539,7 +2539,8 @@ void VulkanPipelineStateViewer::setState()
|
||||
ui->stencils->endUpdate();
|
||||
|
||||
// set up thread debugging inputs
|
||||
if(m_Ctx.APIProps().shaderDebugging && state.computeShader.reflection && draw &&
|
||||
if(m_Ctx.APIProps().shaderDebugging && state.computeShader.reflection &&
|
||||
state.computeShader.reflection->debugInfo.debuggable && draw &&
|
||||
(draw->flags & DrawFlags::Dispatch))
|
||||
{
|
||||
ui->groupX->setEnabled(true);
|
||||
@@ -2569,6 +2570,8 @@ void VulkanPipelineStateViewer::setState()
|
||||
ui->threadY->setMaximum((int)draw->dispatchThreadsDimension[1] - 1);
|
||||
ui->threadZ->setMaximum((int)draw->dispatchThreadsDimension[2] - 1);
|
||||
}
|
||||
|
||||
ui->debugThread->setToolTip(QString());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2581,6 +2584,16 @@ void VulkanPipelineStateViewer::setState()
|
||||
ui->threadZ->setEnabled(false);
|
||||
|
||||
ui->debugThread->setEnabled(false);
|
||||
|
||||
if(!m_Ctx.APIProps().shaderDebugging)
|
||||
ui->debugThread->setToolTip(tr("This API does not support shader debugging"));
|
||||
else if(!draw || !(draw->flags & DrawFlags::Dispatch))
|
||||
ui->debugThread->setToolTip(tr("No dispatch selected"));
|
||||
else if(!state.computeShader.reflection)
|
||||
ui->debugThread->setToolTip(tr("No compute shader bound"));
|
||||
else if(!state.computeShader.reflection->debugInfo.debuggable)
|
||||
ui->debugThread->setToolTip(tr("This shader doesn't support debugging: %1")
|
||||
.arg(state.computeShader.reflection->debugInfo.debugStatus));
|
||||
}
|
||||
|
||||
// highlight the appropriate stages in the flowchart
|
||||
|
||||
@@ -716,6 +716,29 @@ void PixelHistoryView::startDebug(EventTag tag)
|
||||
{
|
||||
m_Ctx.SetEventID({this}, tag.eventId, tag.eventId);
|
||||
|
||||
const ShaderReflection *shaderDetails =
|
||||
m_Ctx.CurPipelineState().GetShaderReflection(ShaderStage::Pixel);
|
||||
|
||||
if(!m_Ctx.APIProps().shaderDebugging)
|
||||
{
|
||||
RDDialog::critical(this, tr("Can't debug pixel"),
|
||||
tr("This API does not support shader debugging"));
|
||||
return;
|
||||
}
|
||||
else if(!shaderDetails)
|
||||
{
|
||||
RDDialog::critical(this, tr("Can't debug pixel"),
|
||||
tr("No pixel shader bound at event %1").arg(tag.eventId));
|
||||
return;
|
||||
}
|
||||
else if(!shaderDetails->debugInfo.debuggable)
|
||||
{
|
||||
RDDialog::critical(
|
||||
this, tr("Can't debug pixel"),
|
||||
tr("This shader doesn't support debugging: %1").arg(shaderDetails->debugInfo.debugStatus));
|
||||
return;
|
||||
}
|
||||
|
||||
bool done = false;
|
||||
ShaderDebugTrace *trace = NULL;
|
||||
|
||||
@@ -748,8 +771,6 @@ void PixelHistoryView::startDebug(EventTag tag)
|
||||
return;
|
||||
}
|
||||
|
||||
const ShaderReflection *shaderDetails =
|
||||
m_Ctx.CurPipelineState().GetShaderReflection(ShaderStage::Pixel);
|
||||
const ShaderBindpointMapping &bindMapping =
|
||||
m_Ctx.CurPipelineState().GetBindpointMapping(ShaderStage::Pixel);
|
||||
ResourceId pipeline = m_Ctx.CurPipelineState().GetGraphicsPipelineObject();
|
||||
@@ -832,6 +853,14 @@ void PixelHistoryView::on_events_customContextMenuRequested(const QPoint &pos)
|
||||
|
||||
contextMenu.addAction(&debugAction);
|
||||
|
||||
if(!m_Ctx.APIProps().shaderDebugging)
|
||||
{
|
||||
debugAction.setToolTip(tr("This API does not support shader debugging"));
|
||||
debugAction.setEnabled(false);
|
||||
}
|
||||
|
||||
// can't check if the shader supports debugging here because we don't have its details.
|
||||
|
||||
QObject::connect(&jumpAction, &QAction::triggered, [this, tag]() { jumpToPrimitive(tag); });
|
||||
QObject::connect(&debugAction, &QAction::triggered, [this, tag]() { startDebug(tag); });
|
||||
|
||||
|
||||
@@ -500,8 +500,55 @@ void TextureViewer::UI_UpdateCachedTexture()
|
||||
|
||||
m_CachedTexture = m_Ctx.GetTexture(id);
|
||||
|
||||
ui->debugPixelContext->setEnabled(m_Ctx.APIProps().shaderDebugging && m_CachedTexture != NULL);
|
||||
ui->pixelHistory->setEnabled(m_Ctx.APIProps().pixelHistory && m_CachedTexture != NULL);
|
||||
if(m_CachedTexture != NULL)
|
||||
{
|
||||
if(m_Ctx.APIProps().shaderDebugging)
|
||||
{
|
||||
const ShaderReflection *shaderDetails =
|
||||
m_Ctx.CurPipelineState().GetShaderReflection(ShaderStage::Pixel);
|
||||
|
||||
if(!shaderDetails)
|
||||
{
|
||||
ui->debugPixelContext->setEnabled(false);
|
||||
ui->debugPixelContext->setToolTip(tr("No pixel shader bound"));
|
||||
}
|
||||
else if(!shaderDetails->debugInfo.debuggable)
|
||||
{
|
||||
ui->debugPixelContext->setEnabled(false);
|
||||
ui->debugPixelContext->setToolTip(
|
||||
tr("The current pixel shader does not support debugging: %1")
|
||||
.arg(shaderDetails->debugInfo.debugStatus));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->debugPixelContext->setEnabled(true);
|
||||
ui->debugPixelContext->setToolTip(QString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->debugPixelContext->setEnabled(false);
|
||||
ui->debugPixelContext->setToolTip(tr("Shader Debugging not supported on this API"));
|
||||
}
|
||||
|
||||
if(m_Ctx.APIProps().pixelHistory)
|
||||
{
|
||||
ui->pixelHistory->setEnabled(true);
|
||||
ui->pixelHistory->setToolTip(QString());
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->pixelHistory->setEnabled(false);
|
||||
ui->pixelHistory->setToolTip(tr("Pixel History not supported on this API"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->debugPixelContext->setEnabled(false);
|
||||
ui->debugPixelContext->setToolTip(tr("No active texture selected"));
|
||||
ui->pixelHistory->setEnabled(false);
|
||||
ui->pixelHistory->setToolTip(tr("No active texture selected"));
|
||||
}
|
||||
}
|
||||
|
||||
TextureViewer::TextureViewer(ICaptureContext &ctx, QWidget *parent)
|
||||
@@ -2797,27 +2844,11 @@ void TextureViewer::OnCaptureLoaded()
|
||||
ui->locationGoto->setEnabled(true);
|
||||
ui->viewTexBuffer->setEnabled(true);
|
||||
|
||||
if(m_Ctx.APIProps().pixelHistory)
|
||||
{
|
||||
ui->pixelHistory->setEnabled(true);
|
||||
ui->pixelHistory->setToolTip(QString());
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->pixelHistory->setEnabled(false);
|
||||
ui->pixelHistory->setToolTip(tr("Pixel History not implemented on this API"));
|
||||
}
|
||||
ui->pixelHistory->setEnabled(false);
|
||||
ui->pixelHistory->setToolTip(QString());
|
||||
|
||||
if(m_Ctx.APIProps().shaderDebugging)
|
||||
{
|
||||
ui->debugPixelContext->setEnabled(true);
|
||||
ui->debugPixelContext->setToolTip(QString());
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->debugPixelContext->setEnabled(false);
|
||||
ui->debugPixelContext->setToolTip(tr("Shader Debugging not implemented on this API"));
|
||||
}
|
||||
ui->debugPixelContext->setEnabled(false);
|
||||
ui->pixelHistory->setToolTip(QString());
|
||||
|
||||
TextureListItemModel *model = (TextureListItemModel *)ui->textureList->model();
|
||||
|
||||
|
||||
@@ -1269,6 +1269,17 @@ The first entry in the list is always the file where the entry point is.
|
||||
|
||||
DOCUMENT("The :class:`ShaderEncoding` of the source. See :data:`files`.");
|
||||
ShaderEncoding encoding = ShaderEncoding::Unknown;
|
||||
|
||||
DOCUMENT(R"(Indicates whether this particular shader can be debugged. In some cases even if the
|
||||
API can debug shaders in general, specific shaders cannot be debugged because they use unsupported
|
||||
functionality
|
||||
)");
|
||||
bool debuggable = true;
|
||||
|
||||
DOCUMENT(R"(If :data:`debuggable` is false then this contains a simple explanation of why the
|
||||
shader is not supported for debugging
|
||||
)");
|
||||
rdcstr debugStatus;
|
||||
};
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(ShaderDebugInfo);
|
||||
|
||||
@@ -1682,12 +1682,6 @@ void GatherConstantBuffers(WrappedID3D12Device *pDevice, const DXBCBytecode::Pro
|
||||
ShaderDebugTrace *D3D12Replay::DebugVertex(uint32_t eventId, uint32_t vertid, uint32_t instid,
|
||||
uint32_t idx)
|
||||
{
|
||||
if(!GetAPIProperties().shaderDebugging)
|
||||
{
|
||||
RDCUNIMPLEMENTED("Vertex debugging not yet implemented for D3D12");
|
||||
return new ShaderDebugTrace;
|
||||
}
|
||||
|
||||
using namespace DXBCBytecode;
|
||||
using namespace DXBCDebug;
|
||||
|
||||
@@ -1700,13 +1694,25 @@ ShaderDebugTrace *D3D12Replay::DebugVertex(uint32_t eventId, uint32_t vertid, ui
|
||||
WrappedID3D12Shader *vs =
|
||||
m_pDevice->GetResourceManager()->GetCurrentAs<WrappedID3D12Shader>(vertexShader.resourceId);
|
||||
if(!vs)
|
||||
{
|
||||
RDCERR("Can't debug with no current vertex shader");
|
||||
return new ShaderDebugTrace;
|
||||
}
|
||||
|
||||
DXBC::DXBCContainer *dxbc = vs->GetDXBC();
|
||||
const ShaderReflection &refl = vs->GetDetails();
|
||||
|
||||
if(!dxbc)
|
||||
{
|
||||
RDCERR("Vertex shader couldn't be reflected");
|
||||
return new ShaderDebugTrace;
|
||||
}
|
||||
|
||||
if(!refl.debugInfo.debuggable)
|
||||
{
|
||||
RDCERR("Vertex shader is not debuggable");
|
||||
return new ShaderDebugTrace;
|
||||
}
|
||||
|
||||
dxbc->GetDisassembly();
|
||||
|
||||
@@ -2050,12 +2056,6 @@ ShaderDebugTrace *D3D12Replay::DebugVertex(uint32_t eventId, uint32_t vertid, ui
|
||||
ShaderDebugTrace *D3D12Replay::DebugPixel(uint32_t eventId, uint32_t x, uint32_t y, uint32_t sample,
|
||||
uint32_t primitive)
|
||||
{
|
||||
if(!GetAPIProperties().shaderDebugging)
|
||||
{
|
||||
RDCUNIMPLEMENTED("Pixel debugging not yet implemented for D3D12");
|
||||
return new ShaderDebugTrace();
|
||||
}
|
||||
|
||||
using namespace DXBC;
|
||||
using namespace DXBCBytecode;
|
||||
using namespace DXBCDebug;
|
||||
@@ -2071,13 +2071,25 @@ ShaderDebugTrace *D3D12Replay::DebugPixel(uint32_t eventId, uint32_t x, uint32_t
|
||||
WrappedID3D12Shader *ps =
|
||||
m_pDevice->GetResourceManager()->GetCurrentAs<WrappedID3D12Shader>(pixelShader.resourceId);
|
||||
if(!ps)
|
||||
{
|
||||
RDCERR("Can't debug with no current pixel shader");
|
||||
return new ShaderDebugTrace;
|
||||
}
|
||||
|
||||
DXBCContainer *dxbc = ps->GetDXBC();
|
||||
const ShaderReflection &refl = ps->GetDetails();
|
||||
|
||||
if(!dxbc)
|
||||
{
|
||||
RDCERR("Pixel shader couldn't be reflected");
|
||||
return new ShaderDebugTrace;
|
||||
}
|
||||
|
||||
if(!refl.debugInfo.debuggable)
|
||||
{
|
||||
RDCERR("Pixel shader is not debuggable");
|
||||
return new ShaderDebugTrace;
|
||||
}
|
||||
|
||||
dxbc->GetDisassembly();
|
||||
|
||||
@@ -2836,12 +2848,6 @@ void ExtractInputsPS(PSInput IN, float4 debug_pixelPos : SV_Position,
|
||||
ShaderDebugTrace *D3D12Replay::DebugThread(uint32_t eventId, const uint32_t groupid[3],
|
||||
const uint32_t threadid[3])
|
||||
{
|
||||
if(!GetAPIProperties().shaderDebugging)
|
||||
{
|
||||
RDCUNIMPLEMENTED("Compute shader debugging not yet implemented for D3D12");
|
||||
return new ShaderDebugTrace();
|
||||
}
|
||||
|
||||
using namespace DXBCBytecode;
|
||||
using namespace DXBCDebug;
|
||||
|
||||
@@ -2855,13 +2861,25 @@ ShaderDebugTrace *D3D12Replay::DebugThread(uint32_t eventId, const uint32_t grou
|
||||
WrappedID3D12Shader *cs =
|
||||
m_pDevice->GetResourceManager()->GetCurrentAs<WrappedID3D12Shader>(computeShader.resourceId);
|
||||
if(!cs)
|
||||
{
|
||||
RDCERR("Can't debug with no current compute shader");
|
||||
return new ShaderDebugTrace;
|
||||
}
|
||||
|
||||
DXBC::DXBCContainer *dxbc = cs->GetDXBC();
|
||||
const ShaderReflection &refl = cs->GetDetails();
|
||||
|
||||
if(!dxbc)
|
||||
{
|
||||
RDCERR("Pixel shader couldn't be reflected");
|
||||
return new ShaderDebugTrace;
|
||||
}
|
||||
|
||||
if(!refl.debugInfo.debuggable)
|
||||
{
|
||||
RDCERR("Pixel shader is not debuggable");
|
||||
return new ShaderDebugTrace;
|
||||
}
|
||||
|
||||
dxbc->GetDisassembly();
|
||||
|
||||
|
||||
@@ -230,6 +230,20 @@ void MakeShaderReflection(DXBC::DXBCContainer *dxbc, ShaderReflection *refl,
|
||||
// by default, and SPDB has an extra sorting step that probably maybe possibly does this.
|
||||
}
|
||||
|
||||
if(dxbc->GetDXBCByteCode())
|
||||
{
|
||||
refl->debugInfo.debuggable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
refl->debugInfo.debuggable = false;
|
||||
|
||||
if(dxbc->GetDXILByteCode())
|
||||
refl->debugInfo.debugStatus = "Debugging DXIL is not supported";
|
||||
else
|
||||
refl->debugInfo.debugStatus = "Shader contains no recognised bytecode";
|
||||
}
|
||||
|
||||
refl->encoding = ShaderEncoding::DXBC;
|
||||
refl->rawBytes = dxbc->m_ShaderBlob;
|
||||
|
||||
|
||||
@@ -182,24 +182,18 @@ void Debugger::MakeSignatureNames(const rdcarray<SPIRVInterfaceAccess> &sigList,
|
||||
}
|
||||
}
|
||||
|
||||
ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const ShaderStage stage,
|
||||
const rdcstr &entryPoint,
|
||||
const rdcarray<SpecConstant> &specInfo,
|
||||
const std::map<size_t, uint32_t> &instructionLines,
|
||||
const SPIRVPatchData &patchData, uint32_t activeIndex)
|
||||
// this function is implemented here to keep it next to the code we might need to update, even
|
||||
// though it's checked at reflection time.
|
||||
void Reflector::CheckDebuggable(bool &debuggable, rdcstr &debugStatus) const
|
||||
{
|
||||
Id entryId = entryLookup[entryPoint];
|
||||
|
||||
if(entryId == Id())
|
||||
{
|
||||
RDCERR("Invalid entry point '%s'", entryPoint.c_str());
|
||||
return new ShaderDebugTrace;
|
||||
}
|
||||
debuggable = true;
|
||||
debugStatus.clear();
|
||||
|
||||
if(m_MajorVersion > 1 || m_MinorVersion > 5)
|
||||
{
|
||||
RDCERR("Unsupported SPIR-V version %u.%u", m_MajorVersion, m_MinorVersion);
|
||||
return new ShaderDebugTrace;
|
||||
debugStatus +=
|
||||
StringFormat::Fmt("Unsupported SPIR-V version %u.%u\n", m_MajorVersion, m_MinorVersion);
|
||||
debuggable = false;
|
||||
}
|
||||
|
||||
// whitelist supported extensions
|
||||
@@ -218,8 +212,8 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
|
||||
continue;
|
||||
}
|
||||
|
||||
RDCERR("Unsupported SPIR-V extension %s", ext.c_str());
|
||||
return new ShaderDebugTrace;
|
||||
debuggable = false;
|
||||
debugStatus += StringFormat::Fmt("Unsupported SPIR-V extension %s\n", ext.c_str());
|
||||
}
|
||||
|
||||
for(Capability c : capabilities)
|
||||
@@ -409,11 +403,40 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
|
||||
|
||||
if(!supported)
|
||||
{
|
||||
RDCERR("Unsupported capability '%s'", ToStr(c).c_str());
|
||||
return new ShaderDebugTrace;
|
||||
debuggable = false;
|
||||
debugStatus += StringFormat::Fmt("Unsupported capability '%s'\n", ToStr(c).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
for(auto it = extSets.begin(); it != extSets.end(); it++)
|
||||
{
|
||||
Id id = it->first;
|
||||
const rdcstr &setname = it->second;
|
||||
|
||||
if(setname == "GLSL.std.450" || setname.beginsWith("NonSemantic."))
|
||||
continue;
|
||||
|
||||
debuggable = false;
|
||||
debugStatus += StringFormat::Fmt("Unsupported extended instruction set: '%s'\n", setname.c_str());
|
||||
}
|
||||
|
||||
debugStatus.trim();
|
||||
}
|
||||
|
||||
ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const ShaderStage stage,
|
||||
const rdcstr &entryPoint,
|
||||
const rdcarray<SpecConstant> &specInfo,
|
||||
const std::map<size_t, uint32_t> &instructionLines,
|
||||
const SPIRVPatchData &patchData, uint32_t activeIndex)
|
||||
{
|
||||
Id entryId = entryLookup[entryPoint];
|
||||
|
||||
if(entryId == Id())
|
||||
{
|
||||
RDCERR("Invalid entry point '%s'", entryPoint.c_str());
|
||||
return new ShaderDebugTrace;
|
||||
}
|
||||
|
||||
global.clock = uint64_t(time(NULL)) << 32;
|
||||
|
||||
for(auto it = extSets.begin(); it != extSets.end(); it++)
|
||||
@@ -441,25 +464,6 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *apiWrapper, const Shader
|
||||
|
||||
global.extInsts[id] = extinst;
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unsupported extended instruction set: %s", setname.c_str());
|
||||
return new ShaderDebugTrace;
|
||||
}
|
||||
}
|
||||
|
||||
for(const rdcstr &e : extensions)
|
||||
{
|
||||
if(e == "SPV_GOOGLE_decorate_string" || e == "SPV_GOOGLE_hlsl_functionality1" ||
|
||||
e == "SPV_EXT_descriptor_indexing")
|
||||
{
|
||||
// supported extensions
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unsupported extension '%s'", e.c_str());
|
||||
return new ShaderDebugTrace;
|
||||
}
|
||||
}
|
||||
|
||||
ShaderDebugTrace *ret = new ShaderDebugTrace;
|
||||
|
||||
@@ -610,6 +610,8 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st
|
||||
reflection.encoding = ShaderEncoding::SPIRV;
|
||||
reflection.rawBytes.assign((byte *)m_SPIRV.data(), m_SPIRV.size() * sizeof(uint32_t));
|
||||
|
||||
CheckDebuggable(reflection.debugInfo.debuggable, reflection.debugInfo.debugStatus);
|
||||
|
||||
const EntryPoint *entry = NULL;
|
||||
for(const EntryPoint &e : entries)
|
||||
{
|
||||
@@ -1675,7 +1677,6 @@ void Reflector::AddSignatureParameter(const bool isInput, const ShaderStage stag
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace rdcspv
|
||||
|
||||
#if ENABLED(ENABLE_UNIT_TESTS)
|
||||
|
||||
@@ -98,6 +98,7 @@ private:
|
||||
virtual void UnregisterOp(Iter iter);
|
||||
|
||||
rdcstr StringiseConstant(rdcspv::Id id) const;
|
||||
void CheckDebuggable(bool &debuggable, rdcstr &debugStatus) const;
|
||||
|
||||
void MakeConstantBlockVariables(const DataType &structType, uint32_t arraySize,
|
||||
uint32_t arrayByteStride, rdcarray<ShaderConstant> &cblock,
|
||||
|
||||
@@ -3430,6 +3430,12 @@ ShaderDebugTrace *VulkanReplay::DebugVertex(uint32_t eventId, uint32_t vertid, u
|
||||
VulkanCreationInfo::ShaderModuleReflection &shadRefl =
|
||||
shader.GetReflection(entryPoint, state.graphics.pipeline);
|
||||
|
||||
if(!shadRefl.refl.debugInfo.debuggable)
|
||||
{
|
||||
RDCLOG("Shader is not debuggable: %s", shadRefl.refl.debugInfo.debugStatus.c_str());
|
||||
return new ShaderDebugTrace();
|
||||
}
|
||||
|
||||
shadRefl.PopulateDisassembly(shader.spirv);
|
||||
|
||||
VulkanAPIWrapper *apiWrapper =
|
||||
@@ -3635,6 +3641,12 @@ ShaderDebugTrace *VulkanReplay::DebugPixel(uint32_t eventId, uint32_t x, uint32_
|
||||
VulkanCreationInfo::ShaderModuleReflection &shadRefl =
|
||||
shader.GetReflection(entryPoint, state.graphics.pipeline);
|
||||
|
||||
if(!shadRefl.refl.debugInfo.debuggable)
|
||||
{
|
||||
RDCLOG("Shader is not debuggable: %s", shadRefl.refl.debugInfo.debugStatus.c_str());
|
||||
return new ShaderDebugTrace();
|
||||
}
|
||||
|
||||
shadRefl.PopulateDisassembly(shader.spirv);
|
||||
|
||||
VulkanAPIWrapper *apiWrapper =
|
||||
@@ -4292,6 +4304,12 @@ ShaderDebugTrace *VulkanReplay::DebugThread(uint32_t eventId, const uint32_t gro
|
||||
VulkanCreationInfo::ShaderModuleReflection &shadRefl =
|
||||
shader.GetReflection(entryPoint, state.compute.pipeline);
|
||||
|
||||
if(!shadRefl.refl.debugInfo.debuggable)
|
||||
{
|
||||
RDCLOG("Shader is not debuggable: %s", shadRefl.refl.debugInfo.debugStatus.c_str());
|
||||
return new ShaderDebugTrace();
|
||||
}
|
||||
|
||||
shadRefl.PopulateDisassembly(shader.spirv);
|
||||
|
||||
VulkanAPIWrapper *apiWrapper =
|
||||
|
||||
@@ -282,8 +282,10 @@ void DoSerialise(SerialiserType &ser, ShaderDebugInfo &el)
|
||||
SERIALISE_MEMBER(compileFlags);
|
||||
SERIALISE_MEMBER(files);
|
||||
SERIALISE_MEMBER(encoding);
|
||||
SERIALISE_MEMBER(debuggable);
|
||||
SERIALISE_MEMBER(debugStatus);
|
||||
|
||||
SIZE_CHECK(56);
|
||||
SIZE_CHECK(80);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
@@ -315,7 +317,7 @@ void DoSerialise(SerialiserType &ser, ShaderReflection &el)
|
||||
|
||||
SERIALISE_MEMBER(pointerTypes);
|
||||
|
||||
SIZE_CHECK(336);
|
||||
SIZE_CHECK(360);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
|
||||
@@ -120,7 +120,8 @@ class Buffer_Truncation(rdtest.TestCase):
|
||||
if not rdtest.value_compare(outcol.value.fv[0:4], [0.0, 0.0, 0.0, 0.0]):
|
||||
raise rdtest.TestFailureException("expected outcol to be 0s, but got {}".format(outcol.value.fv[0:4]))
|
||||
|
||||
if self.controller.GetAPIProperties().shaderDebugging:
|
||||
if self.controller.GetAPIProperties().shaderDebugging and pipe.GetShaderReflection(
|
||||
rd.ShaderStage.Pixel).debugInfo.debuggable:
|
||||
# Debug the shader
|
||||
trace: rd.ShaderDebugTrace = self.controller.DebugPixel(int(pipe.GetViewport(0).width/2),
|
||||
int(pipe.GetViewport(0).height/2),
|
||||
|
||||
@@ -115,7 +115,7 @@ class Draw_Zoo(rdtest.TestCase):
|
||||
|
||||
rdtest.log.success("Checked vertex out data in instance {}".format(inst))
|
||||
|
||||
if self.props.shaderDebugging:
|
||||
if self.props.shaderDebugging and refl.debugInfo.debuggable:
|
||||
for vtx in range(num_verts):
|
||||
if vtx in restarts:
|
||||
continue
|
||||
|
||||
@@ -27,9 +27,8 @@ class D3D11_CBuffer_Zoo(rdtest.TestCase):
|
||||
|
||||
rdtest.log.success("CBuffer variables are as expected")
|
||||
|
||||
props: rd.APIProperties = self.controller.GetAPIProperties()
|
||||
|
||||
if props.shaderDebugging:
|
||||
if self.controller.GetAPIProperties().shaderDebugging and pipe.GetShaderReflection(
|
||||
rd.ShaderStage.Pixel).debugInfo.debuggable:
|
||||
trace: rd.ShaderDebugTrace = self.controller.DebugPixel(int(pipe.GetViewport(0).width / 2.0),
|
||||
int(pipe.GetViewport(0).height / 2.0),
|
||||
rd.ReplayController.NoPreference,
|
||||
|
||||
@@ -64,9 +64,8 @@ class D3D12_CBuffer_Zoo(rdtest.TestCase):
|
||||
|
||||
rdtest.log.success("CBuffer variables are as expected")
|
||||
|
||||
props: rd.APIProperties = self.controller.GetAPIProperties()
|
||||
|
||||
if props.shaderDebugging:
|
||||
if self.controller.GetAPIProperties().shaderDebugging and pipe.GetShaderReflection(
|
||||
rd.ShaderStage.Pixel).debugInfo.debuggable:
|
||||
trace: rd.ShaderDebugTrace = self.controller.DebugPixel(int(pipe.GetViewport(0).width / 2.0),
|
||||
int(pipe.GetViewport(0).height / 2.0),
|
||||
rd.ReplayController.NoPreference,
|
||||
|
||||
@@ -10,6 +10,10 @@ class D3D12_PrimitiveID(rdtest.TestCase):
|
||||
self.controller.SetFrameEvent(draw.eventId, True)
|
||||
pipe: rd.PipeState = self.controller.GetPipelineState()
|
||||
|
||||
if not pipe.GetShaderReflection(rd.ShaderStage.Pixel).debugInfo.debuggable:
|
||||
rdtest.log.print("Skipping undebuggable shader at {}.".format(draw.name))
|
||||
return
|
||||
|
||||
trace: rd.ShaderDebugTrace = self.controller.DebugPixel(x, y, rd.ReplayController.NoPreference, prim)
|
||||
|
||||
cycles, variables = self.process_trace(trace)
|
||||
|
||||
@@ -9,6 +9,10 @@ class D3D12_Resource_Mapping_Zoo(rdtest.TestCase):
|
||||
def test_debug_pixel(self, x, y, test_name):
|
||||
pipe: rd.PipeState = self.controller.GetPipelineState()
|
||||
|
||||
if not pipe.GetShaderReflection(rd.ShaderStage.Pixel).debugInfo.debuggable:
|
||||
rdtest.log.print("Skipping undebuggable shader at {}.".format(test_name))
|
||||
return
|
||||
|
||||
# Debug the shader
|
||||
trace: rd.ShaderDebugTrace = self.controller.DebugPixel(x, y, rd.ReplayController.NoPreference,
|
||||
rd.ReplayController.NoPreference)
|
||||
|
||||
@@ -24,6 +24,10 @@ class D3D12_Shader_Debug_Zoo(rdtest.TestCase):
|
||||
|
||||
pipe: rd.PipeState = self.controller.GetPipelineState()
|
||||
|
||||
if not pipe.GetShaderReflection(rd.ShaderStage.Pixel).debugInfo.debuggable:
|
||||
rdtest.log.print("Skipping undebuggable shader at {}.".format(draw.name))
|
||||
return
|
||||
|
||||
# Loop over every test
|
||||
for test in range(draw.numInstances):
|
||||
# Debug the shader
|
||||
|
||||
@@ -22,6 +22,10 @@ class D3D12_Shader_Linkage_Zoo(rdtest.TestCase):
|
||||
self.controller.SetFrameEvent(drawcall.eventId, False)
|
||||
pipe: rd.PipeState = self.controller.GetPipelineState()
|
||||
|
||||
if not pipe.GetShaderReflection(rd.ShaderStage.Pixel).debugInfo.debuggable:
|
||||
rdtest.log.print("Skipping undebuggable shader at {}.".format(event_name))
|
||||
continue
|
||||
|
||||
# Debug the shader
|
||||
trace: rd.ShaderDebugTrace = self.controller.DebugPixel(200, 150, rd.ReplayController.NoPreference,
|
||||
rd.ReplayController.NoPreference)
|
||||
|
||||
@@ -21,6 +21,10 @@ class VK_Shader_Debug_Zoo(rdtest.TestCase):
|
||||
self.controller.SetFrameEvent(section.eventId, False)
|
||||
pipe: rd.PipeState = self.controller.GetPipelineState()
|
||||
|
||||
if not pipe.GetShaderReflection(rd.ShaderStage.Pixel).debugInfo.debuggable:
|
||||
rdtest.log.print("Skipping undebuggable shader at {} in {}.".format(child, test_name))
|
||||
return
|
||||
|
||||
for test in range(section.numInstances):
|
||||
x = 4 * test + 1
|
||||
y = 4 * child + 1
|
||||
|
||||
Reference in New Issue
Block a user