From 1fbf98a3b8b837fb5f54aeea15445e2fad6d922c Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 18 May 2016 22:12:32 +0200 Subject: [PATCH] Return a dummy ID3D11Debug interface if requested, but debug is disabled * Since RenderDoc controls the device creation, it will remove any debug flags if the appropriate capture option isn't enabled. This then means the real ID3D11Debug interface isn't available even though it "should" be. To fix this, we return a fake interface that does nothing but will at least satisfy user code expectations --- renderdoc/driver/d3d11/d3d11_device.cpp | 18 +++++++++++++- renderdoc/driver/d3d11/d3d11_device.h | 31 +++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index 380b88668..bdbd7d996 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -280,6 +280,7 @@ WrappedID3D11Device::WrappedID3D11Device(ID3D11Device* realDevice, D3D11InitPara m_Alive = true; m_DummyInfoQueue.m_pDevice = this; + m_DummyDebug.m_pDevice = this; m_WrappedDebug.m_pDevice = this; m_FrameCounter = 0; @@ -483,6 +484,18 @@ ULONG STDMETHODCALLTYPE DummyID3D11InfoQueue::Release() return 1; } +ULONG STDMETHODCALLTYPE DummyID3D11Debug::AddRef() +{ + m_pDevice->AddRef(); + return 1; +} + +ULONG STDMETHODCALLTYPE DummyID3D11Debug::Release() +{ + m_pDevice->Release(); + return 1; +} + HRESULT STDMETHODCALLTYPE WrappedID3D11Debug::QueryInterface(REFIID riid, void **ppvObject) { if(riid == __uuidof(ID3D11InfoQueue) @@ -674,7 +687,10 @@ HRESULT WrappedID3D11Device::QueryInterface(REFIID riid, void **ppvObject) } else { - return E_NOINTERFACE; + RDCWARN("Returning a dummy ID3D11Debug that does nothing. This ID3D11Debug will not work!"); + *ppvObject = (ID3D11Debug *)&m_DummyDebug; + m_DummyDebug.AddRef(); + return S_OK; } } else if(riid == IRenderDoc_uuid) diff --git a/renderdoc/driver/d3d11/d3d11_device.h b/renderdoc/driver/d3d11/d3d11_device.h index abcc7e771..d61a758d4 100644 --- a/renderdoc/driver/d3d11/d3d11_device.h +++ b/renderdoc/driver/d3d11/d3d11_device.h @@ -171,6 +171,36 @@ struct DummyID3D11InfoQueue : public ID3D11InfoQueue virtual BOOL STDMETHODCALLTYPE GetMuteDebugOutput() { return TRUE; } }; +// give every impression of working but do nothing. +// Same idea as DummyID3D11InfoQueue above, a dummy interface so that users +// expecting a ID3D11Debug don't get confused if we have turned off the debug +// layer and can't return the real one. +struct DummyID3D11Debug : public ID3D11Debug +{ + WrappedID3D11Device *m_pDevice; + + DummyID3D11Debug() {} + + ////////////////////////////// + // implement IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { return E_NOINTERFACE; } + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); + + ////////////////////////////// + // implement ID3D11Debug + virtual HRESULT STDMETHODCALLTYPE SetFeatureMask(UINT Mask) { return S_OK; } + virtual UINT STDMETHODCALLTYPE GetFeatureMask() { return 0; } + virtual HRESULT STDMETHODCALLTYPE SetPresentPerRenderOpDelay(UINT Milliseconds) { return S_OK; } + virtual UINT STDMETHODCALLTYPE GetPresentPerRenderOpDelay(void) { return 0; } + virtual HRESULT STDMETHODCALLTYPE SetSwapChain(IDXGISwapChain *pSwapChain) { return S_OK; } + virtual HRESULT STDMETHODCALLTYPE GetSwapChain(IDXGISwapChain **ppSwapChain) + { if(ppSwapChain) *ppSwapChain = NULL; return S_OK; } + virtual HRESULT STDMETHODCALLTYPE ValidateContext(ID3D11DeviceContext *pContext) { return S_OK; } + virtual HRESULT STDMETHODCALLTYPE ReportLiveDeviceObjects(D3D11_RLDO_FLAGS Flags) { return S_OK; } + virtual HRESULT STDMETHODCALLTYPE ValidateContextForDispatch(ID3D11DeviceContext *pContext) { return S_OK; } +}; + class WrappedID3D11ClassLinkage; enum CaptureFailReason; @@ -190,6 +220,7 @@ private: D3D11Replay m_Replay; DummyID3D11InfoQueue m_DummyInfoQueue; + DummyID3D11Debug m_DummyDebug; WrappedID3D11Debug m_WrappedDebug; unsigned int m_InternalRefcount;