VulkanSceneGraph icon indicating copy to clipboard operation
VulkanSceneGraph copied to clipboard

from Context.cpp: Warning: Context::reserve(const ResourceRequirements& requirements) invalid combination...

Open timoore opened this issue 2 years ago • 6 comments

While running vsgCs, I've recently started seeing this warning from Context.cpp: Warning: Context::reserve(const ResourceRequirements& requirements) invalid combination of required_maxSets (0) & required_descriptorPoolSizes (2) unable to allocate DescriptorPool.

I don't know this code well, but I think it means that all the existing descriptor pools have hit their limit on number of descriptor sets. Rendering is still working, as far as I can see.

Incidently, I was surprised that a new descriptor pool is allocated essentially for every BindDescriptorSet command. The common Vulkan usage is to a few large pools. I don't know if there's any real problem doing it the VSG way.

timoore avatar Sep 06 '23 18:09 timoore

I merged some fixes to the DescriptorPool manage for 1.0.9, the new warning is part of this, but perhaps there are regressions in there with some usage combinations.

The intention is that DecriptorPools can be used for many Descriptor/DescriptorSet, the design/implementation is for this to happen and only allocator new DescritotorPoll when existing ones are exhausted. There is also a reuse mechanism built in.

robertosfield avatar Sep 06 '23 20:09 robertosfield

I get the same thing, but can't see anything that isn't getting rendered. I have a lot of subgraphs being created and compiled in parallel threads after the initial viewer->compile(). I've put in a mutex to ensure that only one subgraph is compiled at any time, but it hasn't made any difference. I've also implemented a deferred delete operation (4 frames) to ensure that descriptors aren't deleted while still being used. I'm clutching at straws as I don't really understand how descriptor allocation works though.

Cheers, Roland

Warning: Context::reserve(const ResourceRequirements& requirements) invalid combination of required_maxSets (0) & required_descriptorPoolSizes (1) unable to allocate DescriptorPool. Warning: Context::reserve(const ResourceRequirements& requirements) invalid combination of required_maxSets (0) & required_descriptorPoolSizes (1) unable to allocate DescriptorPool. Warning: Context::reserve(const ResourceRequirements& requirements) invalid combination of required_maxSets (1) & required_descriptorPoolSizes (0) unable to allocate DescriptorPool. Warning: Context::reserve(const ResourceRequirements& requirements) invalid combination of required_maxSets (1) & required_descriptorPoolSizes (0) unable to allocate DescriptorPool. Warning: Context::reserve(const ResourceRequirements& requirements) invalid combination of required_maxSets (1) & required_descriptorPoolSizes (0) unable to allocate DescriptorPool. Warning: Context::reserve(const ResourceRequirements& requirements) invalid combination of required_maxSets (1) & required_descriptorPoolSizes (0) unable to allocate DescriptorPool. Warning: Context::reserve(const ResourceRequirements& requirements) invalid combination of required_maxSets (1) & required_descriptorPoolSizes (0) unable to allocate DescriptorPool.

rolandhill avatar Sep 06 '23 23:09 rolandhill

I put some debugging output into Context::reserve() and you can see an edited selection below. The warning appears when the reserve request is partially filled, ie we need zero maxSets or DescriptorPoolSizes, but not both. If the request can be filled from available resources then there is "Nothing to do" - if neither can be filled from available resources then it is "All OK".

Context::reserve() Requested: maxSets: 4 descriptorPoolSizes: 3 Available: maxSets: 0 descriptorPoolSizes: 0 Required: maxSets: 4 descriptorPoolSizes: 3 All OK

Context::reserve() Requested: maxSets: 0 descriptorPoolSizes: 0 Available: maxSets: 0 descriptorPoolSizes: 0 Required: maxSets: 0 descriptorPoolSizes: 0 Nothing to do

Context::reserve() Requested: maxSets: 1 descriptorPoolSizes: 3 Available: maxSets: 1 descriptorPoolSizes: 3 Required: maxSets: 0 descriptorPoolSizes: 0 Nothing to do

Context::reserve() Requested: maxSets: 1 descriptorPoolSizes: 4 Available: maxSets: 1 descriptorPoolSizes: 3 Required: maxSets: 0 descriptorPoolSizes: 1 Context::reserve(const ResourceRequirements& requirements) invalid combination of required_maxSets (0) & required_descriptorPoolSizes (1) unable to allocate DescriptorPool.

Context::reserve() Requested: maxSets: 0 descriptorPoolSizes: 0 Available: maxSets: 1 descriptorPoolSizes: 3 Required: maxSets: 0 descriptorPoolSizes: 0 Nothing to do

Context::reserve() Requested: maxSets: 2 descriptorPoolSizes: 3 Available: maxSets: 1 descriptorPoolSizes: 3 Required: maxSets: 1 descriptorPoolSizes: 0 Context::reserve(const ResourceRequirements& requirements) invalid combination of required_maxSets (1) & required_descriptorPoolSizes (0) unable to allocate DescriptorPool.

Context::reserve() Context::reserve() Requested: maxSets: 2 descriptorPoolSizes: 3 Available: maxSets: 1 descriptorPoolSizes: 3 Required: maxSets: 1 descriptorPoolSizes: 0 Context::reserve(const ResourceRequirements& requirements) invalid combination of required_maxSets (1) & required_descriptorPoolSizes (0) unable to allocate DescriptorPool.

Context::reserve() Requested: maxSets: 2 descriptorPoolSizes: 4 Available: maxSets: 1 descriptorPoolSizes: 3 Required: maxSets: 1 descriptorPoolSizes: 1 All OK

Context::reserve() Requested: maxSets: 1 descriptorPoolSizes: 4 Available: maxSets: 2 descriptorPoolSizes: 4 Required: maxSets: 0 descriptorPoolSizes: 0 Nothing to do

Context::reserve() Requested: maxSets: 2 descriptorPoolSizes: 3 Available: maxSets: 2 descriptorPoolSizes: 4 Required: maxSets: 0 descriptorPoolSizes: 0 Nothing to do

rolandhill avatar Sep 07 '23 02:09 rolandhill

Think it's fixed now. See PR https://github.com/vsg-dev/VulkanSceneGraph/pull/961

Cheers, Roland

rolandhill avatar Sep 07 '23 03:09 rolandhill

I merged some fixes to the DescriptorPool manage for 1.0.9, the new warning is part of this, but perhaps there are regressions in there with some usage combinations.

The intention is that DecriptorPools can be used for many Descriptor/DescriptorSet, the design/implementation is for this to happen and only allocator new DescritotorPoll when existing ones are exhausted. There is also a reuse mechanism built in.

The behavior I'm seeing -- allocation of many tiny DescriptorPool objects -- is probably an artifact of this compile traversal's use. It is only used to allocate descriptor sets for terrain tiles that have mostly been constructed (and compiled) in another thread. I also don't do any special initialization of this compile traversal's context. I'll experiment with giving it larger descriptor set and descriptor type requirements.

timoore avatar Sep 07 '23 07:09 timoore

I create the vsg::ResourceHints specifically to allow applications/scene graphs to be able to provide guidance on allocating memory and descriptor pools:

https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/ResourceHints.h

There is also the minimum maxSets and pool sizes in vsg::Context:

https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/vk/Context.h#L88

robertosfield avatar Sep 07 '23 07:09 robertosfield

This issue has been dealt with as part of rewrite of how vk/vsg::DescriptorPool are managed with the introduction of a new vsg::DescriptorPools class, merged with the PR #1239. I will now close this Issue.

robertosfield avatar Jul 17 '24 18:07 robertosfield