mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-12 13:00:32 +00:00
Add proper refcounting to wrapped D3D9 device
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "d3d9_common.h"
|
||||
#include "d3d9_device.h"
|
||||
|
||||
unsigned int RefCounter9::SoftRef(WrappedD3DDevice9 *device)
|
||||
{
|
||||
unsigned int ret = AddRef();
|
||||
if(device)
|
||||
device->SoftRef();
|
||||
else
|
||||
RDCWARN("No device pointer, is a deleted resource being AddRef()d?");
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned int RefCounter9::SoftRelease(WrappedD3DDevice9 *device)
|
||||
{
|
||||
unsigned int ret = Release();
|
||||
if(device)
|
||||
device->SoftRelease();
|
||||
else
|
||||
RDCWARN("No device pointer, is a deleted resource being Release()d?");
|
||||
return ret;
|
||||
}
|
||||
|
||||
void RefCounter9::AddDeviceSoftref(WrappedD3DDevice9 *device)
|
||||
{
|
||||
if(device)
|
||||
device->SoftRef();
|
||||
}
|
||||
|
||||
void RefCounter9::ReleaseDeviceSoftref(WrappedD3DDevice9 *device)
|
||||
{
|
||||
if(device)
|
||||
device->SoftRelease();
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "api/replay/renderdoc_replay.h"
|
||||
#include "core/core.h"
|
||||
#include "driver/dx/official/d3d9.h"
|
||||
|
||||
class WrappedD3DDevice9;
|
||||
|
||||
class RefCounter9
|
||||
{
|
||||
private:
|
||||
IUnknown *m_pReal;
|
||||
unsigned int m_iRefcount;
|
||||
bool m_SelfDeleting;
|
||||
|
||||
protected:
|
||||
void SetSelfDeleting(bool selfDelete) { m_SelfDeleting = selfDelete; }
|
||||
// used for derived classes that need to soft ref but are handling their
|
||||
// own self-deletion
|
||||
static void AddDeviceSoftref(WrappedD3DDevice9 *device);
|
||||
static void ReleaseDeviceSoftref(WrappedD3DDevice9 *device);
|
||||
|
||||
public:
|
||||
RefCounter9(IUnknown *real, bool selfDelete = true)
|
||||
: m_pReal(real), m_iRefcount(1), m_SelfDeleting(selfDelete)
|
||||
{
|
||||
}
|
||||
virtual ~RefCounter9() {}
|
||||
unsigned int GetRefCount() { return m_iRefcount; }
|
||||
//////////////////////////////
|
||||
// implement IUnknown
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||
/* [in] */ REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
__RPC__deref_out void **ppvObject)
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef()
|
||||
{
|
||||
InterlockedIncrement(&m_iRefcount);
|
||||
return m_iRefcount;
|
||||
}
|
||||
ULONG STDMETHODCALLTYPE Release()
|
||||
{
|
||||
unsigned int ret = InterlockedDecrement(&m_iRefcount);
|
||||
if(ret == 0 && m_SelfDeleting)
|
||||
delete this;
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned int SoftRef(WrappedD3DDevice9 *device);
|
||||
unsigned int SoftRelease(WrappedD3DDevice9 *device);
|
||||
};
|
||||
@@ -186,8 +186,8 @@ void D3D9DebugManager::RenderTextInternal(float x, float y, const char *text)
|
||||
res |= m_WrappedDevice->SetTransform(D3DTS_VIEW, &identity);
|
||||
|
||||
// enable fixed function pipeline
|
||||
res |= m_WrappedDevice->SetVertexShader(nullptr);
|
||||
res |= m_WrappedDevice->SetPixelShader(nullptr);
|
||||
res |= m_WrappedDevice->SetVertexShader(NULL);
|
||||
res |= m_WrappedDevice->SetPixelShader(NULL);
|
||||
|
||||
// default render states
|
||||
res |= m_WrappedDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include "common/common.h"
|
||||
#include "driver/dx/official/d3d9.h"
|
||||
#include "stb/stb_truetype.h"
|
||||
#include "d3d9_common.h"
|
||||
#include "d3d9_device.h"
|
||||
|
||||
class D3D9DebugManager
|
||||
|
||||
@@ -24,18 +24,67 @@
|
||||
|
||||
#include "d3d9_device.h"
|
||||
#include "core/core.h"
|
||||
#include "serialise/serialiser.h"
|
||||
#include "d3d9_debug.h"
|
||||
#include "windows.h" // TODO investigate how else this can be solved
|
||||
|
||||
WrappedD3DDevice9::WrappedD3DDevice9(IDirect3DDevice9 *device)
|
||||
: m_device(device), m_DebugManager(nullptr)
|
||||
: m_RefCounter(device, false),
|
||||
m_SoftRefCounter(NULL, false),
|
||||
m_device(device),
|
||||
m_DebugManager(NULL)
|
||||
{
|
||||
m_FrameCounter = 0;
|
||||
|
||||
// refcounters implicitly construct with one reference, but we don't start with any soft
|
||||
// references.
|
||||
m_SoftRefCounter.Release();
|
||||
m_InternalRefcount = 0;
|
||||
m_Alive = true;
|
||||
}
|
||||
|
||||
void WrappedD3DDevice9::CheckForDeath()
|
||||
{
|
||||
if(!m_Alive)
|
||||
return;
|
||||
|
||||
if(m_RefCounter.GetRefCount() == 0)
|
||||
{
|
||||
RDCASSERT(m_SoftRefCounter.GetRefCount() >= m_InternalRefcount);
|
||||
|
||||
if(m_SoftRefCounter.GetRefCount() <= m_InternalRefcount)
|
||||
{
|
||||
m_Alive = false;
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WrappedD3DDevice9::~WrappedD3DDevice9()
|
||||
{
|
||||
SAFE_DELETE(m_DebugManager);
|
||||
|
||||
SAFE_RELEASE(m_device);
|
||||
}
|
||||
|
||||
HRESULT WrappedD3DDevice9::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
// RenderDoc UUID {A7AA6116-9C8D-4BBA-9083-B4D816B71B78}
|
||||
static const GUID IRenderDoc_uuid = {
|
||||
0xa7aa6116, 0x9c8d, 0x4bba, {0x90, 0x83, 0xb4, 0xd8, 0x16, 0xb7, 0x1b, 0x78}};
|
||||
|
||||
if(riid == IRenderDoc_uuid)
|
||||
{
|
||||
AddRef();
|
||||
*ppvObject = (IUnknown *)this;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
string guid = ToStr::Get(riid);
|
||||
RDCWARN("Querying IDirect3DDevice9 for interface: %s", guid.c_str());
|
||||
}
|
||||
|
||||
return m_device->QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
void WrappedD3DDevice9::LazyInit()
|
||||
@@ -43,29 +92,6 @@ void WrappedD3DDevice9::LazyInit()
|
||||
m_DebugManager = new D3D9DebugManager(this);
|
||||
}
|
||||
|
||||
HRESULT __stdcall WrappedD3DDevice9::QueryInterface(REFIID riid, void **ppvObj)
|
||||
{
|
||||
return m_device->QueryInterface(riid, ppvObj);
|
||||
}
|
||||
|
||||
ULONG __stdcall WrappedD3DDevice9::AddRef()
|
||||
{
|
||||
ULONG refCount;
|
||||
refCount = m_device->AddRef();
|
||||
return refCount;
|
||||
}
|
||||
|
||||
ULONG __stdcall WrappedD3DDevice9::Release()
|
||||
{
|
||||
ULONG refCount;
|
||||
refCount = m_device->Release();
|
||||
if(refCount == 0)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
return refCount;
|
||||
}
|
||||
|
||||
HRESULT __stdcall WrappedD3DDevice9::TestCooperativeLevel()
|
||||
{
|
||||
return m_device->TestCooperativeLevel();
|
||||
|
||||
@@ -23,9 +23,8 @@
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include "common/common.h"
|
||||
#include "common/timing.h"
|
||||
#include "driver/dx/official/d3d9.h"
|
||||
#include "d3d9_common.h"
|
||||
|
||||
class D3D9DebugManager;
|
||||
|
||||
@@ -37,11 +36,25 @@ public:
|
||||
|
||||
void LazyInit();
|
||||
|
||||
void InternalRef() { InterlockedIncrement(&m_InternalRefcount); }
|
||||
void InternalRelease() { InterlockedDecrement(&m_InternalRefcount); }
|
||||
void SoftRef() { m_SoftRefCounter.AddRef(); }
|
||||
void SoftRelease()
|
||||
{
|
||||
m_SoftRefCounter.Release();
|
||||
CheckForDeath();
|
||||
}
|
||||
|
||||
D3D9DebugManager *GetDebugManager() { return m_DebugManager; }
|
||||
/*** IUnknown methods ***/
|
||||
virtual HRESULT __stdcall QueryInterface(REFIID riid, void **ppvObj);
|
||||
virtual ULONG __stdcall AddRef();
|
||||
virtual ULONG __stdcall Release();
|
||||
ULONG STDMETHODCALLTYPE AddRef() { return m_RefCounter.AddRef(); }
|
||||
ULONG STDMETHODCALLTYPE Release()
|
||||
{
|
||||
unsigned int ret = m_RefCounter.Release();
|
||||
CheckForDeath();
|
||||
return ret;
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
|
||||
/*** IDirect3DDevice9 methods ***/
|
||||
virtual HRESULT __stdcall TestCooperativeLevel();
|
||||
@@ -229,9 +242,16 @@ public:
|
||||
virtual HRESULT __stdcall CreateQuery(D3DQUERYTYPE Type, IDirect3DQuery9 **ppQuery);
|
||||
|
||||
private:
|
||||
void CheckForDeath();
|
||||
|
||||
IDirect3DDevice9 *m_device;
|
||||
D3D9DebugManager *m_DebugManager;
|
||||
|
||||
unsigned int m_InternalRefcount;
|
||||
RefCounter9 m_RefCounter;
|
||||
RefCounter9 m_SoftRefCounter;
|
||||
bool m_Alive;
|
||||
|
||||
uint32_t m_FrameCounter;
|
||||
};
|
||||
|
||||
|
||||
@@ -184,6 +184,7 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="d3d9_common.cpp" />
|
||||
<ClCompile Include="d3d9_debug.cpp" />
|
||||
<ClCompile Include="d3d9_device.cpp" />
|
||||
<ClCompile Include="d3d9_hooks.cpp" />
|
||||
@@ -194,6 +195,7 @@
|
||||
<ClInclude Include="..\dx\official\d3d9types.h" />
|
||||
<ClInclude Include="..\dx\official\d3dcommon.h" />
|
||||
<ClInclude Include="..\dx\official\d3dcompiler.h" />
|
||||
<ClInclude Include="d3d9_common.h" />
|
||||
<ClInclude Include="d3d9_debug.h" />
|
||||
<ClInclude Include="d3d9_device.h" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
<ClCompile Include="d3d9_device.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="d3d9_common.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\dx\official\d3d9.h">
|
||||
@@ -47,5 +50,8 @@
|
||||
<ClInclude Include="d3d9_device.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="d3d9_common.h">
|
||||
<Filter>Common</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user