Skip to content

Commit fee55d2

Browse files
committed
Added automatic TXD resizing for 32 bit OS users to help fix low memory crashes
1 parent bba7580 commit fee55d2

23 files changed

+574
-5
lines changed

MTA10/core/CCommandFuncs.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,5 +513,6 @@ void CCommandFuncs::ShowFrameGraph ( const char* szParameters )
513513

514514
void CCommandFuncs::JingleBells ( const char* szParameters )
515515
{
516+
g_strJingleBells = szParameters;
516517
g_pCore->GetConsole ()->Print ( "Batman smells" );
517518
}

MTA10/core/CCore.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ static float fTest = 1;
3333

3434
extern CCore* g_pCore;
3535
bool g_bBoundsChecker = false;
36+
SString g_strJingleBells;
3637

3738
BOOL AC_RestrictAccess( VOID )
3839
{
@@ -2387,3 +2388,21 @@ void CCore::NotifyRenderingGrass( bool bIsRenderingGrass )
23872388
m_bIsRenderingGrass = bIsRenderingGrass;
23882389
CDirect3DEvents9::CloseActiveShader();
23892390
}
2391+
2392+
bool CCore::GetRightSizeTxdEnabled( void )
2393+
{
2394+
// 32 bit users get rightsized txds
2395+
if ( !Is64BitOS() )
2396+
return true;
2397+
2398+
// Low ram users get rightsized txds
2399+
int iSystemRamMB = static_cast < int > ( GetWMITotalPhysicalMemory () / 1024LL / 1024LL );
2400+
if ( iSystemRamMB <= 2048 )
2401+
return true;
2402+
2403+
// Debug users get rightsized txds
2404+
if ( g_strJingleBells == "rightsize" )
2405+
return true;
2406+
2407+
return false;
2408+
}

MTA10/core/CCore.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ extern class CCore* g_pCore;
8080
extern class CGraphics* g_pGraphics;
8181
extern class CLocalization* g_pLocalization;
8282
bool UsingAltD3DSetup();
83+
extern SString g_strJingleBells;
8384

8485
class CCore : public CCoreInterface, public CSingleton < CCore >
8586
{
@@ -272,6 +273,7 @@ class CCore : public CCoreInterface, public CSingleton < CCore >
272273
bool GetRequiredDisplayResolution ( int& iOutWidth, int& iOutHeight, int& iOutColorBits, int& iOutAdapterIndex, bool& bOutAllowUnsafeResolutions );
273274
void NotifyRenderingGrass ( bool bIsRenderingGrass );
274275
bool IsRenderingGrass ( void ) { return m_bIsRenderingGrass; }
276+
bool GetRightSizeTxdEnabled ( void );
275277

276278
private:
277279
// Core devices.

MTA10/core/CGraphics.cpp

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,3 +1949,138 @@ void CGraphics::DrawProgressMessage( bool bPreserveBackbuffer )
19491949

19501950
m_ActiveBlendMode = savedBlendMode;
19511951
}
1952+
1953+
1954+
/////////////////////////////////////////////////////////////
1955+
//
1956+
// CGraphics::ResizeTextureData
1957+
//
1958+
// Resize supplied texture data into outBuffer
1959+
// Returns true on success
1960+
//
1961+
/////////////////////////////////////////////////////////////
1962+
bool CGraphics::ResizeTextureData( const void* pData, uint uiDataPitch, uint uiWidth, uint uiHeight, uint d3dFormat, uint uiNewWidth, uint uiNewHeight, CBuffer& outBuffer )
1963+
{
1964+
bool bResult = false;
1965+
IDirect3DSurface9* pCurrentSurface = NULL;
1966+
IDirect3DSurface9* pNewSurface = NULL;
1967+
1968+
do
1969+
{
1970+
// Create surfaces
1971+
if ( FAILED( g_pGraphics->GetDevice()->CreateOffscreenPlainSurface( uiWidth, uiHeight, (D3DFORMAT)d3dFormat, D3DPOOL_SYSTEMMEM, &pCurrentSurface, NULL ) ) )
1972+
break;
1973+
if ( FAILED( g_pGraphics->GetDevice()->CreateOffscreenPlainSurface( uiNewWidth, uiNewHeight, (D3DFORMAT)d3dFormat, D3DPOOL_SYSTEMMEM, &pNewSurface, NULL ) ) )
1974+
break;
1975+
1976+
// Data in
1977+
if ( !CopyDataToSurface( pCurrentSurface, (const BYTE*)pData, uiDataPitch ) )
1978+
break;
1979+
1980+
// Resize
1981+
if ( FAILED( D3DXLoadSurfaceFromSurface( pNewSurface, NULL, NULL, pCurrentSurface, NULL, NULL, D3DX_FILTER_TRIANGLE, 0 ) ) )
1982+
break;
1983+
1984+
// Data out
1985+
if ( !CopyDataFromSurface( pNewSurface, outBuffer ) )
1986+
break;
1987+
1988+
bResult = true;
1989+
}
1990+
while ( false );
1991+
1992+
// Clean up
1993+
SAFE_RELEASE( pCurrentSurface );
1994+
SAFE_RELEASE( pNewSurface );
1995+
return bResult;
1996+
}
1997+
1998+
1999+
/////////////////////////////////////////////////////////////
2000+
//
2001+
// CopyDataFromSurface
2002+
//
2003+
// Copy raw data into the supplied surface
2004+
// Returns true on success
2005+
//
2006+
/////////////////////////////////////////////////////////////
2007+
bool CGraphics::CopyDataToSurface( IDirect3DSurface9* pSurface, const uchar* pData, uint uiDataPitch )
2008+
{
2009+
D3DSURFACE_DESC SurfDesc;
2010+
pSurface->GetDesc( &SurfDesc );
2011+
2012+
D3DLOCKED_RECT LockedRect;
2013+
if ( FAILED( pSurface->LockRect( &LockedRect, NULL, D3DLOCK_NOSYSLOCK ) ) )
2014+
return false;
2015+
2016+
uiDataPitch /= CRenderItemManager::GetPitchDivisor( SurfDesc.Format );
2017+
uint uiSurfPitch = LockedRect.Pitch / CRenderItemManager::GetPitchDivisor( SurfDesc.Format );
2018+
BYTE* pSurfBits = (BYTE*)LockedRect.pBits;
2019+
2020+
uint uiLineWidthBytes = SurfDesc.Width * CRenderItemManager::GetBitsPerPixel( SurfDesc.Format ) / 8;
2021+
2022+
if ( uiLineWidthBytes == uiSurfPitch && uiLineWidthBytes == uiDataPitch )
2023+
{
2024+
// Pitches match byte width
2025+
memcpy( pSurfBits, pData, uiLineWidthBytes * SurfDesc.Height );
2026+
}
2027+
else
2028+
{
2029+
// Copy lines into surface
2030+
for ( uint i = 0; i < SurfDesc.Height; i++ )
2031+
{
2032+
memcpy( pSurfBits + uiSurfPitch * i, pData + uiDataPitch * i, uiLineWidthBytes );
2033+
}
2034+
}
2035+
2036+
if ( FAILED( pSurface->UnlockRect() ) )
2037+
return false;
2038+
2039+
return true;
2040+
}
2041+
2042+
2043+
/////////////////////////////////////////////////////////////
2044+
//
2045+
// CopyDataFromSurface
2046+
//
2047+
// Copy raw data from the supplied surface into outBuffer
2048+
// Returns true on success
2049+
//
2050+
/////////////////////////////////////////////////////////////
2051+
bool CGraphics::CopyDataFromSurface( IDirect3DSurface9* pSurface, CBuffer& outBuffer )
2052+
{
2053+
D3DSURFACE_DESC SurfDesc;
2054+
pSurface->GetDesc( &SurfDesc );
2055+
2056+
D3DLOCKED_RECT LockedRect;
2057+
if ( FAILED( pSurface->LockRect( &LockedRect, NULL, D3DLOCK_NOSYSLOCK ) ) )
2058+
return false;
2059+
2060+
uint uiSurfPitch = LockedRect.Pitch / CRenderItemManager::GetPitchDivisor( SurfDesc.Format );
2061+
BYTE* pSurfBits = (BYTE*)LockedRect.pBits;
2062+
2063+
uint uiLineWidthBytes = SurfDesc.Width * CRenderItemManager::GetBitsPerPixel( SurfDesc.Format ) / 8;
2064+
2065+
outBuffer.SetSize( uiLineWidthBytes * SurfDesc.Height );
2066+
char* pOutData = outBuffer.GetData();
2067+
2068+
if ( uiLineWidthBytes == uiSurfPitch )
2069+
{
2070+
// Pitch matches byte width
2071+
memcpy( pOutData, pSurfBits, uiLineWidthBytes * SurfDesc.Height );
2072+
}
2073+
else
2074+
{
2075+
// Copy lines from surface
2076+
for ( uint i = 0; i < SurfDesc.Height; i++ )
2077+
{
2078+
memcpy( pOutData + uiLineWidthBytes * i, pSurfBits + uiSurfPitch * i, uiLineWidthBytes );
2079+
}
2080+
}
2081+
2082+
if ( FAILED( pSurface->UnlockRect() ) )
2083+
return false;
2084+
2085+
return true;
2086+
}

MTA10/core/CGraphics.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,11 @@ class CGraphics : public CGraphicsInterface, public CSingleton < CGraphics >
194194
void SaveGTARenderStates ( void );
195195
void RestoreGTARenderStates ( void );
196196

197+
// Texture data manipulation
198+
bool ResizeTextureData ( const void* pData, uint uiDataPitch, uint uiWidth, uint uiHeight, uint d3dFormat, uint uiNewWidth, uint uiNewHeight, CBuffer& outBuffer );
199+
bool CopyDataToSurface ( IDirect3DSurface9* pSurface, const uchar* pPixelsData, uint uiDataPitch );
200+
bool CopyDataFromSurface ( IDirect3DSurface9* pSurface, CBuffer& outBuffer );
201+
197202
// To draw queued up drawings
198203
void DrawPreGUIQueue ( void );
199204
void DrawPostGUIQueue ( void );

MTA10/core/CRenderItemManager.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,30 @@ int CRenderItemManager::GetBitsPerPixel ( D3DFORMAT Format )
846846
}
847847

848848

849+
////////////////////////////////////////////////////////////////
850+
//
851+
// CRenderItemManager::GetPitchDivisor
852+
//
853+
// Returns block width for a given D3D format
854+
//
855+
////////////////////////////////////////////////////////////////
856+
int CRenderItemManager::GetPitchDivisor ( D3DFORMAT Format )
857+
{
858+
switch ( Format )
859+
{
860+
case D3DFMT_DXT1:
861+
case D3DFMT_DXT2:
862+
case D3DFMT_DXT3:
863+
case D3DFMT_DXT4:
864+
case D3DFMT_DXT5:
865+
return 4;
866+
867+
default:
868+
return 1;
869+
}
870+
}
871+
872+
849873
////////////////////////////////////////////////////////////////
850874
//
851875
// CRenderItemManager::CalcD3DResourceMemoryKBUsage

MTA10/core/CRenderItemManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class CRenderItemManager : public CRenderItemManagerInterface
6969
void NotifyShaderItemUsesDepthBuffer ( CShaderItem* pShaderItem, bool bUsesDepthBuffer );
7070

7171
static int GetBitsPerPixel ( D3DFORMAT Format );
72+
static int GetPitchDivisor ( D3DFORMAT Format );
7273
static int CalcD3DResourceMemoryKBUsage ( IDirect3DResource9* pD3DResource );
7374
static int CalcD3DSurfaceMemoryKBUsage ( IDirect3DSurface9* pD3DSurface );
7475
static int CalcD3DTextureMemoryKBUsage ( IDirect3DTexture9* pD3DTexture );

0 commit comments

Comments
 (0)