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

Started by
9 comments, last by gwihlidal 19 years, 9 months ago
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
Advertisement
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.
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
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?)

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.
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
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
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
Chris ByersMicrosoft DirectX MVP - 2005
That's actually something I had thought about too. Unless there is a method to query the remaining references on a COM object?

~Graham
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
Chris ByersMicrosoft DirectX MVP - 2005
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
Yep, you should be fine.
Chris ByersMicrosoft DirectX MVP - 2005

This topic is closed to new replies.

Advertisement