From cc108d6488bd36f76f635a25f8b3cfd78766d7fd Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 11 Jun 2015 21:03:12 +0200 Subject: [PATCH] Track and don't show pipeline refcounts to the user * Some naughty applications assume refcount will hit 0 if they release all references but keep the object bound to the pipeline, so for compatibility's sake we preserve this behaviour --- renderdoc/driver/d3d11/d3d11_renderstate.cpp | 12 ++++++-- renderdoc/driver/d3d11/d3d11_renderstate.h | 4 +-- renderdoc/driver/d3d11/d3d11_resources.h | 31 +++++++++++++++----- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/renderdoc/driver/d3d11/d3d11_renderstate.cpp b/renderdoc/driver/d3d11/d3d11_renderstate.cpp index f48c61728..610661753 100644 --- a/renderdoc/driver/d3d11/d3d11_renderstate.cpp +++ b/renderdoc/driver/d3d11/d3d11_renderstate.cpp @@ -849,7 +849,7 @@ void D3D11RenderState::ApplyState(WrappedID3D11DeviceContext *context) OM.UAVStartSlot, D3D11_PS_CS_UAV_REGISTER_COUNT-OM.UAVStartSlot, OM.UAVs, UAV_keepcounts); } -void D3D11RenderState::TakeRef(IUnknown *p) +void D3D11RenderState::TakeRef(ID3D11DeviceChild *p) { if(p) { @@ -863,11 +863,16 @@ void D3D11RenderState::TakeRef(IUnknown *p) m_pDevice->InternalRef(); m_pDevice->InternalRef(); + + // we can use any specialisation of device child here, as all that is templated + // is the nested pointer type. Saves having another class in the inheritance + // heirarchy :( + ((WrappedDeviceChild*)p)->PipelineAddRef(); } } } -void D3D11RenderState::ReleaseRef(IUnknown *p) +void D3D11RenderState::ReleaseRef(ID3D11DeviceChild *p) { if(p) { @@ -881,6 +886,9 @@ void D3D11RenderState::ReleaseRef(IUnknown *p) m_pDevice->InternalRelease(); m_pDevice->InternalRelease(); + + // see above + ((WrappedDeviceChild*)p)->PipelineRelease(); } } } diff --git a/renderdoc/driver/d3d11/d3d11_renderstate.h b/renderdoc/driver/d3d11/d3d11_renderstate.h index e9d74b4d8..ccc6baf9f 100644 --- a/renderdoc/driver/d3d11/d3d11_renderstate.h +++ b/renderdoc/driver/d3d11/d3d11_renderstate.h @@ -255,8 +255,8 @@ struct D3D11RenderState ///////////////////////////////////////////////////////////////////////// // Utility functions to swap resources around, removing and adding refs - void TakeRef(IUnknown *p); - void ReleaseRef(IUnknown *p); + void TakeRef(ID3D11DeviceChild *p); + void ReleaseRef(ID3D11DeviceChild *p); template void ChangeRefRead(T **stateArray, T *const*newArray, size_t offset, size_t num) diff --git a/renderdoc/driver/d3d11/d3d11_resources.h b/renderdoc/driver/d3d11/d3d11_resources.h index 9a5cffc6e..4464ab9ce 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.h +++ b/renderdoc/driver/d3d11/d3d11_resources.h @@ -479,11 +479,13 @@ class WrappedDeviceChild : public RefCounter, public NestedType, public TrackedR protected: WrappedID3D11Device* m_pDevice; NestedType* m_pReal; + unsigned int m_PipelineRefs; WrappedDeviceChild(NestedType* real, WrappedID3D11Device* device) : RefCounter(real), m_pDevice(device), - m_pReal(real) + m_pReal(real), + m_PipelineRefs(0) { m_pDevice->SoftRef(); @@ -515,9 +517,23 @@ public: NestedType* GetReal() { return m_pReal; } - ULONG STDMETHODCALLTYPE AddRef() { return RefCounter::SoftRef(m_pDevice); } - ULONG STDMETHODCALLTYPE Release() { return RefCounter::SoftRelease(m_pDevice); } + ULONG STDMETHODCALLTYPE AddRef() { return RefCounter::SoftRef(m_pDevice) - m_PipelineRefs; } + ULONG STDMETHODCALLTYPE Release() + { + unsigned int piperefs = m_PipelineRefs; + return RefCounter::SoftRelease(m_pDevice) - piperefs; + } + void PipelineAddRef() + { + InterlockedIncrement(&m_PipelineRefs); + } + + void PipelineRelease() + { + InterlockedDecrement(&m_PipelineRefs); + } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { if(riid == __uuidof(NestedType)) @@ -684,12 +700,13 @@ public: ULONG STDMETHODCALLTYPE AddRef() { - return RefCounter::SoftRef(m_pDevice); + return RefCounter::SoftRef(m_pDevice) - m_PipelineRefs; } ULONG STDMETHODCALLTYPE Release() { unsigned int extRefCount = RefCounter::Release(); + unsigned int pipeRefs = m_PipelineRefs; WrappedID3D11Device *dev = m_pDevice; @@ -698,7 +715,7 @@ public: RefCounter::ReleaseDeviceSoftref(dev); - return extRefCount; + return extRefCount - pipeRefs; } HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) @@ -759,7 +776,7 @@ public: static map m_BufferList; static const int AllocPoolCount = 128*1024; - static const int AllocPoolMaxByteSize = 11*1024*1024; + static const int AllocPoolMaxByteSize = 13*1024*1024; ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Buffer, AllocPoolCount, AllocPoolMaxByteSize); WrappedID3D11Buffer(ID3D11Buffer* real, uint32_t byteLength, WrappedID3D11Device* device) @@ -1045,7 +1062,7 @@ class WrappedID3D11ShaderResourceView : public WrappedView