From c7a4a45d1d9442d7883bfc9e22f9d19fc90d9c86 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 16 Jan 2015 22:18:01 +0000 Subject: [PATCH] Only return interfaces where supported by real object. Refs #119 * Note in some cases we still unconditionally return an object (like ID3D11InfoQueue) just for compatibility's sake if it's pretty ubiquitous and programs might expect it to always be there. This change however will stop us from reporting interfaces that might actually not be HW or OS supported. --- renderdoc/driver/d3d11/d3d11_context.cpp | 30 +++++-- renderdoc/driver/d3d11/d3d11_device.cpp | 100 +++++++++++++++++------ renderdoc/driver/d3d11/d3d11_resources.h | 12 +++ renderdoc/driver/dxgi/dxgi_wrapped.cpp | 78 ++++++++++++++---- renderdoc/driver/dxgi/dxgi_wrapped.h | 1 + 5 files changed, 172 insertions(+), 49 deletions(-) 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;