diff --git a/renderdoc/driver/d3d11/d3d11_context.cpp b/renderdoc/driver/d3d11/d3d11_context.cpp index d707bb171..1f52a915e 100644 --- a/renderdoc/driver/d3d11/d3d11_context.cpp +++ b/renderdoc/driver/d3d11/d3d11_context.cpp @@ -1326,6 +1326,8 @@ void WrappedID3D11DeviceContext::ClearMaps() HRESULT STDMETHODCALLTYPE WrappedID3D11DeviceContext::QueryInterface( REFIID riid, void **ppvObject ) { + HRESULT hr = S_OK; + if(riid == __uuidof(ID3D11DeviceContext)) { *ppvObject = (ID3D11DeviceContext *)this; @@ -1341,16 +1343,30 @@ HRESULT STDMETHODCALLTYPE WrappedID3D11DeviceContext::QueryInterface( REFIID rii #if defined(INCLUDE_D3D_11_1) else if(riid == __uuidof(ID3D11DeviceContext1)) { - *ppvObject = (ID3D11DeviceContext1 *)this; - AddRef(); - return S_OK; + if(m_pRealContext1) + { + *ppvObject = (ID3D11DeviceContext1 *)this; + AddRef(); + return S_OK; + } + else + { + return E_NOINTERFACE; + } } else if(riid == __uuidof(ID3D11DeviceContext2)) { - *ppvObject = (ID3D11DeviceContext2 *)this; - AddRef(); - RDCWARN("Trying to get ID3D11Device2. DX11.2 tiled resources are not supported at this time."); - return S_OK; + if(m_pRealContext2) + { + *ppvObject = (ID3D11DeviceContext2 *)this; + AddRef(); + RDCWARN("Trying to get ID3D11DeviceContext2. DX11.2 tiled resources are not supported at this time."); + return S_OK; + } + else + { + return E_NOINTERFACE; + } } else if(riid == __uuidof(ID3DUserDefinedAnnotation)) { diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index c8d58bb3b..fac3b664a 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -493,38 +493,72 @@ HRESULT WrappedID3D11Device::QueryInterface(REFIID riid, void **ppvObject) // DEFINE_GUID(IID_IDirect3DDevice9, 0xd0223b96, 0xbf7a, 0x43fd, 0x92, 0xbd, 0xa4, 0x3b, 0xd, 0x82, 0xb9, 0xeb); static const GUID IDirect3DDevice9_uuid = { 0xd0223b96, 0xbf7a, 0x43fd, { 0x92, 0xbd, 0xa4, 0x3b, 0xd, 0x82, 0xb9, 0xeb } }; + HRESULT hr = S_OK; + if(riid == __uuidof(IDXGIDevice)) { - m_pDevice->QueryInterface(riid, ppvObject); + hr = m_pDevice->QueryInterface(riid, ppvObject); - IDXGIDevice *real = (IDXGIDevice *)(*ppvObject); - *ppvObject = new WrappedIDXGIDevice(real, this); - return S_OK; + if(SUCCEEDED(hr)) + { + IDXGIDevice *real = (IDXGIDevice *)(*ppvObject); + *ppvObject = new WrappedIDXGIDevice(real, this); + return S_OK; + } + else + { + *ppvObject = NULL; + return hr; + } } else if(riid == __uuidof(IDXGIDevice1)) { - m_pDevice->QueryInterface(riid, ppvObject); - - IDXGIDevice1 *real = (IDXGIDevice1 *)(*ppvObject); - *ppvObject = new WrappedIDXGIDevice1(real, this); - return S_OK; + hr = m_pDevice->QueryInterface(riid, ppvObject); + + if(SUCCEEDED(hr)) + { + IDXGIDevice1 *real = (IDXGIDevice1 *)(*ppvObject); + *ppvObject = new WrappedIDXGIDevice1(real, this); + return S_OK; + } + else + { + *ppvObject = NULL; + return hr; + } } #if defined(INCLUDE_DXGI_1_2) else if(riid == __uuidof(IDXGIDevice2)) { - m_pDevice->QueryInterface(riid, ppvObject); - - IDXGIDevice2 *real = (IDXGIDevice2 *)(*ppvObject); - *ppvObject = new WrappedIDXGIDevice2(real, this); - return S_OK; + hr = m_pDevice->QueryInterface(riid, ppvObject); + + if(SUCCEEDED(hr)) + { + IDXGIDevice2 *real = (IDXGIDevice2 *)(*ppvObject); + *ppvObject = new WrappedIDXGIDevice2(real, this); + return S_OK; + } + else + { + *ppvObject = NULL; + return hr; + } } else if(riid == __uuidof(IDXGIDevice3)) { - m_pDevice->QueryInterface(riid, ppvObject); - - IDXGIDevice3 *real = (IDXGIDevice3 *)(*ppvObject); - *ppvObject = new WrappedIDXGIDevice3(real, this); - return S_OK; + hr = m_pDevice->QueryInterface(riid, ppvObject); + + if(SUCCEEDED(hr)) + { + IDXGIDevice3 *real = (IDXGIDevice3 *)(*ppvObject); + *ppvObject = new WrappedIDXGIDevice3(real, this); + return S_OK; + } + else + { + *ppvObject = NULL; + return hr; + } } #endif else if(riid == __uuidof(ID3D11Device)) @@ -548,16 +582,30 @@ HRESULT WrappedID3D11Device::QueryInterface(REFIID riid, void **ppvObject) #if defined(INCLUDE_D3D_11_1) else if(riid == __uuidof(ID3D11Device1)) { - AddRef(); - *ppvObject = (ID3D11Device1 *)this; - return S_OK; + if(m_pDevice1) + { + AddRef(); + *ppvObject = (ID3D11Device1 *)this; + return S_OK; + } + else + { + return E_NOINTERFACE; + } } else if(riid == __uuidof(ID3D11Device2)) { - AddRef(); - *ppvObject = (ID3D11Device2 *)this; - RDCWARN("Trying to get ID3D11Device2. DX11.2 tiled resources are not supported at this time."); - return S_OK; + if(m_pDevice2) + { + AddRef(); + *ppvObject = (ID3D11Device2 *)this; + RDCWARN("Trying to get ID3D11Device2. DX11.2 tiled resources are not supported at this time."); + return S_OK; + } + else + { + return E_NOINTERFACE; + } } else if(riid == __uuidof(ID3D11ShaderTraceFactory)) { diff --git a/renderdoc/driver/d3d11/d3d11_resources.h b/renderdoc/driver/d3d11/d3d11_resources.h index 5f51f6392..80ee07c76 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.h +++ b/renderdoc/driver/d3d11/d3d11_resources.h @@ -156,6 +156,18 @@ public: HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { + // ensure the real object has this interface + void *outObj; + HRESULT hr = m_pWrapped->QueryInterface(riid, &outObj); + + IUnknown *unk = (IUnknown *)outObj; + SAFE_RELEASE(unk); + + if(FAILED(hr)) + { + return hr; + } + if(riid == __uuidof(IDXGIObject)) { *ppvObject = (IDXGIObject *)(IDXGIKeyedMutex *)this; diff --git a/renderdoc/driver/dxgi/dxgi_wrapped.cpp b/renderdoc/driver/dxgi/dxgi_wrapped.cpp index 5425b3fc1..975a4a8ee 100644 --- a/renderdoc/driver/dxgi/dxgi_wrapped.cpp +++ b/renderdoc/driver/dxgi/dxgi_wrapped.cpp @@ -239,6 +239,8 @@ WrappedIDXGISwapChain2::WrappedIDXGISwapChain2(IDXGISwapChain* real, HWND wnd, W real->GetDesc(&desc); #if defined(INCLUDE_DXGI_1_2) + m_pReal1 = NULL; + real->QueryInterface(__uuidof(IDXGISwapChain1), (void **)&m_pReal1); m_pReal2 = NULL; real->QueryInterface(__uuidof(IDXGISwapChain2), (void **)&m_pReal2); #endif @@ -288,6 +290,7 @@ WrappedIDXGISwapChain2::~WrappedIDXGISwapChain2() m_pBackBuffers[i] = NULL; } #if defined(INCLUDE_DXGI_1_2) + SAFE_RELEASE(m_pReal1); SAFE_RELEASE(m_pReal2); #endif SAFE_RELEASE(m_pReal); @@ -579,9 +582,29 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain2::QueryInterface(REFIID riid, vo #if defined(INCLUDE_DXGI_1_2) else if(riid == __uuidof(IDXGISwapChain1)) { - AddRef(); - *ppvObject = (IDXGISwapChain1 *)this; - return S_OK; + if(m_pReal1) + { + AddRef(); + *ppvObject = (IDXGISwapChain1 *)this; + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else if(riid == __uuidof(IDXGISwapChain2)) + { + if(m_pReal2) + { + AddRef(); + *ppvObject = (IDXGISwapChain2 *)this; + return S_OK; + } + else + { + return E_NOINTERFACE; + } } #endif else @@ -612,6 +635,8 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice::QueryInterface( REFIID riid, void HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice1::QueryInterface( REFIID riid, void **ppvObject ) { + HRESULT hr = S_OK; + if(riid == __uuidof(ID3D11Device)) { m_pD3DDevice->AddRef(); @@ -627,19 +652,33 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice1::QueryInterface( REFIID riid, void #if defined(INCLUDE_DXGI_1_2) else if(riid == __uuidof(IDXGIDevice2)) { - m_pReal->QueryInterface(riid, ppvObject); + hr = m_pReal->QueryInterface(riid, ppvObject); - IDXGIDevice2 *real = (IDXGIDevice2 *)(*ppvObject); - *ppvObject = new WrappedIDXGIDevice2(real, m_pD3DDevice); - return S_OK; + if(SUCCEEDED(hr)) + { + IDXGIDevice2 *real = (IDXGIDevice2 *)(*ppvObject); + *ppvObject = new WrappedIDXGIDevice2(real, m_pD3DDevice); + return S_OK; + } + else + { + return E_NOINTERFACE; + } } else if(riid == __uuidof(IDXGIDevice3)) { - m_pReal->QueryInterface(riid, ppvObject); + hr = m_pReal->QueryInterface(riid, ppvObject); - IDXGIDevice3 *real = (IDXGIDevice3 *)(*ppvObject); - *ppvObject = new WrappedIDXGIDevice3(real, m_pD3DDevice); - return S_OK; + if(SUCCEEDED(hr)) + { + IDXGIDevice3 *real = (IDXGIDevice3 *)(*ppvObject); + *ppvObject = new WrappedIDXGIDevice3(real, m_pD3DDevice); + return S_OK; + } + else + { + return E_NOINTERFACE; + } } #endif else @@ -675,11 +714,18 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice2::QueryInterface( REFIID riid, void } else if(riid == __uuidof(IDXGIDevice3)) { - m_pReal->QueryInterface(riid, ppvObject); - - IDXGIDevice3 *real = (IDXGIDevice3 *)(*ppvObject); - *ppvObject = new WrappedIDXGIDevice3(real, m_pD3DDevice); - return S_OK; + HRESULT hr = m_pReal->QueryInterface(riid, ppvObject); + + if(SUCCEEDED(hr)) + { + IDXGIDevice3 *real = (IDXGIDevice3 *)(*ppvObject); + *ppvObject = new WrappedIDXGIDevice3(real, m_pD3DDevice); + return S_OK; + } + else + { + return E_NOINTERFACE; + } } else { diff --git a/renderdoc/driver/dxgi/dxgi_wrapped.h b/renderdoc/driver/dxgi/dxgi_wrapped.h index 64448410a..e0e34516c 100644 --- a/renderdoc/driver/dxgi/dxgi_wrapped.h +++ b/renderdoc/driver/dxgi/dxgi_wrapped.h @@ -116,6 +116,7 @@ class WrappedIDXGISwapChain2 : public SWAPCHAINPARENT, public RefCountDXGIObject { IDXGISwapChain* m_pReal; #if defined(INCLUDE_DXGI_1_2) + IDXGISwapChain1* m_pReal1; IDXGISwapChain2* m_pReal2; #endif WrappedID3D11Device *m_pDevice;