Sign in to follow this  
reaperrar

Q regarding IDirect3DTexture9::GetSurfaceLevel

Recommended Posts

For both:

[CODE]IDirect3DTexture9::GetSurfaceLevel
IDirect3DDevice9::GetRenderTarget[/CODE]

Am I supposed to manage the "IDirect3DSurface9 **ppSurfaceLevel" passed into either of these function calls in terms of releasing?

I assumed these calls would make the **ppSurfaceLevel point to the surface level, though unless I release them manually I d3d get memory leaks.

E.G

This has d3d memory leaks outputted ([i]"Direct3D9: (ERROR) :Memory Address..."[/i]):
[CODE]//poIDirect3DDevice9 is an initialized IDirect3DDevice9*
//oRenderTarget1, oRenderTarget2 and oRenderTarget3 are initialized IDirect3DTexture9*

//Get backbuffer first
IDirect3DSurface9* poBackbufferSurface;
poIDirect3DDevice9->GetRenderTarget(0, &poBackbufferSurface);

//Get Surface of render target
IDirect3DSurface9* poRTSurface1;
oRenderTarget1->GetSurfaceLevel(0, &poRTSurface1);
IDirect3DSurface9* poRTSurface2;
oRenderTarget2->GetSurfaceLevel(0, &poRTSurface2);
IDirect3DSurface9* poRTSurface3;
oRenderTarget3->GetSurfaceLevel(0, &poRTSurface3);

oRenderTarget1->Release();
oRenderTarget2->Release();
oRenderTarget3->Release();

poIDirect3DDevice9->Release();

//App Ends[/CODE]

Whereas this does not:
[CODE]//poIDirect3DDevice9 is an initialized IDirect3DDevice9*
//oRenderTarget1, oRenderTarget2 and oRenderTarget3 are initialized IDirect3DTexture9*

IDirect3DSurface9* poBackbufferSurface = 0;
IDirect3DSurface9* poRTSurface1 = 0;
IDirect3DSurface9* poRTSurface2 = 0;
IDirect3DSurface9* poRTSurface3 = 0;

//Get backbuffer first
poIDirect3DDevice9->GetRenderTarget(0, &poBackbufferSurface);

//Get Surface of render target
oRenderTarget1->GetSurfaceLevel(0, &poRTSurface1);
oRenderTarget2->GetSurfaceLevel(0, &poRTSurface2);
oRenderTarget3->GetSurfaceLevel(0, &poRTSurface3);

poBackbufferSurface->Release();
poRTSurface1->Release();
poRTSurface2->Release();
poRTSurface3->Release();

oRenderTarget1->Release();
oRenderTarget2->Release();
oRenderTarget3->Release();
poIDirect3DDevice9->Release();

//App Ends[/CODE]

Also, in the first example, if the device is lost then a reset is attempted when appropriate... unless I free those surfaces I get the following error:
[i]"All user created D3DPOOL_DEFAULT surfaces must be freed before ResetEx can succeed. ResetEx Fails."[/i]
I release all resources (including the tetxures the surfaces being pointed to by poRTSurface1 etc) before reset yet I still get the error. If I do not get the surface and still release all my other resources like normal, I do not get the error.

I thought poRTSurface1 etc where just pointers to memory stored and released by the "IDirect3DTexture9* oRenderTarget1 " etc :?

Share this post


Link to post
Share on other sites
You are supposed to Release them; it's there in the documentation. E.g. for GetSurfaceLevel:[quote]Calling this method will increase the internal reference count on the IDirect3DSurface9 interface. Failure to call IUnknown::Release when finished using this IDirect3DSurface9 interface results in a memory leak.[/quote]
This also gives an indication of what's going on - they're not just pointers, they're reference-counted objects. Various operations will increase the reference count, and Release decreases it; when the reference count goes to 0 Release will fully destroy the object.

So in this case, let's say that the Reference count was originally 1. Call GetSurfaceLevel and it goes to 2, do your stuff, then call Release and it goes back to 1. Release the containing texture and it goes to 0, at which time it's destroyed. But if you fail to Release after GetSurfaceLevel, this last one will only go to 1 (or if you're calling GetSurfaceLevel every frame it will be much much much higher) so the object is still live and you get the error.

Share this post


Link to post
Share on other sites
These kinds of problems (and questions) almost completely disappear if you use CComPtr from the ATL to manage all the d3d pointers.

Share this post


Link to post
Share on other sites
[quote name='Zoner' timestamp='1336176418' post='4937511']
These kinds of problems (and questions) almost completely disappear if you use CComPtr from the ATL to manage all the d3d pointers.
[/quote]
Agreed, but unfortunately not an option for anyone who's stuck with the Express versions of MSVC.

Share this post


Link to post
Share on other sites
[quote name='mhagain' timestamp='1336178421' post='4937516']
[quote name='Zoner' timestamp='1336176418' post='4937511']
These kinds of problems (and questions) almost completely disappear if you use CComPtr from the ATL to manage all the d3d pointers.
[/quote]
Agreed, but unfortunately not an option for anyone who's stuck with the Express versions of MSVC.
[/quote]

The Windows Runtime Library in VS 2011 has a new [url="http://msdn.microsoft.com/en-us/library/br244983%28v=vs.110%29.aspx"]ComPtr class[/url], and there's also [url="http://msdn.microsoft.com/en-us/library/417w8b3b%28v=vs.110%29.aspx"]_com_ptr_t[/url] which is part of the VC++ support libraries.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this