Is reference counting the best and proper way to deal with ID3D11Resource objects?

Started by
7 comments, last by Jason Z 9 years, 11 months ago
Actually I am revisiting all tutorials and samples I learned about graphics and DirectX11 to make my own - simple - engine/framework.

In all professional code I saw, a sort of reference counting often deals with objects's lifetime.

My question is if reference counting is really the best and the proper way to deal with ID3D11Resource objects, and if it is better to use C++11's smart pointers or Microsoft's implementation (like ComPtr and CComPtr), or make my own reference counting implementation ("higly inspired" by a professional solution), or use raw/naked pointers brutally (I guess this one is not the best solution).

My doubts are about ID3D11Resource objects: since they have also to deal with GPU memory, should I take particularly care about something I'm missing, or is it suffice to treat them as any other objects?
"Recursion is the first step towards madness." - "Skegg?ld, Skálm?ld, Skildir ro Klofnir!"
Direct3D 12 quick reference: https://github.com/alessiot89/D3D12QuickRef/
Advertisement

In my engine, i've actually found i like raw pointers for resources. The reason is because i can keep better track of memory with them. I have a resource manager, and a base class for the resource. I have systems call the resource manager for a resource. If the resource is not yet loaded (in the dictionary of resources), the manager loads it and passes a reference to the resource. When this happens, the resource will increment the use count. When a system is done with a resource, it calls release on it, which decrements the use count. at the end of every frame, i have the resource manager check each of the resources for a use count of zero or less (it of course should never be less or there's a bug), and for each of these resources, the manager releases the actual resource and removes it from the list of resources.

The systems try to be smart enough to foresee any resources that might need to be used of course, so that they can be preloaded.

Doing it this way, i'm able to know exactly when resources are released. I don't want to release the resource the moment the use count reaches zero, because i felt that by releasing them all together at the end of a frame, the beginning of the next frame i'd know the exact amount of memory allocated for resources. it also gives the systems a chance to use that resource again before the end of the frame. there are times when a resource has been deleted, only to be asked for again within that same frame.

I know your not asking about a resource manager exactly, but another thing you could do is have the resource manager on a separate thread. For each of the resource types you would have a "missing" resource. What this missing resource would do, is take the place of any resource that is needed but not yet loaded. for example, if your system was trying to load a tree texture. your system calls for a tree texture, and the resource manager starts loading it. the system tries to use the tree texture, but since its not yet loaded, the resource manager gives it the "missing" texture to use instead (which could be a transparent image). If the resource manager is on the same thread, the game will pretty much freeze until the resource is loaded, or worse crash because the reference to the resource is bad since its not loaded yet. but since its on a separate thread, you might see off in the distance things starting to fade in as they are being loaded. you might not want to immediately switch from the missing resource to the real resource once its loaded, otherwise things will seem to pop into existence. instead you might want to blend them together so that the real resource slowly fades in.

Speaking in terms of graphics resource(not in game asset) I use intrusive ref counting to keep track of resource USAGE. The resource isn't automatically deleted, instead I check the ref count and if it is zero I decide whatever to delete or keep that resource.

For the actual resource usage(aka binding ID3D11Resource as a vertex/constant buffer/ect) the reference counting is bypassed(not needed and time wasteful because of the unnecessary ref ++ ref --) and intrusive ref counting is helping me with this.

I'm curious, why might you want to keep track of the actual usage of the resource? I believe it should be up to the system using that resource to decide whether it needs it or not, no matter how often it uses it. The system should be smart enough to know when to tell the resource manager whether it needs the resource or not, if it needs it, increment the ref, if it doesn't, decrement the ref

Thank you both for replay.

I will check for intrusive reference counting first and give it a try. Then I will think about implementing some sort of "smart" resources manager(s).

Of course more suggestions are always welcomed! happy.png

"Recursion is the first step towards madness." - "Skegg?ld, Skálm?ld, Skildir ro Klofnir!"
Direct3D 12 quick reference: https://github.com/alessiot89/D3D12QuickRef/

I've already explained this thing here http://www.gamedev.net/topic/655568-memory-management-of-resources/

In general, I would recommend against rolling your own smart pointers whenever possible. There are subtle issues with the way that these objects interact with the STL that will give you debugging nightmares. If you choose to use a smart pointer, use the standard ones - they are reliable and very well tested, and there is no reason to think that you will make them better on your own.

Regarding the management of resource lifetimes, I find that using the COM reference counting system is more than sufficient. Most of the time your engine/game will know in advance what needs to be loaded for a particular level, so non-automated resource handling should be perfectly fine. If you absolutely must use automatic resource lifetime management, then you should use the WRL::ComPtr which manages the object lifetime with the COM reference counting system. This gives you the benefits of automatic control, without having to create your own system to support it!

Thank you for the reply.

I saw that DirectXTK and your Hieroglyph 3 engine use WRL::ComPtr (it should work on Windows 7 too), while other solutions (like Epic's UE4) use a custom implementation of a smart pointer (https://docs.unrealengine.com/latest/INT/API/Runtime/Core/Templates/TRefCountPtr/index.html)

I am actually writing only the DX11 wrapper, but since then I will use it to define my custom GFX API, it would be fine to find a solution that could be used alongside all the project. For now I will do some tests to comprehend which solution is the best for me.
"Recursion is the first step towards madness." - "Skegg?ld, Skálm?ld, Skildir ro Klofnir!"
Direct3D 12 quick reference: https://github.com/alessiot89/D3D12QuickRef/

Yeah, if you are sticking to windows only, then WRL::ComPtr is a good solution. If you plan to go cross platform, then you will need a wrapper around your resource pointer anyways (to abstract the API specific parts) so then you can just use plain smart pointers for the wrapper object. If your wrapper object acquires the resource pointer in its constructor, and then releases it in its destructor, then the smart pointer will take care of the reference counting and just delete the wrapper when there are no more references to it (which will then release the resource pointer).

This is more or less what WRL::ComPtr does, with some additional goodies added in for querying interfaces and things like that. If you need those, you can always add them to the wrapper class. In fact, if you make your wrapper class a class template, then you can easily reuse it for any COM based object that you want to use...

This topic is closed to new replies.

Advertisement