From 09d63180d170da069fbabfa26a28f528018a5b17 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 22 Nov 2018 13:00:18 +0000 Subject: [PATCH] Add API option for applications that need access to vendor extensions * This happens at the application's risk since there's no way to know what effect the vendor extension will have or even if it will work together with renderdoc's hooking. --- renderdoc/api/app/renderdoc_app.h | 9 ++++++++ renderdoc/core/core.cpp | 30 +++++++++++++++++++++++--- renderdoc/core/core.h | 19 ++++++++++++++++ renderdoc/driver/d3d11/d3d11_hooks.cpp | 12 +++++++++-- renderdoc/replay/capture_options.cpp | 11 ++++++++++ 5 files changed, 76 insertions(+), 5 deletions(-) diff --git a/renderdoc/api/app/renderdoc_app.h b/renderdoc/api/app/renderdoc_app.h index 931c8c950..e71d1caf3 100644 --- a/renderdoc/api/app/renderdoc_app.h +++ b/renderdoc/api/app/renderdoc_app.h @@ -195,6 +195,15 @@ typedef enum RENDERDOC_CaptureOption { // 0 - API debugging is displayed as normal eRENDERDOC_Option_DebugOutputMute = 11, + // Option to allow vendor extensions to be used even when they may be + // incompatible with RenderDoc and cause corrupted replays or crashes. + // + // Default - inactive + // + // No values are documented, this option should only be used when absolutely + // necessary as directed by a RenderDoc developer. + eRENDERDOC_Option_AllowUnsupportedVendorExtensions = 12, + } RENDERDOC_CaptureOption; // Sets an option that controls how RenderDoc behaves on capture. diff --git a/renderdoc/core/core.cpp b/renderdoc/core/core.cpp index 910279e9a..2743c5ef3 100644 --- a/renderdoc/core/core.cpp +++ b/renderdoc/core/core.cpp @@ -86,9 +86,21 @@ std::string DoStringise(const ReplayLogType &el) { BEGIN_ENUM_STRINGISE(ReplayLogType); { - STRINGISE_ENUM_CLASS_NAMED(eReplay_Full, "Full replay including draw"); - STRINGISE_ENUM_CLASS_NAMED(eReplay_WithoutDraw, "Replay without draw"); - STRINGISE_ENUM_CLASS_NAMED(eReplay_OnlyDraw, "Replay only draw"); + STRINGISE_ENUM_NAMED(eReplay_Full, "Full replay including draw"); + STRINGISE_ENUM_NAMED(eReplay_WithoutDraw, "Replay without draw"); + STRINGISE_ENUM_NAMED(eReplay_OnlyDraw, "Replay only draw"); + } + END_ENUM_STRINGISE(); +} + +template <> +std::string DoStringise(const VendorExtensions &el) +{ + BEGIN_ENUM_STRINGISE(VendorExtensions); + { + STRINGISE_ENUM_CLASS(NvAPI); + STRINGISE_ENUM_CLASS_NAMED(OpenGL_Ext, "Unsupported GL extensions"); + STRINGISE_ENUM_CLASS_NAMED(Vulkan_Ext, "Unsupported Vulkan extensions"); } END_ENUM_STRINGISE(); } @@ -1047,6 +1059,18 @@ map RenderDoc::GetRemoteDrivers() return ret; } +void RenderDoc::EnableVendorExtensions(VendorExtensions ext) +{ + m_VendorExts[(int)ext] = true; + + RDCWARN("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + RDCWARN("!!! Vendor Extension enabled: %s", ToStr(ext).c_str()); + RDCWARN("!!! "); + RDCWARN("!!! This can cause crashes, incorrect replay, or other problems and"); + RDCWARN("!!! is explicitly unsupported. Do not enable without understanding."); + RDCWARN("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); +} + void RenderDoc::SetCaptureOptions(const CaptureOptions &opts) { m_Options = opts; diff --git a/renderdoc/core/core.h b/renderdoc/core/core.h index 58484daae..9096a015b 100644 --- a/renderdoc/core/core.h +++ b/renderdoc/core/core.h @@ -206,6 +206,18 @@ enum ReplayLogType DECLARE_REFLECTION_ENUM(ReplayLogType); +enum class VendorExtensions +{ + NvAPI = 0, + First = NvAPI, + OpenGL_Ext, + Vulkan_Ext, + Count, +}; + +DECLARE_REFLECTION_ENUM(VendorExtensions); +ITERABLE_OPERATORS(VendorExtensions); + struct CaptureData { CaptureData(string p, uint64_t t, RDCDriver d, uint32_t f) @@ -386,6 +398,11 @@ public: void BecomeRemoteServer(const char *listenhost, uint16_t port, RENDERDOC_KillCallback killReplay, RENDERDOC_PreviewWindowCallback previewWindow); + // can't be disabled, only enabled then latched + + bool IsVendorExtensionEnabled(VendorExtensions ext) { return m_VendorExts[(int)ext]; } + void EnableVendorExtensions(VendorExtensions ext); + void SetCaptureOptions(const CaptureOptions &opts); const CaptureOptions &GetCaptureOptions() const { return m_Options; } void RecreateCrashHandler(); @@ -642,6 +659,8 @@ private: IFrameCapturer *MatchFrameCapturer(void *dev, void *wnd); + bool m_VendorExts[ENUM_ARRAY_SIZE(VendorExtensions)] = {}; + volatile bool m_TargetControlThreadShutdown; volatile bool m_ControlClientThreadShutdown; Threading::CriticalSection m_SingleClientLock; diff --git a/renderdoc/driver/d3d11/d3d11_hooks.cpp b/renderdoc/driver/d3d11/d3d11_hooks.cpp index 13591d3af..7a9eaa9fb 100644 --- a/renderdoc/driver/d3d11/d3d11_hooks.cpp +++ b/renderdoc/driver/d3d11/d3d11_hooks.cpp @@ -416,8 +416,16 @@ private: } else { - RDCWARN("Returning NULL for nvapi_QueryInterface(%x)", ID); - return NULL; + if(RenderDoc::Inst().IsVendorExtensionEnabled(VendorExtensions::NvAPI)) + { + RDCDEBUG("NvAPI allowed: Returning %p for nvapi_QueryInterface(%x)", real, ID); + return real; + } + else + { + RDCWARN("NvAPI disabled: Returning NULL for nvapi_QueryInterface(%x)", ID); + return NULL; + } } } diff --git a/renderdoc/replay/capture_options.cpp b/renderdoc/replay/capture_options.cpp index 9b29c9462..461572a19 100644 --- a/renderdoc/replay/capture_options.cpp +++ b/renderdoc/replay/capture_options.cpp @@ -50,6 +50,12 @@ int RENDERDOC_CC SetCaptureOptionU32(RENDERDOC_CaptureOption opt, uint32_t val) break; case eRENDERDOC_Option_CaptureAllCmdLists: opts.captureAllCmdLists = (val != 0); break; case eRENDERDOC_Option_DebugOutputMute: opts.debugOutputMute = (val != 0); break; + case eRENDERDOC_Option_AllowUnsupportedVendorExtensions: + if(val == 0x10DE) + RenderDoc::Inst().EnableVendorExtensions(VendorExtensions::NvAPI); + else + RDCWARN("AllowUnsupportedVendorExtensions unexpected parameter %x", val); + break; default: RDCLOG("Unrecognised capture option '%d'", opt); return 0; } @@ -79,6 +85,9 @@ int RENDERDOC_CC SetCaptureOptionF32(RENDERDOC_CaptureOption opt, float val) break; case eRENDERDOC_Option_CaptureAllCmdLists: opts.captureAllCmdLists = (val != 0.0f); break; case eRENDERDOC_Option_DebugOutputMute: opts.debugOutputMute = (val != 0.0f); break; + case eRENDERDOC_Option_AllowUnsupportedVendorExtensions: + RDCWARN("AllowUnsupportedVendorExtensions unexpected parameter %f", val); + break; default: RDCLOG("Unrecognised capture option '%d'", opt); return 0; } @@ -115,6 +124,7 @@ uint32_t RENDERDOC_CC GetCaptureOptionU32(RENDERDOC_CaptureOption opt) return (RenderDoc::Inst().GetCaptureOptions().captureAllCmdLists ? 1 : 0); case eRENDERDOC_Option_DebugOutputMute: return (RenderDoc::Inst().GetCaptureOptions().debugOutputMute ? 1 : 0); + case eRENDERDOC_Option_AllowUnsupportedVendorExtensions: return 0; default: break; } @@ -151,6 +161,7 @@ float RENDERDOC_CC GetCaptureOptionF32(RENDERDOC_CaptureOption opt) return (RenderDoc::Inst().GetCaptureOptions().captureAllCmdLists ? 1.0f : 0.0f); case eRENDERDOC_Option_DebugOutputMute: return (RenderDoc::Inst().GetCaptureOptions().debugOutputMute ? 1.0f : 0.0f); + case eRENDERDOC_Option_AllowUnsupportedVendorExtensions: return 0.0f; default: break; }