Jump to content
  • Advertisement
Sign in to follow this  
TomVeltmeijer

[D3D12] Overlapping descriptor heaps bug

This topic is 800 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

Hi everyone,
 
I get unexpected results when I call GetCPUDescriptorHandleForHeapStart() on certain descriptor heaps. The returned handle's ptr value is always 3 for the first heap that I create, 4 for the second heap, 5 for the next one, and so on. The size of a descriptor heap is obviously not just 1 byte, so this means that there's a lot of overlap between heaps. It was my understanding that this shouldn't be possible because descriptor handles should reference globally unique addresses (how else would functions like CopyDescriptors() work?).
 
This only happens with CBV_SRV_UAV and SAMPLER descriptor heaps, regardless of their shader visibility. Other types of descriptor heaps start at much larger addresses (e.g., 2029815602608) and their ranges don't overlap, which is what I would expect.
 
I don't experience this problem when I use WARP and/or enable the debug layer.
 
My system has a GTX 970 with driver version 365.10 installed. I tried a few older versions as well, but the results were the same.
 
Is this a driver bug or am I missing something here?

Share this post


Link to post
Share on other sites
Advertisement

There's no hard requirement that the descriptor handles have to be pointers, they just need to be globally unique values. This behavior is allowed, because it is not valid to use a CPU descriptor handle which doesn't follow the formula of (base + (n * increment)). So as long as you stick with that, this behavior works just fine.

Share this post


Link to post
Share on other sites

To find out if a descriptor belongs to a certain heap, I check the following condition:

ptr >= base && ptr < base + n * increment

What you're saying is that I should add the following constraint:

&& isMultipleOf(ptr - base, increment)

This would allow for interleaved descriptor heaps, which is what I'm seeing here.

 

The documentation doesn't say that heaps can be interleaved but it also doesn't say that they can't be, so I suppose my mistake was making an assumption.  :)

 

Thank you for your help.

Share this post


Link to post
Share on other sites

I had made the same assumption at one point in time, but it turned out to be an unnecessary (and incorrect) assumption. Out of curiosity, what's the reason for the attribution of handles -> heaps?

Share this post


Link to post
Share on other sites

For staging descriptors CPU-side, I wanted to make it really easy to create and destroy descriptors.

I have a class that internally has a list of descriptor heaps, which in turn have a list of free indices.

- When a descriptor is created, the class claims a free slot in any of its internal heaps. If all heaps are full, a new one is automatically created.

- When a descriptor is destroyed, the class determines the heap and index of the descriptor and marks the corresponding slot as free again.

Share this post


Link to post
Share on other sites

Yep, that's exactly what I did too. I ended up just keeping around a heap index as well as a heap slot. It was a few extra lines of code, an extra argument to a few functions, and 4 bytes of storage per object which had a descriptor reference, but it was a lot simpler since I didn't have to do the range lookup and probably ends up being faster too.

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!