Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StandardDescriptorSetAllocator handles layouts with high VariableDescriptorCount badly #2453

Open
Firestar99 opened this issue Jan 11, 2024 · 4 comments

Comments

@Firestar99
Copy link
Contributor

Firestar99 commented Jan 11, 2024

Template

  • Version of vulkano: current master (9b6e307)
  • OS: Ubuntu 23.10, KDE on Wayland
  • GPU:

Issue

I was messing about with VariableDescriptorCount, and noticed that the maximum amount of descriptors one can have in a set has to be declared when the PipelineLayout is created. As I want as many as possible, I've just passed in device.physical_device().properties().max_descriptor_set_sampled_images, which on RADV is 8388606 = 0x7ffffe and on AMDVLK is 4294967295 = 0xffffffff. If you then allocate a dynamically-sized descriptor set of any amount of elements, the StandardDescriptorSetAllocator will always pre-allocate layout.variable_descriptor_count() (just count below) * StandardDescriptorSetAllocatorCreateInfo::set_count (default 32) descriptors, even if you only asked for like 2 sampled_image descriptors.

(ty, count * create_info.set_count as u32)

  • On AMDVLK this multiplication overflows the u32.
  • On RADV, it will only allocate 0x7ffffe * 32 = 268435392 descriptors, to which the driver returns an out of device memory error.

You can test it by modifying this line in the runtime-array example from wanting at most 2 descriptors to device.physical_device().properties().max_descriptor_set_sampled_images:

binding.descriptor_count = 2;

@marc0246
Copy link
Contributor

Apart from the overflow, this is intended behavior. The number of preallocated sets is configurable for this reason: you're supposed to set it to 1 for bindless. But just asking for my understanding, what were you expecting setting the max count so high?

@marc0246
Copy link
Contributor

I guess we could add another option that limits the number of descriptors allocated, which would allow you to avoid recreating the layout?

@marc0246
Copy link
Contributor

For the record, StandardDescriptorSetAllocator is ill-suited for bindless, although you can sort of make it work. It's mostly intended for reusing a pool for multiple sets as you can probably tell. On the other hand, for bindless what you probably want is to allocate one pool per set, and have only one set at any point in time. I'm planning to implement that in vulkano in the near future, together with automatic descriptor management, if the user wants it.

@Firestar99
Copy link
Contributor Author

The number of preallocated sets is configurable for this reason: you're supposed to set it to 1 for bindless

Even if you were to do that, it'll still allocate 4294967295 descriptor sets on AMDVLK, likely still resulting in an out-of-device-memory.

I guess we could add another option that limits the number of descriptors allocated, which would allow you to avoid recreating the layout?

I think that's a quite reasonable solution to only allow it to pool a configurable amount of descriptors (like <=1024) and anything above that receiving a dedicated pool, akin to memory allocation.

For the record, StandardDescriptorSetAllocator is ill-suited for bindless

I pretty much expected having to write my own allocator down the line anyways, so I could see just leaving it as is as a viable solution for the moment, and I write my own allocator rather sooner than later :D

@Rua Rua added the type: bug label Jan 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants