SetCustomShaders leads memory leak on WP8 ?

Dec 27, 2012 at 1:43 PM
Edited Dec 27, 2012 at 1:45 PM

Hi,

 I 'm new to directX and I tried to use the spriteBatch in  the toolkit to make some shader effcts of a dds image file such as inverting color.

 I define a shader in hlsl and load the cso file to create a shader, and set the shader into the spriteBatch by using  SetCustomShaders  fuction:

Microsoft::WRL::ComPtr<ID3D11PixelShader> m_InvertedShader;

m_d3dDevice->CreatePixelShader(shaderFileData->Data,shaderFileData->Length,nullptr,m_InvertedShader.GetAddressOf());

m_spriteBatch->Begin(SpriteSortMode_Immediate,nullptr,nullptr,nullptr,nullptr,[=]
	{
		//Custom pixel shader for picture filter
		m_d3dContext.Get()->PSSetShader(m_Inverted.Get(),nullptr,0);
	},XMMatrixIdentity());
The image were inverted perfectly, but when I quit the application some memory leak information was shown in the ouput. I commetted out the setCustomShader parameter and the message of the output in VS also dispeared.
Is there any extra allocation of Com object in the setCustomShader delegation? Thanks for any hlep.
Coordinator
Jan 21, 2013 at 8:45 PM
Edited Jan 21, 2013 at 8:46 PM

Did you explicitly clear the state of your context or set PSSetShader for slot 0 to nulls before exiting?

Feb 7, 2013 at 8:06 AM
Made a call to ClearState before exiting. Still leaking memory.
Coordinator
Feb 7, 2013 at 8:10 PM
Interesting. Can you clarify exactly which object is 'leaked'? Make sure you set the debug name on all your objects.
Coordinator
Feb 7, 2013 at 9:16 PM
If you can provide a simplified/standalone repro for the behavior you are seeing, I would be happy to take a look.
Feb 15, 2013 at 5:47 AM
I've figured out a solution that works for me. Passing a lambda to the delegate kept a strong reference to the renderer (i.e. the CubeRenderer class from the default DirectX WP8 project). Removing the sprite batch before the renderer solves the problem for me.
Coordinator
Feb 15, 2013 at 3:50 PM
Oooh, nicely figured out!

I had thought about the lambda keeping closure variables alive, but was focusing on it closing over the shader itself, but in fact it is your containing class that is being closed over. This produces a classic circular reference chain, where SpriteBatch holds a reference to the lambda which holds a reference to the object that owns the SpriteBatch instance.

Could you try adding:
mSetCustomShaders = nullptr;
at line 387 in SpriteBatch.cpp (right after the mInBeginEndPair = false at the end of SpriteBatch::Impl::End) and confirm if that fixes the leak? I believe that will break the cycle without requiring anything special from your calling code.

Thanks!
Feb 18, 2013 at 1:35 AM
Yes, that fixes the leak.
Coordinator
Feb 18, 2013 at 3:27 PM
Thanks for confirming!

I will make this fix.