Garbage collect D3D state objects before creation

* If we only garbage collect after a successful create, applications which
  deliberately leak state objects and only free them when they see a failed
  create will not have a change to garbage collect.
This commit is contained in:
baldurk committed 2023-09-12 21:53:23 +01:00
1 parent 1bfe6d1492
commit 02272f98ac
5 files changed
+17 -15

No files matched your search

+2
View File
@@ -2715,6 +2715,8 @@ HRESULT WrappedID3D11Device::Present(IDXGISwapper *swapper, UINT SyncInterval, U
void WrappedID3D11Device::CachedObjectsGarbageCollect()
{
SCOPED_LOCK(m_D3DLock);
// 4000 is a fairly arbitrary number, chosen to make sure this garbage
// collection kicks in as rarely as possible (4000 is a *lot* of unique
// state objects to have), while still meaning that we'll never
+1 -1
View File
@@ -592,7 +592,7 @@ private:
// rarely kick in - only in the case where a lot of unique state objects are
// created then released and never re-used.
//
// Must be called while m_D3DLock is held.
// Internally locks m_D3DLock
void CachedObjectsGarbageCollect();
std::set<WrappedID3D11DeviceContext *> m_DeferredContexts;
@@ -132,6 +132,8 @@ HRESULT WrappedID3D11Device::CreateBlendState1(const D3D11_BLEND_DESC1 *pBlendSt
if(ppBlendState == NULL)
return m_pDevice1->CreateBlendState1(pBlendStateDesc, NULL);
CachedObjectsGarbageCollect();
ID3D11BlendState1 *real = NULL;
HRESULT ret = m_pDevice1->CreateBlendState1(pBlendStateDesc, &real);
@@ -154,8 +156,6 @@ HRESULT WrappedID3D11Device::CreateBlendState1(const D3D11_BLEND_DESC1 *pBlendSt
ID3D11BlendState1 *wrapped = new WrappedID3D11BlendState1(real, this);
CachedObjectsGarbageCollect();
{
RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end());
IntAddRef(wrapped);
@@ -250,6 +250,8 @@ HRESULT WrappedID3D11Device::CreateRasterizerState1(const D3D11_RASTERIZER_DESC1
if(ppRasterizerState == NULL)
return m_pDevice1->CreateRasterizerState1(pRasterizerDesc, NULL);
CachedObjectsGarbageCollect();
ID3D11RasterizerState1 *real = NULL;
HRESULT ret = m_pDevice1->CreateRasterizerState1(pRasterizerDesc, &real);
@@ -272,8 +274,6 @@ HRESULT WrappedID3D11Device::CreateRasterizerState1(const D3D11_RASTERIZER_DESC1
ID3D11RasterizerState1 *wrapped = new WrappedID3D11RasterizerState2(real, this);
CachedObjectsGarbageCollect();
{
RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end());
IntAddRef(wrapped);
@@ -783,6 +783,8 @@ HRESULT WrappedID3D11Device::CreateRasterizerState2(const D3D11_RASTERIZER_DESC2
if(ppRasterizerState == NULL)
return m_pDevice3->CreateRasterizerState2(pRasterizerDesc, NULL);
CachedObjectsGarbageCollect();
ID3D11RasterizerState2 *real = NULL;
HRESULT ret;
SERIALISE_TIME_CALL(ret = m_pDevice3->CreateRasterizerState2(pRasterizerDesc, &real));
@@ -806,8 +808,6 @@ HRESULT WrappedID3D11Device::CreateRasterizerState2(const D3D11_RASTERIZER_DESC2
ID3D11RasterizerState2 *wrapped = new WrappedID3D11RasterizerState2(real, this);
CachedObjectsGarbageCollect();
{
RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end());
IntAddRef(wrapped);
+8 -8
View File
@@ -2725,6 +2725,8 @@ HRESULT WrappedID3D11Device::CreateBlendState(const D3D11_BLEND_DESC *pBlendStat
if(ppBlendState == NULL)
return m_pDevice->CreateBlendState(pBlendStateDesc, NULL);
CachedObjectsGarbageCollect();
ID3D11BlendState *real = NULL;
HRESULT ret;
SERIALISE_TIME_CALL(ret = m_pDevice->CreateBlendState(pBlendStateDesc, &real));
@@ -2749,8 +2751,6 @@ HRESULT WrappedID3D11Device::CreateBlendState(const D3D11_BLEND_DESC *pBlendStat
FlushPendingDead();
ID3D11BlendState *wrapped = new WrappedID3D11BlendState1(real, this);
CachedObjectsGarbageCollect();
{
RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end());
// add an internal reference too just so if the application creates and destroys state objects
@@ -2840,6 +2840,8 @@ HRESULT WrappedID3D11Device::CreateDepthStencilState(const D3D11_DEPTH_STENCIL_D
if(ppDepthStencilState == NULL)
return m_pDevice->CreateDepthStencilState(pDepthStencilDesc, NULL);
CachedObjectsGarbageCollect();
ID3D11DepthStencilState *real = NULL;
HRESULT ret;
SERIALISE_TIME_CALL(ret = m_pDevice->CreateDepthStencilState(pDepthStencilDesc, &real));
@@ -2864,8 +2866,6 @@ HRESULT WrappedID3D11Device::CreateDepthStencilState(const D3D11_DEPTH_STENCIL_D
FlushPendingDead();
ID3D11DepthStencilState *wrapped = new WrappedID3D11DepthStencilState(real, this);
CachedObjectsGarbageCollect();
{
RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end());
IntAddRef(wrapped);
@@ -2953,6 +2953,8 @@ HRESULT WrappedID3D11Device::CreateRasterizerState(const D3D11_RASTERIZER_DESC *
if(ppRasterizerState == NULL)
return m_pDevice->CreateRasterizerState(pRasterizerDesc, NULL);
CachedObjectsGarbageCollect();
ID3D11RasterizerState *real = NULL;
HRESULT ret;
SERIALISE_TIME_CALL(ret = m_pDevice->CreateRasterizerState(pRasterizerDesc, &real));
@@ -2977,8 +2979,6 @@ HRESULT WrappedID3D11Device::CreateRasterizerState(const D3D11_RASTERIZER_DESC *
FlushPendingDead();
ID3D11RasterizerState *wrapped = new WrappedID3D11RasterizerState2(real, this);
CachedObjectsGarbageCollect();
{
RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end());
IntAddRef(wrapped);
@@ -3066,6 +3066,8 @@ HRESULT WrappedID3D11Device::CreateSamplerState(const D3D11_SAMPLER_DESC *pSampl
if(ppSamplerState == NULL)
return m_pDevice->CreateSamplerState(pSamplerDesc, NULL);
CachedObjectsGarbageCollect();
ID3D11SamplerState *real = NULL;
HRESULT ret;
SERIALISE_TIME_CALL(ret = m_pDevice->CreateSamplerState(pSamplerDesc, &real));
@@ -3090,8 +3092,6 @@ HRESULT WrappedID3D11Device::CreateSamplerState(const D3D11_SAMPLER_DESC *pSampl
FlushPendingDead();
ID3D11SamplerState *wrapped = new WrappedID3D11SamplerState(real, this);
CachedObjectsGarbageCollect();
{
RDCASSERT(m_CachedStateObjects.find(wrapped) == m_CachedStateObjects.end());
IntAddRef(wrapped);