diff --git a/renderdoc/driver/d3d11/d3d11_context.cpp b/renderdoc/driver/d3d11/d3d11_context.cpp index 7d833f76a..e25df27ef 100644 --- a/renderdoc/driver/d3d11/d3d11_context.cpp +++ b/renderdoc/driver/d3d11/d3d11_context.cpp @@ -102,11 +102,13 @@ WrappedID3D11DeviceContext::WrappedID3D11DeviceContext(WrappedID3D11Device *real m_pRealContext1 = NULL; m_pRealContext2 = NULL; m_pRealContext3 = NULL; + m_pRealContext4 = NULL; if(m_pRealContext) { m_pRealContext->QueryInterface(__uuidof(ID3D11DeviceContext1), (void **)&m_pRealContext1); m_pRealContext->QueryInterface(__uuidof(ID3D11DeviceContext2), (void **)&m_pRealContext2); m_pRealContext->QueryInterface(__uuidof(ID3D11DeviceContext3), (void **)&m_pRealContext3); + m_pRealContext->QueryInterface(__uuidof(ID3D11DeviceContext4), (void **)&m_pRealContext4); } m_NeedUpdateSubWorkaround = false; @@ -205,6 +207,7 @@ WrappedID3D11DeviceContext::~WrappedID3D11DeviceContext() SAFE_RELEASE(m_pRealContext1); SAFE_RELEASE(m_pRealContext2); SAFE_RELEASE(m_pRealContext3); + SAFE_RELEASE(m_pRealContext4); SAFE_DELETE(m_DeferredSavedState); @@ -1373,6 +1376,19 @@ HRESULT STDMETHODCALLTYPE WrappedID3D11DeviceContext::QueryInterface(REFIID riid return E_NOINTERFACE; } } + else if(riid == __uuidof(ID3D11DeviceContext4)) + { + if(m_pRealContext4) + { + *ppvObject = (ID3D11DeviceContext4 *)this; + AddRef(); + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } else if(riid == __uuidof(ID3D11Multithread)) { RDCWARN("ID3D11Multithread is not supported"); diff --git a/renderdoc/driver/d3d11/d3d11_context.h b/renderdoc/driver/d3d11/d3d11_context.h index ec2fb26c1..afda3bbe4 100644 --- a/renderdoc/driver/d3d11/d3d11_context.h +++ b/renderdoc/driver/d3d11/d3d11_context.h @@ -98,7 +98,7 @@ enum CaptureFailReason CaptureFailed_UncappedCmdlist, }; -class WrappedID3D11DeviceContext : public RefCounter, public ID3D11DeviceContext3 +class WrappedID3D11DeviceContext : public RefCounter, public ID3D11DeviceContext4 { private: friend class WrappedID3D11DeviceContext; @@ -145,6 +145,7 @@ private: ID3D11DeviceContext2 *m_pRealContext2; ID3D11DeviceContext3 *m_pRealContext3; + ID3D11DeviceContext4 *m_pRealContext4; bool m_NeedUpdateSubWorkaround; @@ -888,4 +889,11 @@ public: virtual void STDMETHODCALLTYPE SetHardwareProtectionState(BOOL HwProtectionEnable); virtual void STDMETHODCALLTYPE GetHardwareProtectionState(BOOL *pHwProtectionEnable); + + ////////////////////////////// + // implement ID3D11DeviceContext4 + + virtual HRESULT STDMETHODCALLTYPE Signal(ID3D11Fence *pFence, UINT64 Value); + + virtual HRESULT STDMETHODCALLTYPE Wait(ID3D11Fence *pFence, UINT64 Value); }; diff --git a/renderdoc/driver/d3d11/d3d11_context3_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context3_wrap.cpp index ecabc8728..b804d017c 100644 --- a/renderdoc/driver/d3d11/d3d11_context3_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context3_wrap.cpp @@ -23,6 +23,7 @@ ******************************************************************************/ #include "d3d11_context.h" +#include "d3d11_resources.h" ///////////////////////////////// // implement ID3D11DeviceContext3 @@ -49,4 +50,23 @@ void WrappedID3D11DeviceContext::GetHardwareProtectionState(BOOL *pHwProtectionE return; m_pRealContext3->GetHardwareProtectionState(pHwProtectionEnable); +} + +///////////////////////////////// +// implement ID3D11DeviceContext4 + +HRESULT WrappedID3D11DeviceContext::Signal(ID3D11Fence *pFence, UINT64 Value) +{ + if(m_pRealContext4 == NULL) + return E_NOINTERFACE; + + return m_pRealContext4->Signal(UNWRAP(WrappedID3D11Fence, pFence), Value); +} + +HRESULT WrappedID3D11DeviceContext::Wait(ID3D11Fence *pFence, UINT64 Value) +{ + if(m_pRealContext4 == NULL) + return E_NOINTERFACE; + + return m_pRealContext4->Wait(UNWRAP(WrappedID3D11Fence, pFence), Value); } \ No newline at end of file diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index bd96168f4..5c8d4bb73 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -79,12 +79,14 @@ WrappedID3D11Device::WrappedID3D11Device(ID3D11Device *realDevice, D3D11InitPara m_pDevice2 = NULL; m_pDevice3 = NULL; m_pDevice4 = NULL; + m_pDevice5 = NULL; if(m_pDevice) { m_pDevice->QueryInterface(__uuidof(ID3D11Device1), (void **)&m_pDevice1); m_pDevice->QueryInterface(__uuidof(ID3D11Device2), (void **)&m_pDevice2); m_pDevice->QueryInterface(__uuidof(ID3D11Device3), (void **)&m_pDevice3); m_pDevice->QueryInterface(__uuidof(ID3D11Device4), (void **)&m_pDevice4); + m_pDevice->QueryInterface(__uuidof(ID3D11Device5), (void **)&m_pDevice5); } // refcounters implicitly construct with one reference, but we don't start with any soft @@ -249,6 +251,7 @@ WrappedID3D11Device::~WrappedID3D11Device() SAFE_RELEASE(m_pDevice2); SAFE_RELEASE(m_pDevice3); SAFE_RELEASE(m_pDevice4); + SAFE_RELEASE(m_pDevice5); SAFE_RELEASE(m_RealAnnotations); @@ -552,6 +555,19 @@ HRESULT WrappedID3D11Device::QueryInterface(REFIID riid, void **ppvObject) return E_NOINTERFACE; } } + else if(riid == __uuidof(ID3D11Device5)) + { + if(m_pDevice5) + { + AddRef(); + *ppvObject = (ID3D11Device5 *)this; + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } else if(riid == __uuidof(ID3D10Multithread)) { RDCWARN( diff --git a/renderdoc/driver/d3d11/d3d11_device.h b/renderdoc/driver/d3d11/d3d11_device.h index 9750ca233..063054dab 100644 --- a/renderdoc/driver/d3d11/d3d11_device.h +++ b/renderdoc/driver/d3d11/d3d11_device.h @@ -304,7 +304,7 @@ struct DummyID3D11Debug : public ID3D11Debug class WrappedID3D11ClassLinkage; enum CaptureFailReason; -class WrappedID3D11Device : public IFrameCapturer, public ID3DDevice, public ID3D11Device4 +class WrappedID3D11Device : public IFrameCapturer, public ID3DDevice, public ID3D11Device5 { private: enum @@ -348,6 +348,7 @@ private: ID3D11Device2 *m_pDevice2; ID3D11Device3 *m_pDevice3; ID3D11Device4 *m_pDevice4; + ID3D11Device5 *m_pDevice5; ID3D11InfoQueue *m_pInfoQueue; WrappedID3D11DeviceContext *m_pImmediateContext; @@ -876,4 +877,12 @@ public: virtual HRESULT STDMETHODCALLTYPE RegisterDeviceRemovedEvent(HANDLE hEvent, DWORD *pdwCookie); virtual void STDMETHODCALLTYPE UnregisterDeviceRemoved(DWORD dwCookie); + + ////////////////////////////// + // implement ID3D11Device5 + + virtual HRESULT STDMETHODCALLTYPE CreateFence(UINT64 InitialValue, D3D11_FENCE_FLAG Flags, + REFIID riid, void **ppFence); + + virtual HRESULT STDMETHODCALLTYPE OpenSharedFence(HANDLE hFence, REFIID riid, void **ppFence); }; \ No newline at end of file diff --git a/renderdoc/driver/d3d11/d3d11_device3_wrap.cpp b/renderdoc/driver/d3d11/d3d11_device3_wrap.cpp index b597f8194..cab33eadf 100644 --- a/renderdoc/driver/d3d11/d3d11_device3_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_device3_wrap.cpp @@ -998,6 +998,64 @@ void WrappedID3D11Device::UnregisterDeviceRemoved(DWORD dwCookie) return m_pDevice4->UnregisterDeviceRemoved(dwCookie); } +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// ID3D11Device5 interface + +HRESULT WrappedID3D11Device::CreateFence(UINT64 InitialValue, D3D11_FENCE_FLAG Flags, REFIID riid, + void **ppFence) +{ + if(m_pDevice5 == NULL) + return E_NOINTERFACE; + + if(ppFence == NULL) + return E_INVALIDARG; + + if(riid != __uuidof(ID3D11Fence)) + { + RDCERR("Unsupported UUID '%s' in WrappedID3D11Device::CreateFence", ToStr(riid).c_str()); + return E_NOINTERFACE; + } + + ID3D11Fence *ret = NULL; + HRESULT hr = m_pDevice5->CreateFence(InitialValue, Flags, riid, (void **)&ret); + + if(FAILED(hr) || ret == NULL) + return hr; + + WrappedID3D11Fence *wrapped = new WrappedID3D11Fence(ret, this); + + *ppFence = (void *)wrapped; + + return S_OK; +} + +HRESULT WrappedID3D11Device::OpenSharedFence(HANDLE hFence, REFIID riid, void **ppFence) +{ + if(m_pDevice5 == NULL) + return E_NOINTERFACE; + + if(ppFence == NULL) + return E_INVALIDARG; + + if(riid != __uuidof(ID3D11Fence)) + { + RDCERR("Unsupported UUID '%s' in WrappedID3D11Device::OpenSharedFence", ToStr(riid).c_str()); + return E_NOINTERFACE; + } + + ID3D11Fence *ret = NULL; + HRESULT hr = m_pDevice5->OpenSharedFence(hFence, riid, (void **)&ret); + + if(FAILED(hr) || ret == NULL) + return hr; + + WrappedID3D11Fence *wrapped = new WrappedID3D11Fence(ret, this); + + *ppFence = (void *)wrapped; + + return S_OK; +} + #undef IMPLEMENT_FUNCTION_SERIALISED #define IMPLEMENT_FUNCTION_SERIALISED(ret, func, ...) \ template bool WrappedID3D11Device::CONCAT(Serialise_, func(ReadSerialiser &ser, __VA_ARGS__)); \ diff --git a/renderdoc/driver/d3d11/d3d11_resources.cpp b/renderdoc/driver/d3d11/d3d11_resources.cpp index 862b0f584..6c0ce0a15 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.cpp +++ b/renderdoc/driver/d3d11/d3d11_resources.cpp @@ -56,6 +56,7 @@ WRAPPED_POOL_INST(WrappedID3D11Predicate); WRAPPED_POOL_INST(WrappedID3D11ClassInstance); WRAPPED_POOL_INST(WrappedID3D11ClassLinkage); WRAPPED_POOL_INST(WrappedID3DDeviceContextState); +WRAPPED_POOL_INST(WrappedID3D11Fence); map WrappedTexture::m_TextureList; diff --git a/renderdoc/driver/d3d11/d3d11_resources.h b/renderdoc/driver/d3d11/d3d11_resources.h index f621d9d50..1dc8736fe 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.h +++ b/renderdoc/driver/d3d11/d3d11_resources.h @@ -1321,6 +1321,37 @@ public: virtual ~WrappedID3DDeviceContextState(); }; +class WrappedID3D11Fence : public WrappedDeviceChild11 +{ +public: + ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Fence); + + WrappedID3D11Fence(ID3D11Fence *real, WrappedID3D11Device *device) + : WrappedDeviceChild11(real, device) + { + } + virtual ~WrappedID3D11Fence() { Shutdown(); } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) + { + return WrappedDeviceChild11::QueryInterface(riid, ppvObject); + } + + ////////////////////////////// + // implement ID3D11Fence + virtual HRESULT STDMETHODCALLTYPE CreateSharedHandle(const SECURITY_ATTRIBUTES *pAttributes, + DWORD dwAccess, LPCWSTR lpName, + HANDLE *pHandle) + { + return m_pReal->CreateSharedHandle(pAttributes, dwAccess, lpName, pHandle); + } + + virtual UINT64 STDMETHODCALLTYPE GetCompletedValue() { return m_pReal->GetCompletedValue(); } + virtual HRESULT STDMETHODCALLTYPE SetEventOnCompletion(UINT64 Value, HANDLE hEvent) + { + return m_pReal->SetEventOnCompletion(Value, hEvent); + } +}; + #define GET_RANGE(wrapped, unwrapped) \ template <> \ inline const ResourceRange &GetResourceRange(unwrapped *v) \ @@ -1413,6 +1444,7 @@ GET_RES_ID(WrappedID3D11ClassInstance); GET_RES_ID(WrappedID3D11ClassLinkage); GET_RES_ID(WrappedID3DDeviceContextState); GET_RES_ID(WrappedID3D11CommandList); +GET_RES_ID(WrappedID3D11Fence); // generic version that checks all the wrapped pools. We can use this for resource since it checks // buffer and textures first, and also for purely virtual interfaces like asynchronous even though