#Is there much of a reason to NOT use push descriptors?

15 messages · Page 1 of 1 (latest)

torpid dagger
#

Hi all.

I'm currently writing an abstraction layer over Vulkan, DirectX 11/12, and OpenGL. I'm trying to work out if it's better to switch over to push descriptors. I currently have an abstraction for normal descriptor sets working, but I'm writing a Sprite batcher and the way these descriptor sets need to be managed is proving to be a bit of a pain.

It seems that Push Descriptors are supported on most major platforms, and also that they have comparable performance to regular descriptor sets.

So, is there much of a reason to NOT use push descriptors?

carmine wigeon
#

I don't have any reason not to, per se, but I would just say that I believe descriptor indexing (aka "bindless") is an even simpler solution

dawn ingot
#

I use push descriptors for my 2D drawing code, mostly because it's ported forward from an old GL/D3D11-based renderer and I like supporting older hardware. That said, descriptor indexing (if supported on your target platforms) will get you much larger batches, even if you do need to still manage a few descriptor sets.

#

What sort of pain are you having using normal descriptor sets, though? There are relatively straightforward ways to manage a small pool of descriptor pools, just as long as you can notify the managing component of where your app's frame boundaries are.

carmine wigeon
#

A well-made descriptor indexing setup should only ever need 1 set for the whole app

dawn ingot
#

Sure. But I'm the one guy on the server who doesn't hate having my code run on older GPUs. 😄

#

I'll let you advocate for bind-least.

torpid dagger
# dawn ingot What sort of pain are you having using normal descriptor sets, though? There are...

the main issue is switching between multiple textures. the sprite batcher will need to have a map of which textures map to which descriptor sets. i could store the descriptor sets in the texture instead, but that would also mean needing to store multiple sets per texture (as the same textures can be used in the 3D renderer as well). perhaps there's a better way to deal with this that i'm not aware of.

torpid dagger
carmine wigeon
#

Unfortunately I'm not sure about that, never used D3D11

torpid dagger
#

i'll look into it, thanks for the tip

dawn ingot
# torpid dagger the main issue is switching between multiple textures. the sprite batcher will n...

I do the following:

  • Materials (not textures, which can be referenced by more than one material) each have their own descriptor set.
  • For my 2D rendering I use push descriptors where they're available, and otherwise I just create and bind one-off descriptor sets with the "currently bound" textures right before a draw call (if they've changed since the last call). This works off a scheme where I just keep allocating more and more sets from a pool until it runs out of capacity (taking care not to fall into the "NV descriptor pools never run out of capacity" trap). Once the pool is exhausted, I start allocating from another one (either reusing a previously used pool or, if necessary, allocating a new one), and I put the empty pool in a queue. When the GPU finishes rendering the last frame a pool was used in it gets taken out of the queue, reset, and put into the list of pools to reuse the next time one fills up. (I use a similar approach for allocating and recycling things like uniform buffer space in the 3D scene.)
    Is it the optimalest thing one can do on current hardware? Lol, no. Does it even vaguely look like a performance problem on any profile? Also no. But that depends on what you're rendering, so YMMV.
torpid dagger
#

interesting. might look into doing something similar. right now i can't really do the descriptor pool thing as my abstraction has no concept of descriptor pools, and just has Device.CreateDescriptorSet from a descriptor layout. so it creates a new descriptor pool for each descriptor set, which i'm sure is not ideal

#

might look into changing how the implementation works so something like that is possible

dawn ingot
#

Yeah, that's the worst way to do it. The pools are there to amortize the cost of allocating the underlying descriptor memory, which is the expensive part.