Sign in to follow this  
gwihlidal

Do I need a valid Direct3D device to release associated resources?

Recommended Posts

Hi everyone, I am having some crashing issues with my engine when I shut everything down. It worked fine for the longest time, but either a leak was small enough to pass unnoticed, or I did something Direct3D didn't like. I noticed at one point sometimes I call release on a couple resources like textures and shaders that are created using the currently active device, but when I step through the debugger the device has already been released. Does this matter? Can I release resources even after the device itself has been released? It isn't a rendering issue, as that works fine, and I have traced and stepped through all my allocations MANY times. Thank you for your time, ~Graham

Share this post


Link to post
Share on other sites
Quote:
Original post by gwihlidal
I noticed at one point sometimes I call release on a couple resources like textures and shaders that are created using the currently active device, but when I step through the debugger the device has already been released. Does this matter? Can I release resources even after the device itself has been released?
No, it shouldn't matter. I created a test app (DX9) and released the IDirect3DDevice9 and IDirect3D objects before I released my other resources. However, you should release your resources in the reverse order that they were created. So, the IDirect3DDevice9 object should be released second-to-last, and the IDirect3D object should be released last.

Share this post


Link to post
Share on other sites
Each Direct3D object that needs the device implicitly holds a reference to it, so the device refcount is incremented with every object. Consequently, releasing the device first just decrements the refcount. When you release all your objects, your last one will release its device, which will make its refcount zero, which will actually destroy it.

So no, you don't need to release them in the reverse order of creation. I've seen that recommended, but I think that's for compatability with old/obsolete APIs (6 or 7, perhaps?)

Share this post


Link to post
Share on other sites
Quote:
Original post by Coder
So no, you don't need to release them in the reverse order of creation. I've seen that recommended, but I think that's for compatability with old/obsolete APIs (6 or 7, perhaps?)
Right - it's not required, just recommended.

What interfaces are you attempting to release? Some interfaces, such as ID3DXEffect and ID3DXSprite actually store a member copy of the app's LPDIRECT3DDEVICE9 upon construction. At that point, it should call IDirect3DDevice9::AddRef(), which adds a reference count. Then, when Release() is called, it calls IDirect3DDevice9::Release, which decrements the reference count. If the device has already been released (and thus deleted), it's going to crash when that is attempted.

Share this post


Link to post
Share on other sites
Hmm that's what I had actually thought, but my problems are causing considerable headache, and all signs point towards it.

I do in fact have one sprite resource, but I'm pretty sure that gets deallocated before I release the device.

I'm also getting some crazy debugging warnings when I turn on maximum debug information for the D3D runtime. Things like:

Direct3D9: (ERROR) :SetSamplerState failed.

Direct3D9: (ERROR) :Max anisotropy level less than 1.

Direct3D9: (ERROR) :Invalid texture sampler state value. SetSamplerState failed.

Direct3D9: (INFO) :Failed to create driver indexbuffer

Direct3D9: (ERROR) :GetTransform does not work in pure-device


Though I checked and valid settings are being specified, and the card is a Radeon 9600 Pro.

The engine has most components commented out now until I fix this, but I had very complex geometry being rendered perfectly fine, so I don't think values are invalid from the start, perhaps some instances are being reset?

Thanks a lot for the help so far!

~Graham

Share this post


Link to post
Share on other sites
I had the same occur with turning debugging on full blast. I have a Radeon 9200. I've also had my software crash when I didn't set a pointer to NULL after releasing it. It doesn't make sense to me, but when I set it to NULL immediately after releasing it, it worked. It was probably that the ref count wasn't decremented all the way because I left some resource out there, so when I manually set it to NULL, it just gets lost in the system. I don't completely understand what's going on there though. If that's the case, it's not a very good fix...I don't think you should have to set a COM object to NULL after releasing it. Does anyone know?

Chris

Share this post


Link to post
Share on other sites
I just did some reading on it. When you call Release(), the value returned is the reference count. You might want to check that and be sure it is 0 when your program is closing.

Chris

Share this post


Link to post
Share on other sites
Interesting, I didn't even check Release itself for returning a value, all the examples I've looked at have always voided the result basically, that's definitely something that can get me closer to finding the problem.

In regards to the sprite resource, as long as I call release on it before the device is released I should be fine?

Thanks,

~Graham

Share this post


Link to post
Share on other sites
Sounds good, thank you.

Here is a bit of info that might help out others on how to debug similar problems. This helped me pinpoint the potential problems (I'm still debugging things =)

External Source Paste

This macro (yes it's ugly) spots potential leak areas by checking the return value as being 0, and logging it if that is the case. It's simple, but should do the job. Now I just have to find out what is not being released.


Thank you very much,

~Graham

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