Jump to content
  • Advertisement
Sign in to follow this  
Senzaki

[D3D12] Descriptor heaps and memory (de)allocation

This topic is 1063 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello!

 

I am currently trying to develop a little engine using Direct3D12 from scratch, in order to learn how to use it properly. I spend a lot of time reading the documentation, but there are still some points I do not fully understand. One of them is the way heap allocators work.

Problem 1: What I understood was that heap allocators were simply fixed-size arrays of descriptors: you ask for an amount of memory, and you get to use it however you want. But you should always try to minimize the amount of descriptor heaps you are using, as changing the current descriptor heap inside a command list can be costly. But when designing an "general" (if that even exists) engine, you cannot really know the amount of descriptors your user will need... So should I still create more than one descriptor (and maybe bind as many as possible in one call to SetDescriptorHeaps), or should I use another strategy.

Problem 2: Another problem I have is: when you no longer require a given buffer, you no longer need its associated descriptor. So the best solution would be to reuse its location within the descriptor heap. But this requires me to implement some kind of advanced memory allocation algorithm, which I would like to avoid if possible... I am not really trying to create an OS!

Example: Maybe it is because I did not fully understood the usage of descriptors, so here is an example of how I would use them in a real life situation (feel free to correct me if I'm wrong). Imagine I have a set of drawable objects, each of them having their own world transform. I would use a constant buffer (one for each object) to pass the associated matrices to the vertex shader. Allocating them is easy, as I only need to use the location right after the last descriptor I allocated on the heap. But when I delete one of these objects, is it my responsibility to make sure that the space that is no longer used will be reused for the next descriptor?

 

Thank you for your help!

Edited by Senzaki

Share this post


Link to post
Share on other sites
Advertisement


 But when designing an "general" (if that even exists) engine, you cannot really know the amount of descriptors your user will need...

 

I think you can for the most part.  If you have fixed level sizes (arena map, race track), you can pretty much know at load time what resources you have (number of objects, materials, textures, etc.), so you can size your descriptor heap appropriately.  You can then add a a fixed maximum count to support room for dynamic objects that will be inserted/removed on the fly.  Descriptors don't cost much memory, so it wouldn't be a big deal to over allocate some extra heap space.  For more advanced scenarios, you can reuse heap space that you aren't using anymore.

 

For a level editor type application, I'd imagine you could grow heaps sort of the way vectors grow.

 

Another problem I have is: when you no longer require a given buffer, you no longer need its associated descriptor. So the best solution would be to reuse its location within the descriptor heap. But this requires me to implement some kind of advanced memory allocation algorithm, which I would like to avoid if possible...

 

I don't think it needs to be too advanced.  Just keep track of "free" descriptors and whenever you need a new descriptor, pull the next free one.  A lot of particle systems use a similar "recycling array" like this. 

 


Imagine I have a set of drawable objects, each of them having their own world transform. I would use a constant buffer (one for each object) to pass the associated matrices to the vertex shader. Allocating them is easy, as I only need to use the location right after the last descriptor I allocated on the heap. But when I delete one of these objects, is it my responsibility to make sure that the space that is no longer used will be reused for the next descriptor?

 

I didn't really follow your question.  The way I would assume you would do is allocate the cbuffer memory.  Then you need to allocate CBVs that live in a heap that reference subsets of that cbuffer memory.  If an object is deleted, it would be easiest to just flag that cbuffer memory region and CBV as free so it can be used the next time an object is created.  

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!