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

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

Open
timoore opened this issue Sep 6, 2023 · 6 comments

Comments

@timoore
Copy link
Contributor

timoore commented Sep 6, 2023

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.

@robertosfield
Copy link
Collaborator

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.

@rolandhill
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

Think it's fixed now. See PR #961

Cheers,
Roland

@timoore
Copy link
Contributor Author

timoore commented Sep 7, 2023

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.

@robertosfield
Copy link
Collaborator

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

theodoregoetz added a commit to theodoregoetz/VulkanSceneGraph that referenced this issue May 29, 2024
Following the discussions in vsg-dev#960 and vsg-dev#961 this sets the minimum maxSets to 1 so that when switching out graphics pipelines that use different descriptor sets, the warning about Context::reserve() is avoided
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants