Posted 11 May 2012 - 05:53 AM
As I continue to investigate the problem, I found something weird.
I used PIX to record a diagnostic log. At the very last frame, where all D3D objects are being released, I found out that one of our cubemaps is released this way:
Frame 000098 ........PRE: IDirect3DCubeTexture9::Release()
Frame 000098 ........POST: <0> IDirect3DCubeTexture9::Release()
While other cubemaps are released like this:
Frame 000098 ........PRE: IDirect3DCubeTexture9::Release()
Frame 000098 ............PRE: RemoveObject(D3D9 Cube Texture, 0x062AAD30, 0x0018E6E0)
Frame 000098 ............POST: <> RemoveObject(D3D9 Cube Texture, 0x062AAD30, 0x0018E6E0)
Frame 000098 ............PRE: RemoveObject(D3D9 Surface, 0x06272F60, NULL)
Frame 000098 ............POST: <> RemoveObject(D3D9 Surface, 0x06272F60, NULL)
Frame 000098 ............PRE: RemoveObject(D3D9 Surface, 0x06272ED0, NULL)
Frame 000098 ............POST: <> RemoveObject(D3D9 Surface, 0x06272ED0, NULL)
Frame 000098 ............PRE: RemoveObject(D3D9 Surface, 0x06272E40, NULL)
Frame 000098 ............POST: <> RemoveObject(D3D9 Surface, 0x06272E40, NULL)
Frame 000098 ............PRE: RemoveObject(D3D9 Surface, 0x06272DB0, NULL)
Frame 000098 ............POST: <> RemoveObject(D3D9 Surface, 0x06272DB0, NULL)
Frame 000098 ............PRE: RemoveObject(D3D9 Surface, 0x06272D20, NULL)
Frame 000098 ............POST: <> RemoveObject(D3D9 Surface, 0x06272D20, NULL)
Frame 000098 ............PRE: RemoveObject(D3D9 Surface, 0x062AAF18, NULL)
Frame 000098 ............POST: <> RemoveObject(D3D9 Surface, 0x062AAF18, NULL)
Frame 000098 ........POST: <0> IDirect3DCubeTexture9::Release()
The main difference here is that the latter call to IDirect3DCubeTexture9::Release() actually removed the texture object and all of its surfaces, but the first call did nothing.
And both of them returned a reference count of 0(<0>). That's why our sanity check on the return value of Release() can't catch this type of leak.
Of course, PIX marked the texture and the surfaces of the first cubemap as never destroyed, which means they are leaking.