diff --git a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp index 6ce043045..586ceebe8 100644 --- a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp @@ -3270,7 +3270,8 @@ void D3D12PipelineStateViewer::on_debugThread_clicked() // viewer takes ownership of the trace IShaderViewer *s = - m_Ctx.DebugShader(&bindMapping, shaderDetails, ResourceId(), trace, debugContext); + m_Ctx.DebugShader(&bindMapping, shaderDetails, + m_Ctx.CurPipelineState().GetComputePipelineObject(), trace, debugContext); m_Ctx.AddDockWindow(s->Widget(), DockReference::AddTo, this); } diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp index c51e4066c..465e90936 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp @@ -3968,7 +3968,8 @@ void VulkanPipelineStateViewer::on_debugThread_clicked() // viewer takes ownership of the trace IShaderViewer *s = - m_Ctx.DebugShader(&bindMapping, shaderDetails, ResourceId(), trace, debugContext); + m_Ctx.DebugShader(&bindMapping, shaderDetails, + m_Ctx.CurPipelineState().GetComputePipelineObject(), trace, debugContext); m_Ctx.AddDockWindow(s->Widget(), DockReference::AddTo, this); } diff --git a/qrenderdoc/Windows/ShaderViewer.cpp b/qrenderdoc/Windows/ShaderViewer.cpp index f7fc84dea..4095d76a5 100644 --- a/qrenderdoc/Windows/ShaderViewer.cpp +++ b/qrenderdoc/Windows/ShaderViewer.cpp @@ -385,7 +385,18 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR if(!me) return; - rdcarray targets = r->GetDisassemblyTargets(); + rdcarray targets = r->GetDisassemblyTargets(m_Pipeline != ResourceId()); + + if(m_Pipeline == ResourceId()) + { + rdcarray pipelineTargets = r->GetDisassemblyTargets(true); + + if(pipelineTargets.size() > targets.size()) + { + m_PipelineTargets = pipelineTargets; + m_PipelineTargets.removeIf([&targets](const rdcstr &t) { return targets.contains(t); }); + } + } rdcstr disasm = r->DisassembleShader(m_Pipeline, m_ShaderDetails, ""); @@ -410,6 +421,9 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR } } + if(!m_PipelineTargets.empty()) + targetNames << tr("More disassembly formats..."); + m_DisassemblyType->clear(); m_DisassemblyType->addItems(targetNames); m_DisassemblyType->setCurrentIndex(0); @@ -1385,6 +1399,26 @@ void ShaderViewer::disassemble_typeChanged(int index) } } + if(targetStr == tr("More disassembly formats...")) + { + QString text; + + text = + tr("; More disassembly formats are available with a pipeline. This shader view is not\n" + "; associated with any specific pipeline and shows only the shader itself.\n\n" + "; Viewing the shader from the pipeline state view with a pipeline bound will expose\n" + "; these other formats:\n\n"); + + for(const rdcstr &t : m_PipelineTargets) + text += QFormatStr("%1\n").arg(QString(t)); + + m_DisassemblyView->setReadOnly(false); + SetTextAndUpdateMargin0(m_DisassemblyView, text); + m_DisassemblyView->setReadOnly(true); + m_DisassemblyView->emptyUndoBuffer(); + return; + } + QPointer me(this); m_Ctx.Replay().AsyncInvoke([me, this, target](IReplayController *r) { diff --git a/qrenderdoc/Windows/ShaderViewer.h b/qrenderdoc/Windows/ShaderViewer.h index c3710f117..309107c6e 100644 --- a/qrenderdoc/Windows/ShaderViewer.h +++ b/qrenderdoc/Windows/ShaderViewer.h @@ -212,6 +212,7 @@ private: ShaderStage m_Stage; QString m_DebugContext; ResourceId m_Pipeline; + rdcarray m_PipelineTargets; ScintillaEdit *m_DisassemblyView = NULL; QFrame *m_DisassemblyToolbar = NULL; QWidget *m_DisassemblyFrame = NULL; diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index f4fbeca16..49ab348bb 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -520,10 +520,11 @@ values are implementation dependent but will always include a default target fir native disassembly of the shader. Further options may be available for additional diassembly views or hardware-specific ISA formats. +:param bool withPipeline: More disassembly may be available when a pipeline is specified. :return: The list of disassembly targets available. :rtype: ``list`` of ``str`` )"); - virtual rdcarray GetDisassemblyTargets() = 0; + virtual rdcarray GetDisassemblyTargets(bool withPipeline) = 0; DOCUMENT(R"(Retrieve the disassembly for a given shader, for the given disassembly target. diff --git a/renderdoc/core/image_viewer.cpp b/renderdoc/core/image_viewer.cpp index b30b3c35e..f39bcad08 100644 --- a/renderdoc/core/image_viewer.cpp +++ b/renderdoc/core/image_viewer.cpp @@ -262,7 +262,7 @@ public: { return NULL; } - rdcarray GetDisassemblyTargets() { return {"N/A"}; } + rdcarray GetDisassemblyTargets(bool withPipeline) { return {"N/A"}; } rdcstr DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, const rdcstr &target) { return ""; diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index 2e95859c4..b8420d884 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -1223,7 +1223,8 @@ rdcstr ReplayProxy::DisassembleShader(ResourceId pipeline, const ShaderReflectio template rdcarray ReplayProxy::Proxied_GetDisassemblyTargets(ParamSerialiser ¶mser, - ReturnSerialiser &retser) + ReturnSerialiser &retser, + bool withPipeline) { const ReplayProxyPacket expectedPacket = eReplayProxy_GetDisassemblyTargets; ReplayProxyPacket packet = eReplayProxy_GetDisassemblyTargets; @@ -1231,13 +1232,14 @@ rdcarray ReplayProxy::Proxied_GetDisassemblyTargets(ParamSerialiser &par { BEGIN_PARAMS(); + SERIALISE_ELEMENT(withPipeline); END_PARAMS(); } { REMOTE_EXECUTION(); if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) - ret = m_Remote->GetDisassemblyTargets(); + ret = m_Remote->GetDisassemblyTargets(withPipeline); } SERIALISE_RETURN(ret); @@ -1245,9 +1247,9 @@ rdcarray ReplayProxy::Proxied_GetDisassemblyTargets(ParamSerialiser &par return ret; } -rdcarray ReplayProxy::GetDisassemblyTargets() +rdcarray ReplayProxy::GetDisassemblyTargets(bool withPipeline) { - PROXY_FUNCTION(GetDisassemblyTargets); + PROXY_FUNCTION(GetDisassemblyTargets, withPipeline); } template @@ -2835,7 +2837,7 @@ bool ReplayProxy::Tick(int type) PixelHistory(rdcarray(), ResourceId(), 0, 0, Subresource(), CompType::Typeless); break; case eReplayProxy_DisassembleShader: DisassembleShader(ResourceId(), NULL, ""); break; - case eReplayProxy_GetDisassemblyTargets: GetDisassemblyTargets(); break; + case eReplayProxy_GetDisassemblyTargets: GetDisassemblyTargets(false); break; case eReplayProxy_GetTargetShaderEncodings: GetTargetShaderEncodings(); break; case eReplayProxy_GetDriverInfo: GetDriverInfo(); break; case eReplayProxy_GetAvailableGPUs: GetAvailableGPUs(); break; diff --git a/renderdoc/core/replay_proxy.h b/renderdoc/core/replay_proxy.h index 345087718..cafc5c554 100644 --- a/renderdoc/core/replay_proxy.h +++ b/renderdoc/core/replay_proxy.h @@ -514,7 +514,7 @@ public: IMPLEMENT_FUNCTION_PROXIED(ShaderReflection *, GetShader, ResourceId pipeline, ResourceId, ShaderEntryPoint entry); - IMPLEMENT_FUNCTION_PROXIED(rdcarray, GetDisassemblyTargets); + IMPLEMENT_FUNCTION_PROXIED(rdcarray, GetDisassemblyTargets, bool withPipeline); IMPLEMENT_FUNCTION_PROXIED(rdcstr, DisassembleShader, ResourceId pipeline, const ShaderReflection *refl, const rdcstr &target); diff --git a/renderdoc/driver/d3d11/d3d11_replay.cpp b/renderdoc/driver/d3d11/d3d11_replay.cpp index 49b00b39d..0b8528971 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.cpp +++ b/renderdoc/driver/d3d11/d3d11_replay.cpp @@ -284,7 +284,7 @@ ShaderReflection *D3D11Replay::GetShader(ResourceId pipeline, ResourceId shader, return &ret; } -rdcarray D3D11Replay::GetDisassemblyTargets() +rdcarray D3D11Replay::GetDisassemblyTargets(bool withPipeline) { return {DXBCDisassemblyTarget}; } diff --git a/renderdoc/driver/d3d11/d3d11_replay.h b/renderdoc/driver/d3d11/d3d11_replay.h index ef9d49dbc..ccc1f01ad 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.h +++ b/renderdoc/driver/d3d11/d3d11_replay.h @@ -130,7 +130,7 @@ public: rdcarray GetShaderEntryPoints(ResourceId shader); ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, ShaderEntryPoint entry); - rdcarray GetDisassemblyTargets(); + rdcarray GetDisassemblyTargets(bool withPipeline); rdcstr DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, const rdcstr &target); rdcarray GetUsage(ResourceId id); diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index a8aa60742..ebbbd35c2 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -434,7 +434,7 @@ ShaderReflection *D3D12Replay::GetShader(ResourceId pipeline, ResourceId shader, return NULL; } -rdcarray D3D12Replay::GetDisassemblyTargets() +rdcarray D3D12Replay::GetDisassemblyTargets(bool withPipeline) { rdcarray ret; diff --git a/renderdoc/driver/d3d12/d3d12_replay.h b/renderdoc/driver/d3d12/d3d12_replay.h index a82c44950..f1cd9a671 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.h +++ b/renderdoc/driver/d3d12/d3d12_replay.h @@ -83,7 +83,7 @@ public: rdcarray GetShaderEntryPoints(ResourceId shader); ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, ShaderEntryPoint entry); - rdcarray GetDisassemblyTargets(); + rdcarray GetDisassemblyTargets(bool withPipeline); rdcstr DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, const rdcstr &target); rdcarray GetUsage(ResourceId id); diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 80462d317..c72aaafcf 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -766,7 +766,7 @@ ShaderReflection *GLReplay::GetShader(ResourceId pipeline, ResourceId shader, Sh return &shaderDetails.reflection; } -rdcarray GLReplay::GetDisassemblyTargets() +rdcarray GLReplay::GetDisassemblyTargets(bool withPipeline) { return {SPIRVDisassemblyTarget}; } diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index 2af8f89b3..acbd8496e 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -129,7 +129,7 @@ public: rdcarray GetShaderEntryPoints(ResourceId shader); ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, ShaderEntryPoint entry); - rdcarray GetDisassemblyTargets(); + rdcarray GetDisassemblyTargets(bool withPipeline); rdcstr DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, const rdcstr &target); rdcarray GetDebugMessages(); diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index d7f52efcc..fabb9b93d 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -443,14 +443,14 @@ ShaderReflection *VulkanReplay::GetShader(ResourceId pipeline, ResourceId shader return &shad->second.GetReflection(entry.name, pipeline).refl; } -rdcarray VulkanReplay::GetDisassemblyTargets() +rdcarray VulkanReplay::GetDisassemblyTargets(bool withPipeline) { rdcarray ret; - if(m_pDriver->GetExtensions(NULL).ext_AMD_shader_info) + if(withPipeline && m_pDriver->GetExtensions(NULL).ext_AMD_shader_info) ret.push_back(AMDShaderInfoTarget); - if(m_pDriver->GetExtensions(NULL).ext_KHR_pipeline_executable_properties) + if(withPipeline && m_pDriver->GetExtensions(NULL).ext_KHR_pipeline_executable_properties) ret.push_back(KHRExecutablePropertiesTarget); // default is always first diff --git a/renderdoc/driver/vulkan/vk_replay.h b/renderdoc/driver/vulkan/vk_replay.h index 87d388674..60b0df7ca 100644 --- a/renderdoc/driver/vulkan/vk_replay.h +++ b/renderdoc/driver/vulkan/vk_replay.h @@ -273,7 +273,7 @@ public: rdcarray GetShaderEntryPoints(ResourceId shader); ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, ShaderEntryPoint entry); - rdcarray GetDisassemblyTargets(); + rdcarray GetDisassemblyTargets(bool withPipeline); rdcstr DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, const rdcstr &target); rdcarray GetUsage(ResourceId id); diff --git a/renderdoc/replay/replay_controller.cpp b/renderdoc/replay/replay_controller.cpp index 8773f0077..50f6fa67d 100644 --- a/renderdoc/replay/replay_controller.cpp +++ b/renderdoc/replay/replay_controller.cpp @@ -142,13 +142,13 @@ const PipeState &ReplayController::GetPipelineState() return m_PipeState; } -rdcarray ReplayController::GetDisassemblyTargets() +rdcarray ReplayController::GetDisassemblyTargets(bool withPipeline) { CHECK_REPLAY_THREAD(); rdcarray ret; - rdcarray targets = m_pDevice->GetDisassemblyTargets(); + rdcarray targets = m_pDevice->GetDisassemblyTargets(withPipeline); ret.reserve(targets.size()); for(const rdcstr &t : targets) diff --git a/renderdoc/replay/replay_controller.h b/renderdoc/replay/replay_controller.h index 4f806d82e..598193183 100644 --- a/renderdoc/replay/replay_controller.h +++ b/renderdoc/replay/replay_controller.h @@ -143,7 +143,7 @@ public: const VKPipe::State *GetVulkanPipelineState(); const PipeState &GetPipelineState(); - rdcarray GetDisassemblyTargets(); + rdcarray GetDisassemblyTargets(bool withPipeline); rdcstr DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, const char *target); rdcpair BuildCustomShader(const char *entry, ShaderEncoding sourceEncoding, diff --git a/renderdoc/replay/replay_driver.h b/renderdoc/replay/replay_driver.h index 456236683..afa9de134 100644 --- a/renderdoc/replay/replay_driver.h +++ b/renderdoc/replay/replay_driver.h @@ -148,7 +148,7 @@ public: virtual ShaderReflection *GetShader(ResourceId pipeline, ResourceId shader, ShaderEntryPoint entry) = 0; - virtual rdcarray GetDisassemblyTargets() = 0; + virtual rdcarray GetDisassemblyTargets(bool withPipeline) = 0; virtual rdcstr DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, const rdcstr &target) = 0;