From 4dec05cb2b6bc2e184da6cb48d80a396a1b2ef31 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 24 Feb 2017 14:23:31 +0000 Subject: [PATCH] Fake backbuffer refcount on D3D12 to match D3D11 behaviour. Refs #527 --- renderdoc/driver/d3d12/d3d12_device.cpp | 19 ++++++++++++++- renderdoc/driver/d3d12/d3d12_device.h | 2 +- renderdoc/driver/d3d12/d3d12_resources.h | 31 +++++++++++++++++++++--- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index 670a94c9c..7ef811432 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -648,7 +648,13 @@ void WrappedID3D12Device::ReleaseSwapchainResources(WrappedIDXGISwapChain4 *swap for(int i = 0; i < swap->GetNumBackbuffers(); i++) { - WrappedID3D12Resource *wrapped = (WrappedID3D12Resource *)swap->GetBackbuffers()[i]; + ID3D12Resource *res = (ID3D12Resource *)swap->GetBackbuffers()[i]; + + if(!res) + continue; + + WrappedID3D12Resource *wrapped = (WrappedID3D12Resource *)res; + wrapped->ReleaseInternalRef(); SAFE_RELEASE(wrapped); } @@ -671,6 +677,17 @@ void WrappedID3D12Device::ReleaseSwapchainResources(WrappedIDXGISwapChain4 *swap } } +void WrappedID3D12Device::NewSwapchainBuffer(IUnknown *backbuffer) +{ + ID3D12Resource *pRes = (ID3D12Resource *)backbuffer; + + if(pRes) + { + WrappedID3D12Resource *wrapped = (WrappedID3D12Resource *)pRes; + wrapped->AddInternalRef(); + } +} + bool WrappedID3D12Device::Serialise_WrapSwapchainBuffer(Serialiser *localSerialiser, WrappedIDXGISwapChain4 *swap, DXGI_SWAP_CHAIN_DESC *swapDesc, UINT buffer, diff --git a/renderdoc/driver/d3d12/d3d12_device.h b/renderdoc/driver/d3d12/d3d12_device.h index 92e3f0856..264b665c3 100644 --- a/renderdoc/driver/d3d12/d3d12_device.h +++ b/renderdoc/driver/d3d12/d3d12_device.h @@ -472,7 +472,7 @@ public: UINT buffer, IUnknown *realSurface); HRESULT Present(WrappedIDXGISwapChain4 *swap, UINT SyncInterval, UINT Flags); - void NewSwapchainBuffer(IUnknown *backbuffer) {} + void NewSwapchainBuffer(IUnknown *backbuffer); void ReleaseSwapchainResources(WrappedIDXGISwapChain4 *swap, UINT QueueCount, IUnknown *const *ppPresentQueue, IUnknown **unwrappedQueues); diff --git a/renderdoc/driver/d3d12/d3d12_resources.h b/renderdoc/driver/d3d12/d3d12_resources.h index 253a521b8..81198e427 100644 --- a/renderdoc/driver/d3d12/d3d12_resources.h +++ b/renderdoc/driver/d3d12/d3d12_resources.h @@ -56,10 +56,13 @@ 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) @@ -93,9 +96,31 @@ 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() { return RefCounter12::SoftRef(m_pDevice); } - ULONG STDMETHODCALLTYPE Release() { return RefCounter12::SoftRelease(m_pDevice); } + 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; + } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { if(riid == __uuidof(IUnknown)) @@ -722,7 +747,7 @@ class WrappedID3D12Resource : public WrappedDeviceChild12 public: static const int AllocPoolCount = 16384; - static const int AllocMaxByteSize = 1024 * 1024; + static const int AllocMaxByteSize = 1536 * 1024; ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D12Resource, AllocPoolCount, AllocMaxByteSize, false); static std::map *m_List;