Skip to content

Commit

Permalink
Added another test fix for #9085 (Clone failed @ 'dxCreateShader')
Browse files Browse the repository at this point in the history
  • Loading branch information
ccw808 committed Jan 2, 2016
1 parent 76bd22a commit e53f44e
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 23 deletions.
26 changes: 17 additions & 9 deletions MTA10/core/CRenderItem.EffectCloner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ class CEffectClonerImpl : public CEffectCloner
CEffectClonerImpl ( CRenderItemManager* pManager );
virtual ~CEffectClonerImpl ( void );
virtual void DoPulse ( void );
virtual ID3DXEffect* CreateD3DEffect ( const SString& strFilename, const SString& strRootPath, SString& strOutStatus, bool& bOutUsesVertexShader, bool& bOutUsesDepthBuffer, bool bDebug );
virtual void ReleaseD3DEffect ( ID3DXEffect* pD3DEffect );
virtual ID3DXEffect** CreateD3DEffect ( const SString& strFilename, const SString& strRootPath, SString& strOutStatus, bool& bOutUsesVertexShader, bool& bOutUsesDepthBuffer, bool bDebug );
virtual void ReleaseD3DEffect ( ID3DXEffect** pD3DEffect );

// CEffectClonerImpl
void MaybeTidyUp ( bool bForceDrasticMeasures = false, CEffectTemplate* pKeepThis = NULL );

CElapsedTime m_TidyupTimer;
CRenderItemManager* m_pManager;
std::map < ID3DXEffect*, CEffectTemplate* > m_CloneMap;
std::map < ID3DXEffect**, CEffectTemplate* > m_CloneMap;
std::map < SString, CEffectTemplate* > m_ValidMap; // Active and files not changed since first created
std::vector < CEffectTemplate* > m_OldList; // Active but files changed since first created
uint m_uiCloneFailTotalCount;
Expand Down Expand Up @@ -84,7 +84,7 @@ CEffectClonerImpl::~CEffectClonerImpl ( void )
//
//
////////////////////////////////////////////////////////////////
ID3DXEffect* CEffectClonerImpl::CreateD3DEffect ( const SString& strFilename, const SString& strRootPath, SString& strOutStatus, bool& bOutUsesVertexShader, bool& bOutUsesDepthBuffer, bool bDebug )
ID3DXEffect** CEffectClonerImpl::CreateD3DEffect ( const SString& strFilename, const SString& strRootPath, SString& strOutStatus, bool& bOutUsesVertexShader, bool& bOutUsesDepthBuffer, bool bDebug )
{
// Do we have a match with the initial path
CEffectTemplate* pEffectTemplate = MapFindRef ( m_ValidMap, ConformPathForSorting ( strFilename ) );
Expand Down Expand Up @@ -134,7 +134,10 @@ ID3DXEffect* CEffectClonerImpl::CreateD3DEffect ( const SString& strFilename, co
}

if ( !strReport.empty() )
{
strReport += SString( "[effects cur:%d created:%d dest:%d]", g_pDeviceState->MemoryState.Effect.iCurrentCount, g_pDeviceState->MemoryState.Effect.iCreatedCount, g_pDeviceState->MemoryState.Effect.iDestroyedCount );
AddReportLog( 7544, SString( "NewEffectTemplate (call:%d) %s %s", uiCallCount, *strReport, *strFilename ) );
}
if ( !pEffectTemplate )
return NULL;
}
Expand Down Expand Up @@ -206,11 +209,14 @@ ID3DXEffect* CEffectClonerImpl::CreateD3DEffect ( const SString& strFilename, co
}
m_uiCloneSuccessTotalCount++;

ID3DXEffect** ppNewD3DEffect = new ID3DXEffect*;
*ppNewD3DEffect = pNewD3DEffect;

// Cross ref clone with original
MapSet ( m_CloneMap, pNewD3DEffect, pEffectTemplate );
MapSet ( m_CloneMap, ppNewD3DEffect, pEffectTemplate );

// Return result
return pNewD3DEffect;
return ppNewD3DEffect;
}


Expand All @@ -221,15 +227,17 @@ ID3DXEffect* CEffectClonerImpl::CreateD3DEffect ( const SString& strFilename, co
// Remove all refs to the d3d effect
//
////////////////////////////////////////////////////////////////
void CEffectClonerImpl::ReleaseD3DEffect ( ID3DXEffect* pD3DEffect )
void CEffectClonerImpl::ReleaseD3DEffect ( ID3DXEffect** ppD3DEffect )
{
// Find pEffectTemplate from which this d3d effect was cloned from
CEffectTemplate* pEffectTemplate = MapFindRef ( m_CloneMap, pD3DEffect );
CEffectTemplate* pEffectTemplate = MapFindRef ( m_CloneMap, ppD3DEffect );
assert ( pEffectTemplate );

// Remove from clone map
MapRemove ( m_CloneMap, pD3DEffect );
MapRemove ( m_CloneMap, ppD3DEffect );

ID3DXEffect* pD3DEffect = *ppD3DEffect;
delete ppD3DEffect;
// Remove from pEffectTemplate. This will alse release the d3d effect.
pEffectTemplate->UnCloneD3DEffect ( pD3DEffect );
}
Expand Down
4 changes: 2 additions & 2 deletions MTA10/core/CRenderItem.EffectCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ class CEffectCloner
public:
virtual ~CEffectCloner ( void ) {}
virtual void DoPulse ( void ) = 0;
virtual ID3DXEffect* CreateD3DEffect ( const SString& strFilename, const SString& strRootPath, SString& strOutStatus, bool& bOutUsesVertexShader, bool& bOutUsesDepthBuffer, bool bDebug ) = 0;
virtual void ReleaseD3DEffect ( ID3DXEffect* pD3DEffect ) = 0;
virtual ID3DXEffect** CreateD3DEffect ( const SString& strFilename, const SString& strRootPath, SString& strOutStatus, bool& bOutUsesVertexShader, bool& bOutUsesDepthBuffer, bool bDebug ) = 0;
virtual void ReleaseD3DEffect ( ID3DXEffect** pD3DEffect ) = 0;
};

CEffectCloner* NewEffectCloner ( CRenderItemManager* pManager );
Expand Down
19 changes: 9 additions & 10 deletions MTA10/core/CRenderItem.EffectTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class CEffectTemplateImpl : public CEffectTemplate
bool m_bHaveFilesChanged;
std::map < SString, SString > m_FileMD5Map;
CTickCount m_TickCountLastUsed;
std::set < ID3DXEffect* > m_CloneList;
uint m_uiCloneCount;
SDebugInfo m_DebugInfo;
HRESULT m_CreateHResult;
};
Expand Down Expand Up @@ -193,7 +193,7 @@ void CEffectTemplateImpl::PreDestruct ( void )
////////////////////////////////////////////////////////////////
int CEffectTemplateImpl::GetTicksSinceLastUsed ( void )
{
if ( !m_CloneList.empty () )
if ( m_uiCloneCount != 0 )
return 0; // Used right now

CTickCount delta = CTickCount::Now ( true ) - m_TickCountLastUsed;
Expand Down Expand Up @@ -445,9 +445,9 @@ ID3DXEffect* CEffectTemplateImpl::CloneD3DEffect ( SString& strOutStatus, bool&
{
// Clone D3DXEffect
ID3DXEffect* pNewD3DEffect = NULL;
LPDIRECT3DDEVICE9 pDevice = NULL;
m_pD3DEffect->GetDevice ( &pDevice );
outHResult = m_pD3DEffect->CloneEffect ( pDevice, &pNewD3DEffect );
outHResult = D3D_OK;
pNewD3DEffect = m_pD3DEffect;
pNewD3DEffect->AddRef();

m_DebugInfo.cloneResult = outHResult;
if ( !pNewD3DEffect )
Expand Down Expand Up @@ -489,8 +489,7 @@ ID3DXEffect* CEffectTemplateImpl::CloneD3DEffect ( SString& strOutStatus, bool&
bOutUsesDepthBuffer = m_bUsesDepthBuffer;

// Add to list of clones
assert ( !MapContains ( m_CloneList, pNewD3DEffect ) );
MapInsert ( m_CloneList, pNewD3DEffect );
m_uiCloneCount++;
return pNewD3DEffect;
}

Expand All @@ -504,10 +503,10 @@ ID3DXEffect* CEffectTemplateImpl::CloneD3DEffect ( SString& strOutStatus, bool&
////////////////////////////////////////////////////////////////
void CEffectTemplateImpl::UnCloneD3DEffect ( ID3DXEffect* pOldD3DEffect )
{
assert ( MapContains ( m_CloneList, pOldD3DEffect ) );
MapRemove ( m_CloneList, pOldD3DEffect );
assert( m_uiCloneCount > 0 );
m_uiCloneCount--;

if ( m_CloneList.empty () )
if ( m_uiCloneCount == 0 )
m_TickCountLastUsed = CTickCount::Now ( true );

SAFE_RELEASE( pOldD3DEffect );
Expand Down
6 changes: 4 additions & 2 deletions MTA10/core/CRenderItem.EffectWrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,8 @@ void CEffectWrapImpl::CreateUnderlyingData ( const SString& strFilename, const S
m_uiSaveStateFlags = D3DXFX_DONOTSAVESHADERSTATE; // D3DXFX_DONOTSAVE(SHADER|SAMPLER)STATE

// Fetch compiled D3DEffect
m_pD3DEffect = m_pManager->GetEffectCloner ()->CreateD3DEffect ( strFilename, strRootPath, strOutStatus, m_bUsesVertexShader, m_bUsesDepthBuffer, bDebug );
m_ppD3DEffect = m_pManager->GetEffectCloner ()->CreateD3DEffect ( strFilename, strRootPath, strOutStatus, m_bUsesVertexShader, m_bUsesDepthBuffer, bDebug );
m_pD3DEffect = m_ppD3DEffect ? *m_ppD3DEffect : NULL;

if ( !m_pD3DEffect )
return;
Expand Down Expand Up @@ -628,7 +629,8 @@ void CEffectWrapImpl::ReleaseUnderlyingData ( void )
{
if ( m_pD3DEffect )
{
m_pManager->GetEffectCloner ()->ReleaseD3DEffect ( m_pD3DEffect );
m_pManager->GetEffectCloner ()->ReleaseD3DEffect ( m_ppD3DEffect );
m_ppD3DEffect = NULL;
m_pD3DEffect = NULL;
}
}
Expand Down

0 comments on commit e53f44e

Please sign in to comment.