1- There occurs a certain amount of memory leak after releasing the 2D
textures.
2- After a group of Textures with specific W/H are allocated and freed,
the DIRECTX function D3DXCreateTexture fails to allocate another group of 2D
textures of specific W/H, even though there is enough memory available to
hold these textures.
I have written a simple API sample that shows the above problems.
System information :-
Operating system :- Windows 7 Ultimate 32-bit
Processor :- Intel(R) Core(TM)2 Quad CPU
Memory :- 3072MB RAM
Display :- NVIDIA GeForce 9400 GT.
NOTE:- The above problems do not occur on Windows XP.
========================================
BOOL Alloc2Dtexture(INT OrientType)
{
UINT MipLevels2D = 0 ;
DWORD Usage = 0 ;
D3DFORMAT Format = D3DFMT_L16 ;
D3DPOOL Pool = D3DPOOL_MANAGED ;
HRESULT nResult = 1 ;
switch (OrientType)
{
case 0:
{
m_ppTextureC = (LPDIRECT3DTEXTURE9
*)malloc(sizeof(LPDIRECT3DTEXTURE9) * Depth);if ( !m_ppTextureC ){ return
FALSE ;}
for (UINT i = 0 ; i < Depth ; i++ ) m_ppTextureC[i] = NULL ;
for (UINT i = 0 ; i < Depth ; i++)
{
nResult = D3DXCreateTexture( g_pd3dDevice, Width, Hight,
MipLevels2D, Usage, Format, Pool, &m_ppTextureC[i] ) ;
if( FAILED(nResult) ) { return FALSE; }
}
}
break;
case 1:
{
m_ppTextureB = (LPDIRECT3DTEXTURE9
*)malloc(sizeof(LPDIRECT3DTEXTURE9) * Hight);if ( !m_ppTextureB ){ return
FALSE ;}
for (UINT i = 0 ; i < Hight ; i++ ) m_ppTextureB[i] = NULL ;
for ( UINT i = 0 ; i < Hight ; i++ )
{
nResult = D3DXCreateTexture( g_pd3dDevice, Width, Depth,
MipLevels2D, Usage, Format, Pool, &m_ppTextureB[i]);
if( FAILED(nResult) ){ return FALSE; }
}
}
break;
case 2:
{
m_ppTextureA = (LPDIRECT3DTEXTURE9
*)malloc(sizeof(LPDIRECT3DTEXTURE9)* Width);if ( !m_ppTextureA){ return FALSE
;}
for (UINT i = 0 ; i < Width ; i++ ) m_ppTextureA[i] = NULL ;
for ( UINT i = 0 ; i < Width ; i++ )
{
nResult = D3DXCreateTexture( g_pd3dDevice, Hight, Depth,
MipLevels2D, Usage, Format, Pool, &m_ppTextureA[i] ) ;
if(FAILED(nResult)){ return FALSE; }
}
}
break;
}
return TRUE ;
}
VOID Free2Dtexture(INT OrientType)
{
switch(OrientType)
{
case 0:
if(NULL != m_ppTextureC)
{
for ( UINT i = 0 ; i < Depth ; i++ )
if(m_ppTextureC[i]!= NULL)
{
m_ppTextureC[i]->Release() ;
m_ppTextureC[i] = NULL ;
}
free(m_ppTextureC); m_ppTextureC = NULL ;
}
break;
case 1:
if(NULL != m_ppTextureB)
{
for ( UINT i = 0 ; i < Hight ; i++ )
if(m_ppTextureB[i] != NULL)
{
m_ppTextureB[i]->Release() ;
m_ppTextureB[i] = NULL ;
}
free(m_ppTextureB); m_ppTextureB = NULL ;
}
break;
case 2:
if(NULL != m_ppTextureA)
{
for ( UINT i = 0 ; i < Width ; i++ )
if(m_ppTextureA[i] != NULL)
{
m_ppTextureA[i]->Release();
m_ppTextureA[i] = NULL ;
}
free(m_ppTextureA); m_ppTextureA = NULL ;
}
break;
}
return ;
}
BOOL AllocTest()
{
INT nSize = Width * Hight * Depth ;
UINT16 *Data = NULL ;
Data = (UINT16 *)malloc( nSize * sizeof(UINT16)) ;
if (Data == NULL )
return FALSE ;
else
memset(Data, 0, nSize * sizeof(UINT16)) ;
BOOL Res = 0 ;
Res = Alloc2Dtexture(0);
if (Res)
Res = Alloc2Dtexture(1);
if (Res)
Res = Alloc2Dtexture(2);
Free2Dtexture(0);
Free2Dtexture(1);
Free2Dtexture(2);
free(Data) ;
Data = NULL ;
return Res ;
}
BOOL TestSecondAllocationFail()
{
BOOL Res = 1 ;
Width = Dim[0][0] ;
Hight = Dim[0][1] ;
Depth = Dim[0][2] ;
Res = AllocTest() ;
if (!Res) { return Res ;}
Width = Dim[1][0] ;
Hight = Dim[1][1] ;
Depth = Dim[1][2] ;
Res = AllocTest() ;
if (!Res) { return Res ;}
return Res ;
}
BOOL TestMemoryLeak()
{
BOOL Res = 1 ;
Width = Dim[0][0] ;
Hight = Dim[0][1] ;
Depth = Dim[0][2] ;
for (UINT j = 0 ; j < 100 ; j++ )
{
Res = AllocTest() ;
if (!Res) { break ;}
}
return Res ;
}
BOOL TestMemoryLeakOneForLoop()
{
BOOL Res = 1 ;
Width = Dim[0][0] ;
Hight = Dim[0][1] ;
Depth = Dim[0][2] ;
Res = AllocTest() ;
return Res ;
}