Skip to content

Commit

Permalink
Added test fix for #9085 (Clone failed @ 'dxCreateShader')
Browse files Browse the repository at this point in the history
  • Loading branch information
ccw808 committed Jun 7, 2016
1 parent 5835f39 commit 6b242d2
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 23 deletions.
44 changes: 33 additions & 11 deletions MTA10/core/CRenderItem.EffectCloner.cpp
Expand Up @@ -28,7 +28,7 @@ class CEffectClonerImpl : public CEffectCloner
virtual void ReleaseD3DEffect ( ID3DXEffect* pD3DEffect );

// CEffectClonerImpl
void MaybeTidyUp ( void );
void MaybeTidyUp ( bool bForceDrasticMeasures = false );

CElapsedTime m_TidyupTimer;
CRenderItemManager* m_pManager;
Expand Down Expand Up @@ -105,12 +105,19 @@ ID3DXEffect* CEffectClonerImpl::CreateD3DEffect ( const SString& strFilename, co
// Need to create new EffectTemplate?
if ( !pEffectTemplate )
{
pEffectTemplate = NewEffectTemplate ( m_pManager, strFilename, strRootPath, strOutStatus, bDebug );
if ( !pEffectTemplate->IsValid () )
for( uint i = 0 ; i < 2 ; i++ )
{
HRESULT hr;
pEffectTemplate = NewEffectTemplate ( m_pManager, strFilename, strRootPath, strOutStatus, bDebug, hr );
if ( pEffectTemplate || hr != E_OUTOFMEMORY || i > 0 )
break;
// Remove unused effects from memory any try again
AddReportLog( 7542, SString( "NewEffectTemplate E_OUTOFMEMORY - Attempting to free unused resources (%s) %s", *strOutStatus, *strFilename ) );
MaybeTidyUp( true );
}
if ( !pEffectTemplate )
{
AddReportLog( 7544, SString( "NewEffectTemplate failed (%s) %s", *strOutStatus, *strFilename ) );
SAFE_RELEASE( pEffectTemplate );
return NULL;
}

OutputDebugLine ( SString ( "[Shader] CEffectClonerImpl::CreateD3DEffect - New EffectTemplate for %s", *strFilename ) );
Expand All @@ -124,7 +131,17 @@ ID3DXEffect* CEffectClonerImpl::CreateD3DEffect ( const SString& strFilename, co
//

// Clone D3DXEffect
ID3DXEffect* pNewD3DEffect = pEffectTemplate->CloneD3DEffect ( strOutStatus, bOutUsesVertexShader, bOutUsesDepthBuffer);
ID3DXEffect* pNewD3DEffect;
for( uint i = 0 ; i < 2 ; i++ )
{
HRESULT hr;
pNewD3DEffect = pEffectTemplate->CloneD3DEffect ( strOutStatus, bOutUsesVertexShader, bOutUsesDepthBuffer, hr );
if ( !pNewD3DEffect || hr != E_OUTOFMEMORY || i > 0 )
break;
// Remove unused effects from memory any try again
AddReportLog( 7543, SString( "CloneD3DEffect E_OUTOFMEMORY - Attempting to free unused resources (%s) %s", *strOutStatus, *strFilename ) );
MaybeTidyUp( true );
}

if( !pNewD3DEffect )
{
Expand Down Expand Up @@ -210,9 +227,9 @@ void CEffectClonerImpl::DoPulse ( void )
// Tidy up if been a little while since last time
//
////////////////////////////////////////////////////////////////
void CEffectClonerImpl::MaybeTidyUp ( void )
void CEffectClonerImpl::MaybeTidyUp ( bool bForceDrasticMeasures )
{
if ( m_TidyupTimer.Get () < 1000 )
if ( !bForceDrasticMeasures && m_TidyupTimer.Get () < 1000 )
return;

m_TidyupTimer.Reset ();
Expand All @@ -221,9 +238,9 @@ void CEffectClonerImpl::MaybeTidyUp ( void )
for ( uint i = 0 ; i < m_OldList.size () ; i++ )
{
CEffectTemplate* pEffectTemplate = m_OldList[i];
if ( pEffectTemplate->GetTicksSinceLastUsed () > 0 )
if ( pEffectTemplate->GetTicksSinceLastUsed () > ( bForceDrasticMeasures ? 0 : 1 ) )
{
OutputDebugLine ( "[Shader] CEffectClonerImpl::MaybeTidyUp: Releasing old EffectTemplate" );
OutputDebugLine ( "[Shader] CEffectClonerImpl::MaybeTidyUp: Releasing old EffectTemplate" );
SAFE_RELEASE( pEffectTemplate );
ListRemoveIndex ( m_OldList, i-- );
}
Expand All @@ -242,7 +259,7 @@ void CEffectClonerImpl::MaybeTidyUp ( void )
for ( std::map < SString, CEffectTemplate* >::iterator iter = m_ValidMap.begin () ; iter != m_ValidMap.end () ; )
{
CEffectTemplate* pEffectTemplate = iter->second;
if ( pEffectTemplate->GetTicksSinceLastUsed () > iTicks )
if ( pEffectTemplate->GetTicksSinceLastUsed () > ( bForceDrasticMeasures ? 0 : iTicks ) )
{
OutputDebugLine ( "[Shader] CEffectClonerImpl::MaybeTidyUp: Releasing valid EffectTemplate" );
SAFE_RELEASE( pEffectTemplate );
Expand All @@ -251,4 +268,9 @@ void CEffectClonerImpl::MaybeTidyUp ( void )
else
++iter;
}

if ( bForceDrasticMeasures )
{
CGraphics::GetSingleton().GetDevice()->EvictManagedResources();
}
}
4 changes: 2 additions & 2 deletions MTA10/core/CRenderItem.EffectCloner.h
Expand Up @@ -42,7 +42,7 @@ class CEffectTemplate : public CRenderItem

virtual bool HaveFilesChanged ( void ) = 0;
virtual int GetTicksSinceLastUsed ( void ) = 0;
virtual ID3DXEffect* CloneD3DEffect ( SString& strOutStatus, bool& bOutUsesVertexShader, bool& bOutUsesDepthBuffer ) = 0;
virtual ID3DXEffect* CloneD3DEffect ( SString& strOutStatus, bool& bOutUsesVertexShader, bool& bOutUsesDepthBuffer, HRESULT& outHResult ) = 0;
virtual void UnCloneD3DEffect ( ID3DXEffect* pD3DEffect ) = 0;

// Debugging #9085 - CloneEffect fail
Expand All @@ -56,4 +56,4 @@ class CEffectTemplate : public CRenderItem
virtual const SDebugInfo& GetDebugInfo ( void ) = 0;
};

CEffectTemplate* NewEffectTemplate ( CRenderItemManager* pManager, const SString& strFilename, const SString& strRootPath, SString& strOutStatus, bool bDebug );
CEffectTemplate* NewEffectTemplate ( CRenderItemManager* pManager, const SString& strFilename, const SString& strRootPath, SString& strOutStatus, bool bDebug, HRESULT& outHResult );
29 changes: 19 additions & 10 deletions MTA10/core/CRenderItem.EffectTemplate.cpp
Expand Up @@ -30,7 +30,7 @@ class CEffectTemplateImpl : public CEffectTemplate
// CEffectTemplate
virtual bool HaveFilesChanged ( void );
virtual int GetTicksSinceLastUsed ( void );
virtual ID3DXEffect* CloneD3DEffect ( SString& strOutStatus, bool& bOutUsesVertexShader, bool& bOutUsesDepthBuffer );
virtual ID3DXEffect* CloneD3DEffect ( SString& strOutStatus, bool& bOutUsesVertexShader, bool& bOutUsesDepthBuffer, HRESULT& outHResult );
virtual void UnCloneD3DEffect ( ID3DXEffect* pD3DEffect );
virtual const SDebugInfo& GetDebugInfo ( void ) { return m_DebugInfo; }

Expand All @@ -46,6 +46,7 @@ class CEffectTemplateImpl : public CEffectTemplate
CTickCount m_TickCountLastUsed;
std::set < ID3DXEffect* > m_CloneList;
SDebugInfo m_DebugInfo;
HRESULT m_CreateHResult;
};


Expand All @@ -54,11 +55,18 @@ class CEffectTemplateImpl : public CEffectTemplate
// CEffectTemplate instantiation
//
///////////////////////////////////////////////////////////////
CEffectTemplate* NewEffectTemplate ( CRenderItemManager* pManager, const SString& strFilename, const SString& strRootPath, SString& strOutStatus, bool bDebug )
CEffectTemplate* NewEffectTemplate ( CRenderItemManager* pManager, const SString& strFilename, const SString& strRootPath, SString& strOutStatus, bool bDebug, HRESULT& outHResult )
{
CEffectTemplateImpl* m_pEffectTemplate = new CEffectTemplateImpl ();
m_pEffectTemplate->PostConstruct ( pManager, strFilename, strRootPath, strOutStatus, bDebug );
return m_pEffectTemplate;
CEffectTemplateImpl* pEffectTemplate = new CEffectTemplateImpl ();
pEffectTemplate->PostConstruct ( pManager, strFilename, strRootPath, strOutStatus, bDebug );

outHResult = pEffectTemplate->m_CreateHResult;
if ( !pEffectTemplate->IsValid () )
{
SAFE_RELEASE ( pEffectTemplate );
}

return pEffectTemplate;
}


Expand Down Expand Up @@ -189,7 +197,7 @@ int CEffectTemplateImpl::GetTicksSinceLastUsed ( void )
return 0; // Used right now

CTickCount delta = CTickCount::Now ( true ) - m_TickCountLastUsed;
return static_cast < int > ( delta.ToLongLong () );
return static_cast < int > ( delta.ToLongLong () ) + 1;
}


Expand Down Expand Up @@ -265,7 +273,7 @@ void CEffectTemplateImpl::CreateUnderlyingData ( const SString& strFilename, con
SString strMetaPath = strFilename.Right ( strFilename.length () - strRootPath.length () );
CIncludeManager IncludeManager ( strRootPath, ExtractPath ( strMetaPath ) );
LPD3DXBUFFER pBufferErrors = NULL;
HRESULT hr = D3DXCreateEffectFromFile( m_pDevice, ExtractFilename ( strMetaPath ), &macroList[0], &IncludeManager, dwFlags, NULL, &m_pD3DEffect, &pBufferErrors );
m_CreateHResult = D3DXCreateEffectFromFile( m_pDevice, ExtractFilename ( strMetaPath ), &macroList[0], &IncludeManager, dwFlags, NULL, &m_pD3DEffect, &pBufferErrors );

// Handle compile errors
strOutStatus = "";
Expand All @@ -283,7 +291,7 @@ void CEffectTemplateImpl::CreateUnderlyingData ( const SString& strFilename, con
if( !m_pD3DEffect )
{
if ( strOutStatus.empty () )
strOutStatus = SString ( "[D3DXCreateEffectFromFile failed (%08x)%s]", hr, *IncludeManager.m_strReport );
strOutStatus = SString ( "[D3DXCreateEffectFromFile failed (%08x)%s]", m_CreateHResult, *IncludeManager.m_strReport );
return;
}

Expand Down Expand Up @@ -433,14 +441,15 @@ void CEffectTemplateImpl::ReleaseUnderlyingData ( void )
// Clone the d3d effect
//
////////////////////////////////////////////////////////////////
ID3DXEffect* CEffectTemplateImpl::CloneD3DEffect ( SString& strOutStatus, bool& bOutUsesVertexShader, bool& bOutUsesDepthBuffer )
ID3DXEffect* CEffectTemplateImpl::CloneD3DEffect ( SString& strOutStatus, bool& bOutUsesVertexShader, bool& bOutUsesDepthBuffer, HRESULT& outHResult )
{
// Clone D3DXEffect
ID3DXEffect* pNewD3DEffect = NULL;
LPDIRECT3DDEVICE9 pDevice = NULL;
m_pD3DEffect->GetDevice ( &pDevice );
m_DebugInfo.cloneResult = m_pD3DEffect->CloneEffect ( pDevice, &pNewD3DEffect );
outHResult = m_pD3DEffect->CloneEffect ( pDevice, &pNewD3DEffect );

m_DebugInfo.cloneResult = outHResult;
if ( !pNewD3DEffect )
{
m_DebugInfo.uiCloneFailCount++;
Expand Down

1 comment on commit 6b242d2

@mantisbot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issues mentioned in this commit (6b242d2):

Please sign in to comment.