diff --git a/qrenderdoc/Code/CaptureContext.cpp b/qrenderdoc/Code/CaptureContext.cpp index 6bc4172e7..93e0d6219 100644 --- a/qrenderdoc/Code/CaptureContext.cpp +++ b/qrenderdoc/Code/CaptureContext.cpp @@ -279,6 +279,8 @@ void CaptureContext::LoadCaptureThreaded(const QString &captureFile, const QStri m_APIProps = r->GetAPIProperties(); + m_TargetEncodings = r->GetTargetShaderEncodings(); + m_PostloadProgress = 0.2f; m_Drawcalls = &r->GetDrawcalls(); diff --git a/qrenderdoc/Code/CaptureContext.h b/qrenderdoc/Code/CaptureContext.h index ae62692c1..921c59d46 100644 --- a/qrenderdoc/Code/CaptureContext.h +++ b/qrenderdoc/Code/CaptureContext.h @@ -107,6 +107,7 @@ public: CaptureModifications GetCaptureModifications() override { return m_CaptureMods; } const FrameDescription &FrameInfo() override { return m_FrameInfo; } const APIProperties &APIProps() override { return m_APIProps; } + rdcarray TargetShaderEncodings() { return m_TargetEncodings; } uint32_t CurSelectedEvent() override { return m_SelectedEventID; } uint32_t CurEvent() override { return m_EventID; } const DrawcallDescription *CurSelectedDrawcall() override @@ -292,6 +293,7 @@ private: const rdcarray *m_Drawcalls; rdcarray m_EmptyDraws; + rdcarray m_TargetEncodings; APIProperties m_APIProps; FrameDescription m_FrameInfo; const DrawcallDescription *m_FirstDrawcall = NULL; diff --git a/qrenderdoc/Code/Interface/QRDInterface.h b/qrenderdoc/Code/Interface/QRDInterface.h index 34e5308bd..cfba336d9 100644 --- a/qrenderdoc/Code/Interface/QRDInterface.h +++ b/qrenderdoc/Code/Interface/QRDInterface.h @@ -1184,6 +1184,15 @@ the UI which aren't reflected in the capture file on disk. )"); virtual const APIProperties &APIProps() = 0; + DOCUMENT(R"(Retrieve the list of :class:`~renderdoc.ShaderEncoding` that are available for +building target shaders for the currently loaded capture. See +:meth:`~renderdoc.ReplayController.BuildTargetShader`. + +:return: The available encodings. +:rtype: ``list`` of :class:`~renderdoc.ShaderEncoding` +)"); + virtual rdcarray TargetShaderEncodings() = 0; + DOCUMENT(R"(Retrieve the currently selected :data:`eventId `. In most cases, prefer using :meth:`CurEvent`. See :meth:`CaptureViewer.OnSelectedEventChanged` for more diff --git a/qrenderdoc/Code/pyrenderdoc/renderdoc.i b/qrenderdoc/Code/pyrenderdoc/renderdoc.i index 6a411234b..c70a4f190 100644 --- a/qrenderdoc/Code/pyrenderdoc/renderdoc.i +++ b/qrenderdoc/Code/pyrenderdoc/renderdoc.i @@ -265,6 +265,7 @@ TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderResource) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderSampler) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderSourceFile) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderVariable) +TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderEncoding) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, RegisterRange) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, LocalVariableMapping) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, SigParameter) diff --git a/qrenderdoc/Windows/PythonShell.cpp b/qrenderdoc/Windows/PythonShell.cpp index 730284d6b..20cf99e7c 100644 --- a/qrenderdoc/Windows/PythonShell.cpp +++ b/qrenderdoc/Windows/PythonShell.cpp @@ -64,6 +64,7 @@ struct CaptureContextInvoker : ICaptureContext } virtual const FrameDescription &FrameInfo() override { return m_Ctx.FrameInfo(); } virtual const APIProperties &APIProps() override { return m_Ctx.APIProps(); } + virtual rdcarray TargetShaderEncodings() { return m_Ctx.TargetShaderEncodings(); } virtual uint32_t CurSelectedEvent() override { return m_Ctx.CurSelectedEvent(); } virtual uint32_t CurEvent() override { return m_Ctx.CurEvent(); } virtual const DrawcallDescription *CurSelectedDrawcall() override diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index 25e38786f..47cffc3a4 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -892,6 +892,21 @@ The language used is native to the API's renderer - HLSL for D3D based renderers const ShaderCompileFlags &flags, ShaderStage type) = 0; + DOCUMENT(R"(Retrieve the list of supported :class:`ShaderEncoding` which can be build using +:meth:`BuildTargetShader`. + +The list is sorted in priority order, so if the caller has a shader in a form but could +compile/translate it to another, prefer to satisfy the first encoding before later encodings. + +This typically means the 'native' encoding is listed first, and then subsequent encodings are +compiled internally - so compiling externally could be preferable as it allows better customisation +of the compile process or using alternate/updated tools. + +:return: The list of target shader encodings available. +:rtype: ``list`` of :class:`ShaderEncoding` +)"); + virtual rdcarray GetTargetShaderEncodings() = 0; + DOCUMENT(R"(Replace one resource with another for subsequent replay and analysis work. This is commonly used for modifying the capture by selectively replacing resources with newly diff --git a/renderdoc/core/image_viewer.cpp b/renderdoc/core/image_viewer.cpp index cd6212949..4baac3ea6 100644 --- a/renderdoc/core/image_viewer.cpp +++ b/renderdoc/core/image_viewer.cpp @@ -245,6 +245,7 @@ public: void BuildTargetShader(string source, string entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId *id, string *errors) { + rdcarray GetTargetShaderEncodings() { return {}; } } void ReplaceResource(ResourceId from, ResourceId to) {} void RemoveReplacement(ResourceId id) {} diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index 70a65e8ec..69425b83d 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -960,6 +960,31 @@ void ReplayProxy::FreeTargetResource(ResourceId id) PROXY_FUNCTION(FreeTargetResource, id); } +template +rdcarray ReplayProxy::Proxied_GetTargetShaderEncodings(ParamSerialiser ¶mser, + ReturnSerialiser &retser) +{ + const ReplayProxyPacket packet = eReplayProxy_GetTargetShaderEncodings; + rdcarray ret; + + { + BEGIN_PARAMS(); + END_PARAMS(); + } + + if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored) + ret = m_Remote->GetTargetShaderEncodings(); + + SERIALISE_RETURN(ret); + + return ret; +} + +rdcarray ReplayProxy::GetTargetShaderEncodings() +{ + PROXY_FUNCTION(GetTargetShaderEncodings); +} + template void ReplayProxy::Proxied_BuildTargetShader(ParamSerialiser ¶mser, ReturnSerialiser &retser, std::string source, std::string entry, @@ -2098,6 +2123,7 @@ bool ReplayProxy::Tick(int type) break; case eReplayProxy_DisassembleShader: DisassembleShader(ResourceId(), NULL, ""); break; case eReplayProxy_GetDisassemblyTargets: GetDisassemblyTargets(); break; + case eReplayProxy_GetTargetShaderEncodings: GetTargetShaderEncodings(); break; default: RDCERR("Unexpected command %u", type); return false; } diff --git a/renderdoc/core/replay_proxy.h b/renderdoc/core/replay_proxy.h index f1aaddaa9..c3abce9ce 100644 --- a/renderdoc/core/replay_proxy.h +++ b/renderdoc/core/replay_proxy.h @@ -93,6 +93,7 @@ enum ReplayProxyPacket eReplayProxy_DisassembleShader, eReplayProxy_GetDisassemblyTargets, + eReplayProxy_GetTargetShaderEncodings, }; #define IMPLEMENT_FUNCTION_PROXIED(rettype, name, ...) \ @@ -496,6 +497,7 @@ public: IMPLEMENT_FUNCTION_PROXIED(void, BuildTargetShader, std::string source, std::string entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId *id, std::string *errors); + IMPLEMENT_FUNCTION_PROXIED(rdcarray, GetTargetShaderEncodings); IMPLEMENT_FUNCTION_PROXIED(void, ReplaceResource, ResourceId from, ResourceId to); IMPLEMENT_FUNCTION_PROXIED(void, RemoveReplacement, ResourceId id); diff --git a/renderdoc/driver/d3d11/d3d11_replay.h b/renderdoc/driver/d3d11/d3d11_replay.h index 27a329f9f..2ee266bb4 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.h +++ b/renderdoc/driver/d3d11/d3d11_replay.h @@ -178,6 +178,10 @@ public: void BuildTargetShader(string source, string entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId *id, string *errors); + rdcarray GetTargetShaderEncodings() + { + return {ShaderEncoding::DXBC, ShaderEncoding::HLSL}; + } void ReplaceResource(ResourceId from, ResourceId to); void RemoveReplacement(ResourceId id); diff --git a/renderdoc/driver/d3d12/d3d12_replay.h b/renderdoc/driver/d3d12/d3d12_replay.h index 210ba2791..f4e4ac292 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.h +++ b/renderdoc/driver/d3d12/d3d12_replay.h @@ -138,6 +138,10 @@ public: void BuildTargetShader(string source, string entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId *id, string *errors); + rdcarray GetTargetShaderEncodings() + { + return {ShaderEncoding::DXBC, ShaderEncoding::HLSL}; + } void ReplaceResource(ResourceId from, ResourceId to); void RemoveReplacement(ResourceId id); diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index 62645a4f7..5ab4dcef6 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -180,6 +180,7 @@ public: void BuildTargetShader(string source, string entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId *id, string *errors); + rdcarray GetTargetShaderEncodings() { return {ShaderEncoding::GLSL}; } void BuildCustomShader(string source, string entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId *id, string *errors); void FreeCustomShader(ResourceId id); diff --git a/renderdoc/driver/vulkan/vk_replay.h b/renderdoc/driver/vulkan/vk_replay.h index 9d42885a6..0bbab55bb 100644 --- a/renderdoc/driver/vulkan/vk_replay.h +++ b/renderdoc/driver/vulkan/vk_replay.h @@ -267,6 +267,10 @@ public: void BuildTargetShader(string source, string entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId *id, string *errors); + rdcarray GetTargetShaderEncodings() + { + return {ShaderEncoding::SPIRV, ShaderEncoding::GLSL}; + } void BuildCustomShader(string source, string entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId *id, string *errors); void FreeCustomShader(ResourceId id); diff --git a/renderdoc/replay/replay_controller.cpp b/renderdoc/replay/replay_controller.cpp index d3eb4f1ca..36b9d0eb2 100644 --- a/renderdoc/replay/replay_controller.cpp +++ b/renderdoc/replay/replay_controller.cpp @@ -1771,6 +1771,11 @@ void ReplayController::Shutdown() delete this; } +rdcarray ReplayController::GetTargetShaderEncodings() +{ + return m_pDevice->GetTargetShaderEncodings(); +} + rdcpair ReplayController::BuildTargetShader( const char *entry, const char *source, const ShaderCompileFlags &compileFlags, ShaderStage type) { diff --git a/renderdoc/replay/replay_controller.h b/renderdoc/replay/replay_controller.h index 20539dbdb..e060771bc 100644 --- a/renderdoc/replay/replay_controller.h +++ b/renderdoc/replay/replay_controller.h @@ -151,6 +151,7 @@ public: void FreeCustomShader(ResourceId id); rdcpair BuildTargetShader(const char *entry, const char *source, + rdcarray GetTargetShaderEncodings(); const ShaderCompileFlags &compileFlags, ShaderStage type); void ReplaceResource(ResourceId from, ResourceId to); diff --git a/renderdoc/replay/replay_driver.h b/renderdoc/replay/replay_driver.h index 8bb4028e1..921b08996 100644 --- a/renderdoc/replay/replay_driver.h +++ b/renderdoc/replay/replay_driver.h @@ -139,6 +139,7 @@ public: virtual void BuildTargetShader(string source, string entry, const ShaderCompileFlags &compileFlags, ShaderStage type, ResourceId *id, string *errors) = 0; + virtual rdcarray GetTargetShaderEncodings() = 0; virtual void ReplaceResource(ResourceId from, ResourceId to) = 0; virtual void RemoveReplacement(ResourceId id) = 0; virtual void FreeTargetResource(ResourceId id) = 0;