From 3b04aa227b90d0f1f8ddd4ff411eb56b837236eb Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 10 Sep 2020 12:40:29 +0100 Subject: [PATCH] Reduce the memory footprint of D3D12 objects --- renderdoc/driver/d3d12/d3d12_common.h | 27 ++++++- renderdoc/driver/d3d12/d3d12_resources.cpp | 2 - renderdoc/driver/d3d12/d3d12_resources.h | 94 ++++++++-------------- 3 files changed, 57 insertions(+), 66 deletions(-) diff --git a/renderdoc/driver/d3d12/d3d12_common.h b/renderdoc/driver/d3d12/d3d12_common.h index 001b2a03e..17f5417f6 100644 --- a/renderdoc/driver/d3d12/d3d12_common.h +++ b/renderdoc/driver/d3d12/d3d12_common.h @@ -147,22 +147,35 @@ class RefCounter12 { private: unsigned int m_iRefcount; - bool m_SelfDeleting; + unsigned int m_InternalRefcount : 30; + unsigned int resident : 1; + unsigned int m_SelfDeleting : 1; protected: RealType *m_pReal; - void SetSelfDeleting(bool selfDelete) { m_SelfDeleting = selfDelete; } + void SetSelfDeleting(bool selfDelete) { m_SelfDeleting = selfDelete ? 1 : 0; } // used for derived classes that need to soft ref but are handling their // own self-deletion public: RefCounter12(RealType *real, bool selfDelete = true) - : m_pReal(real), m_iRefcount(1), m_SelfDeleting(selfDelete) + : m_pReal(real), + m_iRefcount(1), + m_InternalRefcount(0), + resident(1), + m_SelfDeleting(selfDelete ? 1 : 0) { } virtual ~RefCounter12() {} unsigned int GetRefCount() { return m_iRefcount; } + // some applications wrongly check refcount return values and expect them to + // match D3D's values. When we have some internal refs we need to hide, we + // add them here and they're subtracted from return values + void AddInternalRef() { m_InternalRefcount++; } + void ReleaseInternalRef() { m_InternalRefcount--; } + bool Resident() { return resident != 0; } + void SetResident(bool r) { resident = r ? 1 : 0; } ////////////////////////////// // implement IUnknown HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) @@ -193,6 +206,10 @@ public: device->SoftRef(); else RDCWARN("No device pointer, is a deleted resource being AddRef()d?"); + + if(ret >= m_InternalRefcount) + ret -= m_InternalRefcount; + return ret; } @@ -203,6 +220,10 @@ public: device->SoftRelease(); else RDCWARN("No device pointer, is a deleted resource being Release()d?"); + + if(ret >= m_InternalRefcount) + ret -= m_InternalRefcount; + return ret; } }; diff --git a/renderdoc/driver/d3d12/d3d12_resources.cpp b/renderdoc/driver/d3d12/d3d12_resources.cpp index 29ab6704b..669bfb41d 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.cpp +++ b/renderdoc/driver/d3d12/d3d12_resources.cpp @@ -174,8 +174,6 @@ ID3D12DeviceChild *Unwrap(ID3D12DeviceChild *ptr) WrappedID3D12Resource1::~WrappedID3D12Resource1() { - SAFE_RELEASE(m_pReal1); - // perform an implicit unmap on release if(GetResourceRecord()) { diff --git a/renderdoc/driver/d3d12/d3d12_resources.h b/renderdoc/driver/d3d12/d3d12_resources.h index 05dcce5e6..43782d528 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.h +++ b/renderdoc/driver/d3d12/d3d12_resources.h @@ -68,13 +68,10 @@ class WrappedDeviceChild12 : public RefCounter12, { protected: WrappedID3D12Device *m_pDevice; - ULONG m_InternalRefcount; WrappedDeviceChild12(NestedType *real, WrappedID3D12Device *device) : RefCounter12(real), m_pDevice(device) { - m_InternalRefcount = 0; - m_pDevice->SoftRef(); if(real) @@ -108,31 +105,9 @@ protected: public: typedef NestedType InnerType; - // some applications wrongly check refcount return values and expect them to - // match D3D's values. When we have some internal refs we need to hide, we - // add them here and they're subtracted from return values - void AddInternalRef() { InterlockedIncrement(&m_InternalRefcount); } - void ReleaseInternalRef() { InterlockedDecrement(&m_InternalRefcount); } NestedType *GetReal() { return m_pReal; } - ULONG STDMETHODCALLTYPE AddRef() - { - ULONG ret = RefCounter12::SoftRef(m_pDevice); - - if(ret >= m_InternalRefcount) - ret -= m_InternalRefcount; - - return ret; - } - ULONG STDMETHODCALLTYPE Release() - { - ULONG ret = RefCounter12::SoftRelease(m_pDevice); - - if(ret >= m_InternalRefcount) - ret -= m_InternalRefcount; - - return ret; - } - + ULONG STDMETHODCALLTYPE AddRef() { return RefCounter12::SoftRef(m_pDevice); } + ULONG STDMETHODCALLTYPE Release() { return RefCounter12::SoftRelease(m_pDevice); } HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { if(riid == __uuidof(IUnknown)) @@ -413,8 +388,7 @@ class WrappedID3D12DescriptorHeap : public WrappedDeviceChild12 { - ID3D12Fence1 *m_pReal1 = NULL; - public: ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D12Fence1); @@ -483,13 +453,8 @@ public: WrappedID3D12Fence1(ID3D12Fence *real, WrappedID3D12Device *device) : WrappedDeviceChild12(real, device) { - real->QueryInterface(__uuidof(ID3D12Fence1), (void **)&m_pReal1); - } - virtual ~WrappedID3D12Fence1() - { - SAFE_RELEASE(m_pReal1); - Shutdown(); } + virtual ~WrappedID3D12Fence1() { Shutdown(); } ////////////////////////////// // implement ID3D12Fence @@ -504,7 +469,16 @@ public: // implement ID3D12Fence1 virtual D3D12_FENCE_FLAGS STDMETHODCALLTYPE GetCreationFlags() { - return m_pReal1->GetCreationFlags(); + ID3D12Fence1 *real1 = NULL; + m_pReal->QueryInterface(__uuidof(ID3D12Fence1), (void **)&real1); + + if(!real1) + return D3D12_FENCE_FLAG_NONE; + + D3D12_FENCE_FLAGS ret = real1->GetCreationFlags(); + + SAFE_RELEASE(real1); + return ret; } }; @@ -567,8 +541,6 @@ public: class WrappedID3D12Heap1 : public WrappedDeviceChild12 { - ID3D12Heap1 *m_pReal1 = NULL; - public: ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D12Heap1); @@ -580,14 +552,8 @@ public: WrappedID3D12Heap1(ID3D12Heap *real, WrappedID3D12Device *device) : WrappedDeviceChild12(real, device) { - real->QueryInterface(__uuidof(ID3D12Heap1), (void **)&m_pReal1); } - virtual ~WrappedID3D12Heap1() - { - SAFE_RELEASE(m_pReal1); - Shutdown(); - } - + virtual ~WrappedID3D12Heap1() { Shutdown(); } ////////////////////////////// // implement ID3D12Heap virtual D3D12_HEAP_DESC STDMETHODCALLTYPE GetDesc() { return m_pReal->GetDesc(); } @@ -596,8 +562,16 @@ public: virtual HRESULT STDMETHODCALLTYPE GetProtectedResourceSession(REFIID riid, _COM_Outptr_opt_ void **ppProtectedSession) { + ID3D12Heap1 *real1 = NULL; + m_pReal->QueryInterface(__uuidof(ID3D12Heap1), (void **)&real1); + + if(!real1) + return E_NOINTERFACE; + void *iface = NULL; - HRESULT ret = m_pReal1->GetProtectedResourceSession(riid, &iface); + HRESULT ret = real1->GetProtectedResourceSession(riid, &iface); + + SAFE_RELEASE(real1); if(ret != S_OK) return ret; @@ -880,12 +854,8 @@ public: class WrappedID3D12Resource1 : public WrappedDeviceChild12 { - ID3D12Resource1 *m_pReal1 = NULL; - static GPUAddressRangeTracker m_Addresses; - bool resident; - WriteSerialiser &GetThreadSerialiser(); public: @@ -924,10 +894,6 @@ public: if(IsReplayMode(device->GetState())) device->GetResourceList()[GetResourceID()] = this; - real->QueryInterface(__uuidof(ID3D12Resource1), (void **)&m_pReal1); - - SetResident(true); - // assuming only valid for buffers if(m_pReal->GetDesc().Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) { @@ -943,8 +909,6 @@ public: } virtual ~WrappedID3D12Resource1(); - bool Resident() { return resident; } - void SetResident(bool r) { resident = r; } byte *GetMap(UINT Subresource); byte *GetShadow(UINT Subresource); void AllocShadow(UINT Subresource, size_t size); @@ -1003,8 +967,16 @@ public: virtual HRESULT STDMETHODCALLTYPE GetProtectedResourceSession(REFIID riid, _COM_Outptr_opt_ void **ppProtectedSession) { + ID3D12Resource1 *real1 = NULL; + m_pReal->QueryInterface(__uuidof(ID3D12Resource1), (void **)&real1); + + if(!real1) + return E_NOINTERFACE; + void *iface = NULL; - HRESULT ret = m_pReal1->GetProtectedResourceSession(riid, &iface); + HRESULT ret = real1->GetProtectedResourceSession(riid, &iface); + + SAFE_RELEASE(real1); if(ret != S_OK) return ret;