From 7bc32c64caac1523b8bb2a87e468845a2765b2c2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 11 Jul 2024 11:46:24 +0100 Subject: [PATCH 01/23] Created dedicated vsg::DescriptorPools class --- include/vsg/vk/Context.h | 12 +-- include/vsg/vk/DescriptorPools.h | 45 +++++++++++ include/vsg/vk/Device.h | 4 +- src/vsg/CMakeLists.txt | 1 + src/vsg/vk/Context.cpp | 124 ++++++------------------------- src/vsg/vk/DescriptorPool.cpp | 30 +++++++- src/vsg/vk/Device.cpp | 1 + 7 files changed, 103 insertions(+), 114 deletions(-) create mode 100644 include/vsg/vk/DescriptorPools.h diff --git a/include/vsg/vk/Context.h b/include/vsg/vk/Context.h index 51bf078176..be3a7acda0 100644 --- a/include/vsg/vk/Context.h +++ b/include/vsg/vk/Context.h @@ -86,18 +86,14 @@ namespace vsg ref_ptr getOrCreateCommandBuffer(); - uint32_t minimum_maxSets = 0; - DescriptorPoolSizes minimum_descriptorPoolSizes; - /// get the maxSets and descriptorPoolSizes to use + /// reserve resources that may be needed during compile traversal. + void reserve(const ResourceRequirements& requirements); + void getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes); - /// allocate or reuse a DescriptorSet::Implementation from the available DescriptorPool ref_ptr allocateDescriptorSet(DescriptorSetLayout* descriptorSetLayout); - /// reserve resources that may be needed during compile traversal. - void reserve(const ResourceRequirements& requirements); - // used by GraphicsPipeline.cpp ref_ptr renderPass; @@ -114,7 +110,7 @@ namespace vsg GraphicsPipelineStates overridePipelineStates; // DescriptorPool - std::list> descriptorPools; + ref_ptr descriptorPools; // ShaderCompiler ref_ptr shaderCompiler; diff --git a/include/vsg/vk/DescriptorPools.h b/include/vsg/vk/DescriptorPools.h new file mode 100644 index 0000000000..2a5f664da4 --- /dev/null +++ b/include/vsg/vk/DescriptorPools.h @@ -0,0 +1,45 @@ +#pragma once + +/* + +Copyright(c) 2024 Robert Osfield + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + */ + +#include +#include +#include + +namespace vsg +{ + + class VSG_DECLSPEC DescriptorPools : public Inherit + { + public: + DescriptorPools(ref_ptr in_device, const ResourceRequirements& in_resourceRequirements = {}); + + ref_ptr device; + uint32_t minimum_maxSets = 0; + DescriptorPoolSizes minimum_descriptorPoolSizes; + std::list> descriptorPools; + + /// get the maxSets and descriptorPoolSizes to use + void getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes); + + void reserve(const ResourceRequirements& requirements); + + ref_ptr allocateDescriptorSet(DescriptorSetLayout* descriptorSetLayout); + + + protected: + virtual ~DescriptorPools(); + }; + VSG_type_name(vsg::DescriptorPools); + +} // namespace vsg diff --git a/include/vsg/vk/Device.h b/include/vsg/vk/Device.h index e2f7772c18..005bf7dd84 100644 --- a/include/vsg/vk/Device.h +++ b/include/vsg/vk/Device.h @@ -24,6 +24,7 @@ namespace vsg // forward declare class WindowTraits; class MemoryBufferPools; + class DescriptorPools; struct QueueSetting { @@ -83,9 +84,10 @@ namespace vsg /// return true if Device was created with specified extension bool supportsDeviceExtension(const char* extensionName) const; - // provide observer_ptr to memory buffer pools so that these can be accessed when required + // provide observer_ptr to memory buffer and descriptor pools so that these can be accessed when required observer_ptr deviceMemoryBufferPools; observer_ptr stagingMemoryBufferPools; + observer_ptr descriptorPools; protected: virtual ~Device(); diff --git a/src/vsg/CMakeLists.txt b/src/vsg/CMakeLists.txt index 287b8b4459..9cf8c22921 100644 --- a/src/vsg/CMakeLists.txt +++ b/src/vsg/CMakeLists.txt @@ -221,6 +221,7 @@ set(SOURCES vk/CommandPool.cpp vk/Context.cpp vk/DescriptorPool.cpp + vk/DescriptorPools.cpp vk/Device.cpp vk/DeviceFeatures.cpp vk/DeviceMemory.cpp diff --git a/src/vsg/vk/Context.cpp b/src/vsg/vk/Context.cpp index ba4813280b..9cf7bc60cd 100644 --- a/src/vsg/vk/Context.cpp +++ b/src/vsg/vk/Context.cpp @@ -24,6 +24,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include +#include #include #include #include @@ -94,11 +95,11 @@ Context::Context(Device* in_device, const ResourceRequirements& in_resourceRequi //semaphore = vsg::Semaphore::create(device); scratchMemory = ScratchMemory::create(4096); - minimum_maxSets = in_resourceRequirements.computeNumDescriptorSets(); - minimum_descriptorPoolSizes = in_resourceRequirements.computeDescriptorPoolSizes(); + vsg::info("Context::Context() ", this); deviceMemoryBufferPools = device->deviceMemoryBufferPools.ref_ptr(); stagingMemoryBufferPools = device->stagingMemoryBufferPools.ref_ptr(); + descriptorPools = device->descriptorPools.ref_ptr(); if (!deviceMemoryBufferPools) { @@ -119,6 +120,16 @@ Context::Context(Device* in_device, const ResourceRequirements& in_resourceRequi { vsg::debug("Context::Context() reusing stagingMemoryBufferPools = ", stagingMemoryBufferPools); } + + if (!descriptorPools) + { + device->descriptorPools = descriptorPools = DescriptorPools::create(device, in_resourceRequirements); + vsg::info("Context::Context() creating new descriptorPools = ", descriptorPools); + } + else + { + vsg::info("Context::Context() reusing descriptorPools = ", descriptorPools); + } } Context::Context(const Context& context) : @@ -129,8 +140,6 @@ Context::Context(const Context& context) : viewID(context.viewID), mask(context.mask), viewDependentState(context.viewDependentState), - minimum_maxSets(context.minimum_maxSets), - minimum_descriptorPoolSizes(context.minimum_descriptorPoolSizes), renderPass(context.renderPass), defaultPipelineStates(context.defaultPipelineStates), overridePipelineStates(context.overridePipelineStates), @@ -176,57 +185,6 @@ ShaderCompiler* Context::getOrCreateShaderCompiler() return shaderCompiler; } -void Context::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes) -{ - CPU_INSTRUMENTATION_L2_NC(instrumentation, "Context getDescriptorPoolSizesToUse", COLOR_COMPILE) - - if (minimum_maxSets > maxSets) - { - maxSets = minimum_maxSets; - } - - for (auto& [minimum_type, minimum_descriptorCount] : minimum_descriptorPoolSizes) - { - auto itr = descriptorPoolSizes.begin(); - for (; itr != descriptorPoolSizes.end(); ++itr) - { - if (itr->type == minimum_type) - { - if (minimum_descriptorCount > itr->descriptorCount) - itr->descriptorCount = minimum_descriptorCount; - break; - } - } - if (itr == descriptorPoolSizes.end()) - { - descriptorPoolSizes.push_back(VkDescriptorPoolSize{minimum_type, minimum_descriptorCount}); - } - } -} - -ref_ptr Context::allocateDescriptorSet(DescriptorSetLayout* descriptorSetLayout) -{ - CPU_INSTRUMENTATION_L2_NC(instrumentation, "Context allocateDescriptorSet", COLOR_COMPILE) - - for (auto itr = descriptorPools.rbegin(); itr != descriptorPools.rend(); ++itr) - { - auto dsi = (*itr)->allocateDescriptorSet(descriptorSetLayout); - if (dsi) return dsi; - } - - DescriptorPoolSizes descriptorPoolSizes; - descriptorSetLayout->getDescriptorPoolSizes(descriptorPoolSizes); - - uint32_t maxSets = 1; - getDescriptorPoolSizesToUse(maxSets, descriptorPoolSizes); - - auto descriptorPool = vsg::DescriptorPool::create(device, maxSets, descriptorPoolSizes); - auto dsi = descriptorPool->allocateDescriptorSet(descriptorSetLayout); - - descriptorPools.push_back(descriptorPool); - return dsi; -} - void Context::reserve(const ResourceRequirements& requirements) { CPU_INSTRUMENTATION_L2_NC(instrumentation, "Context reserve", COLOR_COMPILE) @@ -236,55 +194,17 @@ void Context::reserve(const ResourceRequirements& requirements) resourceRequirements.maxSlot = requirements.maxSlot; } - auto maxSets = requirements.computeNumDescriptorSets(); - auto descriptorPoolSizes = requirements.computeDescriptorPoolSizes(); - - uint32_t available_maxSets = 0; - DescriptorPoolSizes available_descriptorPoolSizes; - for (auto& descriptorPool : descriptorPools) - { - descriptorPool->getAvailability(available_maxSets, available_descriptorPoolSizes); - } - - auto required_maxSets = maxSets; - if (available_maxSets < required_maxSets) - required_maxSets -= available_maxSets; - else - required_maxSets = 0; + descriptorPools->reserve(requirements); +} - DescriptorPoolSizes required_descriptorPoolSizes; - for (const auto& [type, descriptorCount] : descriptorPoolSizes) - { - uint32_t adjustedDescriptorCount = descriptorCount; - for (auto itr = available_descriptorPoolSizes.begin(); itr != available_descriptorPoolSizes.end(); ++itr) - { - if (itr->type == type) - { - if (itr->descriptorCount < adjustedDescriptorCount) - adjustedDescriptorCount -= itr->descriptorCount; - else - { - adjustedDescriptorCount = 0; - break; - } - } - } - if (adjustedDescriptorCount > 0) - required_descriptorPoolSizes.push_back(VkDescriptorPoolSize{type, adjustedDescriptorCount}); - } +void Context::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes) +{ + return descriptorPools->getDescriptorPoolSizesToUse(maxSets, descriptorPoolSizes); +} - if (required_maxSets > 0 || !required_descriptorPoolSizes.empty()) - { - getDescriptorPoolSizesToUse(required_maxSets, required_descriptorPoolSizes); - if (required_maxSets > 0 && !required_descriptorPoolSizes.empty()) - { - descriptorPools.push_back(vsg::DescriptorPool::create(device, required_maxSets, required_descriptorPoolSizes)); - } - else - { - warn("Context::reserve(const ResourceRequirements& requirements) invalid combination of required_maxSets (", required_maxSets, ") & required_descriptorPoolSizes (", required_descriptorPoolSizes.size(), ") unable to allocate DescriptorPool."); - } - } +ref_ptr Context::allocateDescriptorSet(DescriptorSetLayout* descriptorSetLayout) +{ + return descriptorPools->allocateDescriptorSet(descriptorSetLayout); } void Context::copy(ref_ptr data, ref_ptr dest) diff --git a/src/vsg/vk/DescriptorPool.cpp b/src/vsg/vk/DescriptorPool.cpp index d6637f5e99..0f4f75d7d4 100644 --- a/src/vsg/vk/DescriptorPool.cpp +++ b/src/vsg/vk/DescriptorPool.cpp @@ -21,6 +21,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI using namespace vsg; +static size_t s_numDescriptorPools = 0; + DescriptorPool::DescriptorPool(Device* device, uint32_t maxSets, const DescriptorPoolSizes& descriptorPoolSizes) : _device(device), _availableDescriptorSet(maxSets), @@ -38,6 +40,13 @@ DescriptorPool::DescriptorPool(Device* device, uint32_t maxSets, const Descripto { throw Exception{"Error: Failed to create DescriptorPool.", result}; } + + ++s_numDescriptorPools; + vsg::info("DescriptorPool::DescriptorPool( ", this, ", maxSets = ", maxSets, ", descriptorPoolSizes.size() = ", descriptorPoolSizes.size(), " ) s_numDescriptorPools = ", s_numDescriptorPools); + for(const auto& dps : descriptorPoolSizes) + { + vsg::info(" { ", dps.type, ", ", dps.descriptorCount, " }"); + } } DescriptorPool::~DescriptorPool() @@ -46,6 +55,9 @@ DescriptorPool::~DescriptorPool() { vkDestroyDescriptorPool(*_device, _descriptorPool, _device->getAllocationCallbacks()); } + + --s_numDescriptorPools; + vsg::info("DescriptorPool::~DescriptorPool( ", this, " ) s_numDescriptorPools = ", s_numDescriptorPools); } ref_ptr DescriptorPool::allocateDescriptorSet(DescriptorSetLayout* descriptorSetLayout) @@ -57,6 +69,18 @@ ref_ptr DescriptorPool::allocateDescriptorSet(Des return {}; } + // debug code + { + vsg::info("DescriptorPool::allocateDescriptorSet( ", descriptorSetLayout, ") "); + + DescriptorPoolSizes descriptorPoolSizes; + descriptorSetLayout->getDescriptorPoolSizes(descriptorPoolSizes); + for(const auto& dps : descriptorPoolSizes) + { + vsg::info(" { ", dps.type, ", ", dps.descriptorCount, " }"); + } + } + for (auto itr = _recyclingList.begin(); itr != _recyclingList.end(); ++itr) { auto dsi = *itr; @@ -65,14 +89,14 @@ ref_ptr DescriptorPool::allocateDescriptorSet(Des dsi->_descriptorPool = this; _recyclingList.erase(itr); --_availableDescriptorSet; - // debug("DescriptorPool::allocateDescriptorSet(..) reusing ", dsi) ; + vsg::info("DescriptorPool::allocateDescriptorSet(..) reusing ", dsi) ; return dsi; } } if (_availableDescriptorSet == _recyclingList.size()) { - //debug("The only available vkDescriptorSets associated with DescriptorPool are in the recyclingList, but none are compatible."); + vsg::info("The only available vkDescriptorSets associated with DescriptorPool are in the recyclingList, but none are compatible."); return {}; } @@ -102,7 +126,7 @@ ref_ptr DescriptorPool::allocateDescriptorSet(Des --_availableDescriptorSet; auto dsi = DescriptorSet::Implementation::create(this, descriptorSetLayout); - //debug("DescriptorPool::allocateDescriptorSet(..) allocated ", dsi); + vsg::info("DescriptorPool::allocateDescriptorSet(..) allocated new ", dsi); return dsi; } diff --git a/src/vsg/vk/Device.cpp b/src/vsg/vk/Device.cpp index 96f9fe31b3..3fade05dde 100644 --- a/src/vsg/vk/Device.cpp +++ b/src/vsg/vk/Device.cpp @@ -16,6 +16,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include +#include #include #include From 11af206aa73bddd91fe15362607f958e99afdb8d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 11 Jul 2024 11:53:16 +0100 Subject: [PATCH 02/23] Added DescriptorPools.cpp --- src/vsg/vk/DescriptorPools.cpp | 150 +++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 src/vsg/vk/DescriptorPools.cpp diff --git a/src/vsg/vk/DescriptorPools.cpp b/src/vsg/vk/DescriptorPools.cpp new file mode 100644 index 0000000000..4440d97536 --- /dev/null +++ b/src/vsg/vk/DescriptorPools.cpp @@ -0,0 +1,150 @@ +/* + +Copyright(c) 2024 Robert Osfield + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + */ + +#include +#include +#include + +using namespace vsg; + +#define ROLAND_HILL_FIX 0 + +DescriptorPools::DescriptorPools(ref_ptr in_device, const ResourceRequirements& in_resourceRequirements) : + device(in_device) +{ + vsg::info("DescriptorPools::DescriptorPools() ", this); + + minimum_maxSets = in_resourceRequirements.computeNumDescriptorSets(); + minimum_descriptorPoolSizes = in_resourceRequirements.computeDescriptorPoolSizes(); + + vsg::info(" minimum_maxSets = ", minimum_maxSets); + vsg::info(" minimum_descriptorPoolSizes.size() = ", minimum_descriptorPoolSizes.size()); +} + +DescriptorPools::~DescriptorPools() +{ + vsg::info("DescriptorPools::~DescriptorPools() ", this); +} + + +void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes) +{ + vsg::info("descriptorPools::getDescriptorPoolSizesToUse(", maxSets, ", ", descriptorPoolSizes.size(), ") in "); + + if (minimum_maxSets > maxSets) + { + maxSets = minimum_maxSets; + } + +#if ROLAND_HILL_FIX + maxSets = std::max(1u, maxSets); +#endif + + for (auto& [minimum_type, minimum_descriptorCount] : minimum_descriptorPoolSizes) + { + auto itr = descriptorPoolSizes.begin(); + for (; itr != descriptorPoolSizes.end(); ++itr) + { + if (itr->type == minimum_type) + { + if (minimum_descriptorCount > itr->descriptorCount) + itr->descriptorCount = minimum_descriptorCount; + break; + } + } + if (itr == descriptorPoolSizes.end()) + { + descriptorPoolSizes.push_back(VkDescriptorPoolSize{minimum_type, minimum_descriptorCount}); + } + } +} + +void DescriptorPools::reserve(const ResourceRequirements& requirements) +{ + auto maxSets = requirements.computeNumDescriptorSets(); + auto descriptorPoolSizes = requirements.computeDescriptorPoolSizes(); + + uint32_t available_maxSets = 0; + DescriptorPoolSizes available_descriptorPoolSizes; + for (auto& descriptorPool : descriptorPools) + { + descriptorPool->getAvailability(available_maxSets, available_descriptorPoolSizes); + } + + auto required_maxSets = maxSets; + if (available_maxSets < required_maxSets) + required_maxSets -= available_maxSets; + else + required_maxSets = 0; + + DescriptorPoolSizes required_descriptorPoolSizes; + for (const auto& [type, descriptorCount] : descriptorPoolSizes) + { + uint32_t adjustedDescriptorCount = descriptorCount; + for (auto itr = available_descriptorPoolSizes.begin(); itr != available_descriptorPoolSizes.end(); ++itr) + { + if (itr->type == type) + { + if (itr->descriptorCount < adjustedDescriptorCount) + adjustedDescriptorCount -= itr->descriptorCount; + else + { + adjustedDescriptorCount = 0; + break; + } + } + } + if (adjustedDescriptorCount > 0) + required_descriptorPoolSizes.push_back(VkDescriptorPoolSize{type, adjustedDescriptorCount}); + } + + if (required_maxSets > 0 || !required_descriptorPoolSizes.empty()) + { + getDescriptorPoolSizesToUse(required_maxSets, required_descriptorPoolSizes); +#if ROLAND_HILL_FIX + if (required_maxSets > 0 || !required_descriptorPoolSizes.empty()) +#else + if (required_maxSets > 0 && !required_descriptorPoolSizes.empty()) +#endif + { + descriptorPools.push_back(vsg::DescriptorPool::create(device, required_maxSets, required_descriptorPoolSizes)); + } + else + { + warn("Context::reserve(const ResourceRequirements& requirements) invalid combination of required_maxSets (", required_maxSets, ") & required_descriptorPoolSizes (", required_descriptorPoolSizes.size(), ") unable to allocate DescriptorPool."); + } + } +} + + +ref_ptr DescriptorPools::allocateDescriptorSet(DescriptorSetLayout* descriptorSetLayout) +{ + for (auto itr = descriptorPools.rbegin(); itr != descriptorPools.rend(); ++itr) + { + auto dsi = (*itr)->allocateDescriptorSet(descriptorSetLayout); + if (dsi) return dsi; + } + + DescriptorPoolSizes descriptorPoolSizes; + descriptorSetLayout->getDescriptorPoolSizes(descriptorPoolSizes); + + uint32_t maxSets = 1; + getDescriptorPoolSizesToUse(maxSets, descriptorPoolSizes); + + auto descriptorPool = vsg::DescriptorPool::create(device, maxSets, descriptorPoolSizes); + auto dsi = descriptorPool->allocateDescriptorSet(descriptorSetLayout); + + descriptorPools.push_back(descriptorPool); + return dsi; +} + + From c83fd5593abc02092f36b31e0ec0adbeebdb9fe8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 11 Jul 2024 19:13:02 +0100 Subject: [PATCH 03/23] Further refinements --- include/vsg/vk/Context.h | 2 -- include/vsg/vk/DescriptorPools.h | 7 +++--- src/vsg/vk/Context.cpp | 10 ++------ src/vsg/vk/DescriptorPools.cpp | 40 ++++++++++++++++---------------- 4 files changed, 25 insertions(+), 34 deletions(-) diff --git a/include/vsg/vk/Context.h b/include/vsg/vk/Context.h index be3a7acda0..e0eb40b068 100644 --- a/include/vsg/vk/Context.h +++ b/include/vsg/vk/Context.h @@ -90,8 +90,6 @@ namespace vsg /// reserve resources that may be needed during compile traversal. void reserve(const ResourceRequirements& requirements); - void getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes); - ref_ptr allocateDescriptorSet(DescriptorSetLayout* descriptorSetLayout); // used by GraphicsPipeline.cpp diff --git a/include/vsg/vk/DescriptorPools.h b/include/vsg/vk/DescriptorPools.h index 2a5f664da4..47506b817e 100644 --- a/include/vsg/vk/DescriptorPools.h +++ b/include/vsg/vk/DescriptorPools.h @@ -29,16 +29,15 @@ namespace vsg DescriptorPoolSizes minimum_descriptorPoolSizes; std::list> descriptorPools; - /// get the maxSets and descriptorPoolSizes to use - void getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes); - void reserve(const ResourceRequirements& requirements); ref_ptr allocateDescriptorSet(DescriptorSetLayout* descriptorSetLayout); - protected: virtual ~DescriptorPools(); + + /// get the maxSets and descriptorPoolSizes to use + void getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes); }; VSG_type_name(vsg::DescriptorPools); diff --git a/src/vsg/vk/Context.cpp b/src/vsg/vk/Context.cpp index 9cf7bc60cd..1bb6265109 100644 --- a/src/vsg/vk/Context.cpp +++ b/src/vsg/vk/Context.cpp @@ -98,9 +98,6 @@ Context::Context(Device* in_device, const ResourceRequirements& in_resourceRequi vsg::info("Context::Context() ", this); deviceMemoryBufferPools = device->deviceMemoryBufferPools.ref_ptr(); - stagingMemoryBufferPools = device->stagingMemoryBufferPools.ref_ptr(); - descriptorPools = device->descriptorPools.ref_ptr(); - if (!deviceMemoryBufferPools) { device->deviceMemoryBufferPools = deviceMemoryBufferPools = MemoryBufferPools::create("Device_MemoryBufferPool", device, in_resourceRequirements); @@ -111,6 +108,7 @@ Context::Context(Device* in_device, const ResourceRequirements& in_resourceRequi vsg::debug("Context::Context() reusing deviceMemoryBufferPools = ", deviceMemoryBufferPools); } + stagingMemoryBufferPools = device->stagingMemoryBufferPools.ref_ptr(); if (!stagingMemoryBufferPools) { device->stagingMemoryBufferPools = stagingMemoryBufferPools = MemoryBufferPools::create("Staging_MemoryBufferPool", device, in_resourceRequirements); @@ -121,6 +119,7 @@ Context::Context(Device* in_device, const ResourceRequirements& in_resourceRequi vsg::debug("Context::Context() reusing stagingMemoryBufferPools = ", stagingMemoryBufferPools); } + descriptorPools = device->descriptorPools.ref_ptr(); if (!descriptorPools) { device->descriptorPools = descriptorPools = DescriptorPools::create(device, in_resourceRequirements); @@ -197,11 +196,6 @@ void Context::reserve(const ResourceRequirements& requirements) descriptorPools->reserve(requirements); } -void Context::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes) -{ - return descriptorPools->getDescriptorPoolSizesToUse(maxSets, descriptorPoolSizes); -} - ref_ptr Context::allocateDescriptorSet(DescriptorSetLayout* descriptorSetLayout) { return descriptorPools->allocateDescriptorSet(descriptorSetLayout); diff --git a/src/vsg/vk/DescriptorPools.cpp b/src/vsg/vk/DescriptorPools.cpp index 4440d97536..219dd697c4 100644 --- a/src/vsg/vk/DescriptorPools.cpp +++ b/src/vsg/vk/DescriptorPools.cpp @@ -23,7 +23,7 @@ DescriptorPools::DescriptorPools(ref_ptr in_device, const ResourceRequir { vsg::info("DescriptorPools::DescriptorPools() ", this); - minimum_maxSets = in_resourceRequirements.computeNumDescriptorSets(); + minimum_maxSets = std::max(1u, in_resourceRequirements.computeNumDescriptorSets()); minimum_descriptorPoolSizes = in_resourceRequirements.computeDescriptorPoolSizes(); vsg::info(" minimum_maxSets = ", minimum_maxSets); @@ -38,17 +38,13 @@ DescriptorPools::~DescriptorPools() void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes) { - vsg::info("descriptorPools::getDescriptorPoolSizesToUse(", maxSets, ", ", descriptorPoolSizes.size(), ") in "); + vsg::info("DescriptorPools::getDescriptorPoolSizesToUse(", maxSets, ", ", descriptorPoolSizes.size(), ") in "); if (minimum_maxSets > maxSets) { maxSets = minimum_maxSets; } -#if ROLAND_HILL_FIX - maxSets = std::max(1u, maxSets); -#endif - for (auto& [minimum_type, minimum_descriptorCount] : minimum_descriptorPoolSizes) { auto itr = descriptorPoolSizes.begin(); @@ -66,6 +62,12 @@ void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorP descriptorPoolSizes.push_back(VkDescriptorPoolSize{minimum_type, minimum_descriptorCount}); } } + + vsg::info(" maxSets = ", maxSets); + for(const auto& dps : descriptorPoolSizes) + { + vsg::info(" { ", dps.type, ", ", dps.descriptorCount, " }"); + } } void DescriptorPools::reserve(const ResourceRequirements& requirements) @@ -107,33 +109,31 @@ void DescriptorPools::reserve(const ResourceRequirements& requirements) required_descriptorPoolSizes.push_back(VkDescriptorPoolSize{type, adjustedDescriptorCount}); } - if (required_maxSets > 0 || !required_descriptorPoolSizes.empty()) + // check if all the requirements have been met by exisiting availability + if (required_maxSets==0 && required_descriptorPoolSizes.empty()) { - getDescriptorPoolSizesToUse(required_maxSets, required_descriptorPoolSizes); -#if ROLAND_HILL_FIX - if (required_maxSets > 0 || !required_descriptorPoolSizes.empty()) -#else - if (required_maxSets > 0 && !required_descriptorPoolSizes.empty()) -#endif - { - descriptorPools.push_back(vsg::DescriptorPool::create(device, required_maxSets, required_descriptorPoolSizes)); - } - else - { - warn("Context::reserve(const ResourceRequirements& requirements) invalid combination of required_maxSets (", required_maxSets, ") & required_descriptorPoolSizes (", required_descriptorPoolSizes.size(), ") unable to allocate DescriptorPool."); - } + vsg::info("DescriptorPools::reserve(const ResourceRequirements& requirements) enought resource in existing DescriptorPools"); + return; } + + // not enough descriptor resources available so allocator new DescriptorPool. + getDescriptorPoolSizesToUse(required_maxSets, required_descriptorPoolSizes); + descriptorPools.push_back(vsg::DescriptorPool::create(device, required_maxSets, required_descriptorPoolSizes)); } ref_ptr DescriptorPools::allocateDescriptorSet(DescriptorSetLayout* descriptorSetLayout) { + vsg::info("DescriptorPools::allocateDescriptorSet( ", descriptorSetLayout, " ) ", this, ", descriptorPools.size() = ", descriptorPools.size()); for (auto itr = descriptorPools.rbegin(); itr != descriptorPools.rend(); ++itr) { auto dsi = (*itr)->allocateDescriptorSet(descriptorSetLayout); + vsg::info(" DescriptorPool::allocateDescriptorSet( ", descriptorSetLayout, " ) dsi = ", dsi); if (dsi) return dsi; } + vsg::info(" Falling back to creating new DescriptorPool"); + DescriptorPoolSizes descriptorPoolSizes; descriptorSetLayout->getDescriptorPoolSizes(descriptorPoolSizes); From ab2b247cbc2c153fb7ca3e2a5f1a37e4c97601d1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 13 Jul 2024 18:40:21 +0100 Subject: [PATCH 04/23] Added output of the number of vkDescrtiptorSet allocated. Added comments explaining function and cleaned up code. --- src/vsg/state/DescriptorSet.cpp | 7 +++++++ src/vsg/vk/DescriptorPool.cpp | 11 +++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/vsg/state/DescriptorSet.cpp b/src/vsg/state/DescriptorSet.cpp index bdf9b4579d..15e233a117 100644 --- a/src/vsg/state/DescriptorSet.cpp +++ b/src/vsg/state/DescriptorSet.cpp @@ -19,6 +19,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI using namespace vsg; +static size_t s_numDescriptorSets = 0; + DescriptorSet::DescriptorSet() { } @@ -122,15 +124,20 @@ DescriptorSet::Implementation::Implementation(DescriptorPool* descriptorPool, De { throw Exception{"Error: Failed to create DescriptorSet.", result}; } + + ++s_numDescriptorSets; + vsg::info("DescriptorSet::Implementation::Implementation() ", this, ", descriptorPool = ", descriptorPool, " s_numDescriptorSets = ", s_numDescriptorSets); } DescriptorSet::Implementation::~Implementation() { + --s_numDescriptorSets; if (_descriptorPool && _descriptorSet) { std::scoped_lock lock(_descriptorPool->mutex); vkFreeDescriptorSets(*(_descriptorPool->getDevice()), *_descriptorPool, 1, &_descriptorSet); } + vsg::info("DescriptorSet::Implementation::~Implementation() ", this, ", _descriptorPool = ", _descriptorPool, " s_numDescriptorSets = ", s_numDescriptorSets); } void DescriptorSet::Implementation::assign(Context& context, const Descriptors& in_descriptors) diff --git a/src/vsg/vk/DescriptorPool.cpp b/src/vsg/vk/DescriptorPool.cpp index 0f4f75d7d4..d080e232b3 100644 --- a/src/vsg/vk/DescriptorPool.cpp +++ b/src/vsg/vk/DescriptorPool.cpp @@ -86,6 +86,7 @@ ref_ptr DescriptorPool::allocateDescriptorSet(Des auto dsi = *itr; if (dsi->_descriptorSetLayout.get() == descriptorSetLayout || compare_value_container(dsi->_descriptorSetLayout->bindings, descriptorSetLayout->bindings) == 0) { + // swap ownership so that DescriptorSet::Implementation now "has a" reference to this DescriptorPool dsi->_descriptorPool = this; _recyclingList.erase(itr); --_availableDescriptorSet; @@ -132,12 +133,10 @@ ref_ptr DescriptorPool::allocateDescriptorSet(Des void DescriptorPool::freeDescriptorSet(ref_ptr dsi) { - { - std::scoped_lock lock(mutex); - _recyclingList.push_back(dsi); - ++_availableDescriptorSet; - } - + // swap ownership so that DescriptorSet::Implementation' reference is reset to null and while this DescriptorPool takes a refernece to it. + std::scoped_lock lock(mutex); + _recyclingList.push_back(dsi); + ++_availableDescriptorSet; dsi->_descriptorPool = {}; } From 6c6a694f7bf5dea3448e417522b149a15c214965 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 15 Jul 2024 14:42:15 +0100 Subject: [PATCH 05/23] Removed no longer used define --- src/vsg/vk/DescriptorPools.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vsg/vk/DescriptorPools.cpp b/src/vsg/vk/DescriptorPools.cpp index 219dd697c4..85f74c5f25 100644 --- a/src/vsg/vk/DescriptorPools.cpp +++ b/src/vsg/vk/DescriptorPools.cpp @@ -16,8 +16,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI using namespace vsg; -#define ROLAND_HILL_FIX 0 - DescriptorPools::DescriptorPools(ref_ptr in_device, const ResourceRequirements& in_resourceRequirements) : device(in_device) { From 9bc5a06f3ea31732843ef1e4413db0e9b57fffba Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 15 Jul 2024 18:10:21 +0100 Subject: [PATCH 06/23] Added report() methods and removed/quietened down debug outpu --- include/vsg/vk/DescriptorPool.h | 9 +++- include/vsg/vk/DescriptorPools.h | 2 + src/vsg/state/DescriptorSet.cpp | 7 --- src/vsg/vk/Context.cpp | 6 +-- src/vsg/vk/DescriptorPool.cpp | 81 +++++++++++++++++++++----------- src/vsg/vk/DescriptorPools.cpp | 49 +++++++++++-------- 6 files changed, 96 insertions(+), 58 deletions(-) diff --git a/include/vsg/vk/DescriptorPool.h b/include/vsg/vk/DescriptorPool.h index 92d4675f05..efba0b514a 100644 --- a/include/vsg/vk/DescriptorPool.h +++ b/include/vsg/vk/DescriptorPool.h @@ -13,6 +13,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI */ #include +#include namespace vsg { @@ -21,7 +22,7 @@ namespace vsg class VSG_DECLSPEC DescriptorPool : public Inherit { public: - DescriptorPool(Device* device, uint32_t maxSets, const DescriptorPoolSizes& descriptorPoolSizes); + DescriptorPool(Device* device, uint32_t in_maxSets, const DescriptorPoolSizes& in_descriptorPoolSizes); operator VkDescriptorPool() const { return _descriptorPool; } VkDescriptorPool vk() const { return _descriptorPool; } @@ -38,6 +39,12 @@ namespace vsg /// get the stats of the available DescriptorSets/Descriptors bool getAvailability(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes) const; + /// write the internal details to stream. + void report(std::ostream& out, indentation indent = {}) const; + + const uint32_t maxSets = 0; + const DescriptorPoolSizes descriptorPoolSizes; + /// mutex used to ensure thread safe access of DescriptorPool resources. /// Locked automatically by allocateDescriptorSet(..), freeDescriptorSet(), getAvailability() and DescriptorSet:::Implementation /// to ensure thread safe operation. Normal VulkanSceneGraph usage will not require users to lock this mutex so treat as an internal implementation detail. diff --git a/include/vsg/vk/DescriptorPools.h b/include/vsg/vk/DescriptorPools.h index 47506b817e..85c3b45d99 100644 --- a/include/vsg/vk/DescriptorPools.h +++ b/include/vsg/vk/DescriptorPools.h @@ -33,6 +33,8 @@ namespace vsg ref_ptr allocateDescriptorSet(DescriptorSetLayout* descriptorSetLayout); + void report(std::ostream& out, indentation indent = {}) const; + protected: virtual ~DescriptorPools(); diff --git a/src/vsg/state/DescriptorSet.cpp b/src/vsg/state/DescriptorSet.cpp index 15e233a117..bdf9b4579d 100644 --- a/src/vsg/state/DescriptorSet.cpp +++ b/src/vsg/state/DescriptorSet.cpp @@ -19,8 +19,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI using namespace vsg; -static size_t s_numDescriptorSets = 0; - DescriptorSet::DescriptorSet() { } @@ -124,20 +122,15 @@ DescriptorSet::Implementation::Implementation(DescriptorPool* descriptorPool, De { throw Exception{"Error: Failed to create DescriptorSet.", result}; } - - ++s_numDescriptorSets; - vsg::info("DescriptorSet::Implementation::Implementation() ", this, ", descriptorPool = ", descriptorPool, " s_numDescriptorSets = ", s_numDescriptorSets); } DescriptorSet::Implementation::~Implementation() { - --s_numDescriptorSets; if (_descriptorPool && _descriptorSet) { std::scoped_lock lock(_descriptorPool->mutex); vkFreeDescriptorSets(*(_descriptorPool->getDevice()), *_descriptorPool, 1, &_descriptorSet); } - vsg::info("DescriptorSet::Implementation::~Implementation() ", this, ", _descriptorPool = ", _descriptorPool, " s_numDescriptorSets = ", s_numDescriptorSets); } void DescriptorSet::Implementation::assign(Context& context, const Descriptors& in_descriptors) diff --git a/src/vsg/vk/Context.cpp b/src/vsg/vk/Context.cpp index 1bb6265109..07db5b376f 100644 --- a/src/vsg/vk/Context.cpp +++ b/src/vsg/vk/Context.cpp @@ -95,7 +95,7 @@ Context::Context(Device* in_device, const ResourceRequirements& in_resourceRequi //semaphore = vsg::Semaphore::create(device); scratchMemory = ScratchMemory::create(4096); - vsg::info("Context::Context() ", this); + vsg::debug("Context::Context() ", this); deviceMemoryBufferPools = device->deviceMemoryBufferPools.ref_ptr(); if (!deviceMemoryBufferPools) @@ -123,11 +123,11 @@ Context::Context(Device* in_device, const ResourceRequirements& in_resourceRequi if (!descriptorPools) { device->descriptorPools = descriptorPools = DescriptorPools::create(device, in_resourceRequirements); - vsg::info("Context::Context() creating new descriptorPools = ", descriptorPools); + vsg::debug("Context::Context() creating new descriptorPools = ", descriptorPools); } else { - vsg::info("Context::Context() reusing descriptorPools = ", descriptorPools); + vsg::debug("Context::Context() reusing descriptorPools = ", descriptorPools); } } diff --git a/src/vsg/vk/DescriptorPool.cpp b/src/vsg/vk/DescriptorPool.cpp index d080e232b3..83f145e851 100644 --- a/src/vsg/vk/DescriptorPool.cpp +++ b/src/vsg/vk/DescriptorPool.cpp @@ -21,10 +21,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI using namespace vsg; -static size_t s_numDescriptorPools = 0; - -DescriptorPool::DescriptorPool(Device* device, uint32_t maxSets, const DescriptorPoolSizes& descriptorPoolSizes) : +DescriptorPool::DescriptorPool(Device* device, uint32_t in_maxSets, const DescriptorPoolSizes& in_descriptorPoolSizes) : _device(device), + maxSets(in_maxSets), + descriptorPoolSizes(in_descriptorPoolSizes), _availableDescriptorSet(maxSets), _availableDescriptorPoolSizes(descriptorPoolSizes) { @@ -40,13 +40,6 @@ DescriptorPool::DescriptorPool(Device* device, uint32_t maxSets, const Descripto { throw Exception{"Error: Failed to create DescriptorPool.", result}; } - - ++s_numDescriptorPools; - vsg::info("DescriptorPool::DescriptorPool( ", this, ", maxSets = ", maxSets, ", descriptorPoolSizes.size() = ", descriptorPoolSizes.size(), " ) s_numDescriptorPools = ", s_numDescriptorPools); - for(const auto& dps : descriptorPoolSizes) - { - vsg::info(" { ", dps.type, ", ", dps.descriptorCount, " }"); - } } DescriptorPool::~DescriptorPool() @@ -55,9 +48,6 @@ DescriptorPool::~DescriptorPool() { vkDestroyDescriptorPool(*_device, _descriptorPool, _device->getAllocationCallbacks()); } - - --s_numDescriptorPools; - vsg::info("DescriptorPool::~DescriptorPool( ", this, " ) s_numDescriptorPools = ", s_numDescriptorPools); } ref_ptr DescriptorPool::allocateDescriptorSet(DescriptorSetLayout* descriptorSetLayout) @@ -69,18 +59,6 @@ ref_ptr DescriptorPool::allocateDescriptorSet(Des return {}; } - // debug code - { - vsg::info("DescriptorPool::allocateDescriptorSet( ", descriptorSetLayout, ") "); - - DescriptorPoolSizes descriptorPoolSizes; - descriptorSetLayout->getDescriptorPoolSizes(descriptorPoolSizes); - for(const auto& dps : descriptorPoolSizes) - { - vsg::info(" { ", dps.type, ", ", dps.descriptorCount, " }"); - } - } - for (auto itr = _recyclingList.begin(); itr != _recyclingList.end(); ++itr) { auto dsi = *itr; @@ -90,14 +68,13 @@ ref_ptr DescriptorPool::allocateDescriptorSet(Des dsi->_descriptorPool = this; _recyclingList.erase(itr); --_availableDescriptorSet; - vsg::info("DescriptorPool::allocateDescriptorSet(..) reusing ", dsi) ; return dsi; } } if (_availableDescriptorSet == _recyclingList.size()) { - vsg::info("The only available vkDescriptorSets associated with DescriptorPool are in the recyclingList, but none are compatible."); + vsg::debug("The only available vkDescriptorSets associated with DescriptorPool are in the recyclingList, but none are compatible."); return {}; } @@ -127,7 +104,7 @@ ref_ptr DescriptorPool::allocateDescriptorSet(Des --_availableDescriptorSet; auto dsi = DescriptorSet::Implementation::create(this, descriptorSetLayout); - vsg::info("DescriptorPool::allocateDescriptorSet(..) allocated new ", dsi); + vsg::debug("DescriptorPool::allocateDescriptorSet(..) allocated new ", dsi); return dsi; } @@ -173,3 +150,51 @@ bool DescriptorPool::getAvailability(uint32_t& maxSets, DescriptorPoolSizes& des return true; } + +void DescriptorPool::report(std::ostream& out, indentation indent) const +{ + out<_descriptorSetLayout) + { + for(auto& binding : dsi->_descriptorSetLayout->bindings) + { + out< #include +#include + using namespace vsg; DescriptorPools::DescriptorPools(ref_ptr in_device, const ResourceRequirements& in_resourceRequirements) : device(in_device) { - vsg::info("DescriptorPools::DescriptorPools() ", this); - minimum_maxSets = std::max(1u, in_resourceRequirements.computeNumDescriptorSets()); minimum_descriptorPoolSizes = in_resourceRequirements.computeDescriptorPoolSizes(); - - vsg::info(" minimum_maxSets = ", minimum_maxSets); - vsg::info(" minimum_descriptorPoolSizes.size() = ", minimum_descriptorPoolSizes.size()); } DescriptorPools::~DescriptorPools() { - vsg::info("DescriptorPools::~DescriptorPools() ", this); + //report(std::cout); } void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes) { - vsg::info("DescriptorPools::getDescriptorPoolSizesToUse(", maxSets, ", ", descriptorPoolSizes.size(), ") in "); - if (minimum_maxSets > maxSets) { maxSets = minimum_maxSets; @@ -60,12 +55,6 @@ void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorP descriptorPoolSizes.push_back(VkDescriptorPoolSize{minimum_type, minimum_descriptorCount}); } } - - vsg::info(" maxSets = ", maxSets); - for(const auto& dps : descriptorPoolSizes) - { - vsg::info(" { ", dps.type, ", ", dps.descriptorCount, " }"); - } } void DescriptorPools::reserve(const ResourceRequirements& requirements) @@ -110,7 +99,7 @@ void DescriptorPools::reserve(const ResourceRequirements& requirements) // check if all the requirements have been met by exisiting availability if (required_maxSets==0 && required_descriptorPoolSizes.empty()) { - vsg::info("DescriptorPools::reserve(const ResourceRequirements& requirements) enought resource in existing DescriptorPools"); + vsg::debug("DescriptorPools::reserve(const ResourceRequirements& requirements) enought resource in existing DescriptorPools"); return; } @@ -122,16 +111,12 @@ void DescriptorPools::reserve(const ResourceRequirements& requirements) ref_ptr DescriptorPools::allocateDescriptorSet(DescriptorSetLayout* descriptorSetLayout) { - vsg::info("DescriptorPools::allocateDescriptorSet( ", descriptorSetLayout, " ) ", this, ", descriptorPools.size() = ", descriptorPools.size()); for (auto itr = descriptorPools.rbegin(); itr != descriptorPools.rend(); ++itr) { auto dsi = (*itr)->allocateDescriptorSet(descriptorSetLayout); - vsg::info(" DescriptorPool::allocateDescriptorSet( ", descriptorSetLayout, " ) dsi = ", dsi); if (dsi) return dsi; } - vsg::info(" Falling back to creating new DescriptorPool"); - DescriptorPoolSizes descriptorPoolSizes; descriptorSetLayout->getDescriptorPoolSizes(descriptorPoolSizes); @@ -145,4 +130,30 @@ ref_ptr DescriptorPools::allocateDescriptorSet(De return dsi; } +void DescriptorPools::report(std::ostream& out, indentation indent) const +{ + out<<"DescriptorPools::report(..) "<report(out, indent); + } + indent -= 4; + out< Date: Mon, 15 Jul 2024 18:33:15 +0100 Subject: [PATCH 07/23] Fixed comment --- include/vsg/vk/Context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/vsg/vk/Context.h b/include/vsg/vk/Context.h index e0eb40b068..d53a55724c 100644 --- a/include/vsg/vk/Context.h +++ b/include/vsg/vk/Context.h @@ -107,7 +107,7 @@ namespace vsg // the scene graph . GraphicsPipelineStates overridePipelineStates; - // DescriptorPool + // DescriptorPools ref_ptr descriptorPools; // ShaderCompiler From 552d4807b6d7af1b9deb95ae74d3b96324559ff3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 15 Jul 2024 18:33:29 +0100 Subject: [PATCH 08/23] Ran clang-format --- include/vsg/vk/Context.h | 1 - include/vsg/vk/DescriptorPool.h | 2 +- src/vsg/vk/Context.cpp | 4 ++-- src/vsg/vk/DescriptorPool.cpp | 38 ++++++++++++++++----------------- src/vsg/vk/DescriptorPools.cpp | 24 ++++++++++----------- src/vsg/vk/Device.cpp | 2 +- 6 files changed, 34 insertions(+), 37 deletions(-) diff --git a/include/vsg/vk/Context.h b/include/vsg/vk/Context.h index d53a55724c..5699cbb8b4 100644 --- a/include/vsg/vk/Context.h +++ b/include/vsg/vk/Context.h @@ -86,7 +86,6 @@ namespace vsg ref_ptr getOrCreateCommandBuffer(); - /// reserve resources that may be needed during compile traversal. void reserve(const ResourceRequirements& requirements); diff --git a/include/vsg/vk/DescriptorPool.h b/include/vsg/vk/DescriptorPool.h index efba0b514a..91170cf9bc 100644 --- a/include/vsg/vk/DescriptorPool.h +++ b/include/vsg/vk/DescriptorPool.h @@ -12,8 +12,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI */ -#include #include +#include namespace vsg { diff --git a/src/vsg/vk/Context.cpp b/src/vsg/vk/Context.cpp index 07db5b376f..b28ae443c7 100644 --- a/src/vsg/vk/Context.cpp +++ b/src/vsg/vk/Context.cpp @@ -24,8 +24,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include -#include #include +#include #include #include @@ -198,7 +198,7 @@ void Context::reserve(const ResourceRequirements& requirements) ref_ptr Context::allocateDescriptorSet(DescriptorSetLayout* descriptorSetLayout) { - return descriptorPools->allocateDescriptorSet(descriptorSetLayout); + return descriptorPools->allocateDescriptorSet(descriptorSetLayout); } void Context::copy(ref_ptr data, ref_ptr dest) diff --git a/src/vsg/vk/DescriptorPool.cpp b/src/vsg/vk/DescriptorPool.cpp index 83f145e851..ea2d6f5b93 100644 --- a/src/vsg/vk/DescriptorPool.cpp +++ b/src/vsg/vk/DescriptorPool.cpp @@ -153,48 +153,48 @@ bool DescriptorPool::getAvailability(uint32_t& maxSets, DescriptorPoolSizes& des void DescriptorPool::report(std::ostream& out, indentation indent) const { - out<_descriptorSetLayout) { - for(auto& binding : dsi->_descriptorSetLayout->bindings) + for (auto& binding : dsi->_descriptorSetLayout->bindings) { - out< maxSets) @@ -97,7 +96,7 @@ void DescriptorPools::reserve(const ResourceRequirements& requirements) } // check if all the requirements have been met by exisiting availability - if (required_maxSets==0 && required_descriptorPoolSizes.empty()) + if (required_maxSets == 0 && required_descriptorPoolSizes.empty()) { vsg::debug("DescriptorPools::reserve(const ResourceRequirements& requirements) enought resource in existing DescriptorPools"); return; @@ -108,7 +107,6 @@ void DescriptorPools::reserve(const ResourceRequirements& requirements) descriptorPools.push_back(vsg::DescriptorPool::create(device, required_maxSets, required_descriptorPoolSizes)); } - ref_ptr DescriptorPools::allocateDescriptorSet(DescriptorSetLayout* descriptorSetLayout) { for (auto itr = descriptorPools.rbegin(); itr != descriptorPools.rend(); ++itr) @@ -132,28 +130,28 @@ ref_ptr DescriptorPools::allocateDescriptorSet(De void DescriptorPools::report(std::ostream& out, indentation indent) const { - out<<"DescriptorPools::report(..) "<report(out, indent); } indent -= 4; - out< #include #include +#include #include #include -#include #include #include From 72db272065960d53a346bff59e3626d740d881fb Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 16 Jul 2024 16:10:29 +0100 Subject: [PATCH 09/23] Added stats query methods to DescriptorPools/DescriptorPool --- include/vsg/vk/DescriptorPool.h | 5 +- include/vsg/vk/DescriptorPools.h | 13 +++++ src/vsg/vk/DescriptorPool.cpp | 64 ++++++++++++++++++------- src/vsg/vk/DescriptorPools.cpp | 82 ++++++++++++++++++++++++++++++-- 4 files changed, 142 insertions(+), 22 deletions(-) diff --git a/include/vsg/vk/DescriptorPool.h b/include/vsg/vk/DescriptorPool.h index 91170cf9bc..124a7423b8 100644 --- a/include/vsg/vk/DescriptorPool.h +++ b/include/vsg/vk/DescriptorPool.h @@ -37,7 +37,10 @@ namespace vsg void freeDescriptorSet(ref_ptr dsi); /// get the stats of the available DescriptorSets/Descriptors - bool getAvailability(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes) const; + bool available(uint32_t& numSets, DescriptorPoolSizes& descriptorPoolSizes) const; + + /// compute the number of sets and descriptors used. + bool used(uint32_t& numSets, DescriptorPoolSizes& usedDescriptorPoolSizes) const; /// write the internal details to stream. void report(std::ostream& out, indentation indent = {}) const; diff --git a/include/vsg/vk/DescriptorPools.h b/include/vsg/vk/DescriptorPools.h index 85c3b45d99..04aae6d8b1 100644 --- a/include/vsg/vk/DescriptorPools.h +++ b/include/vsg/vk/DescriptorPools.h @@ -19,6 +19,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI namespace vsg { + /// Container for DescriptorPools. class VSG_DECLSPEC DescriptorPools : public Inherit { public: @@ -29,12 +30,24 @@ namespace vsg DescriptorPoolSizes minimum_descriptorPoolSizes; std::list> descriptorPools; + /// check if there are enough Descriptorsets/Descrioptors, if not allocated a new DescriptorPool for these resources void reserve(const ResourceRequirements& requirements); + // allocate vkDescriptorSet ref_ptr allocateDescriptorSet(DescriptorSetLayout* descriptorSetLayout); + /// write the internal details to stream. void report(std::ostream& out, indentation indent = {}) const; + /// compute the number of sets and descriptors available. + bool available(uint32_t& numSets, DescriptorPoolSizes& availableDescriptorPoolSizes) const; + + /// compute the number of sets and descriptors used. + bool used(uint32_t& numSets, DescriptorPoolSizes& descriptorPoolSizes) const; + + /// compute the number of sets and descriptors allocated. + bool allocated(uint32_t& numSets, DescriptorPoolSizes& descriptorPoolSizes) const; + protected: virtual ~DescriptorPools(); diff --git a/src/vsg/vk/DescriptorPool.cpp b/src/vsg/vk/DescriptorPool.cpp index ea2d6f5b93..8de46d0c80 100644 --- a/src/vsg/vk/DescriptorPool.cpp +++ b/src/vsg/vk/DescriptorPool.cpp @@ -22,9 +22,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI using namespace vsg; DescriptorPool::DescriptorPool(Device* device, uint32_t in_maxSets, const DescriptorPoolSizes& in_descriptorPoolSizes) : - _device(device), maxSets(in_maxSets), descriptorPoolSizes(in_descriptorPoolSizes), + _device(device), _availableDescriptorSet(maxSets), _availableDescriptorPoolSizes(descriptorPoolSizes) { @@ -78,11 +78,11 @@ ref_ptr DescriptorPool::allocateDescriptorSet(Des return {}; } - DescriptorPoolSizes descriptorPoolSizes; - descriptorSetLayout->getDescriptorPoolSizes(descriptorPoolSizes); + DescriptorPoolSizes requiredDescriptorPoolSizes; + descriptorSetLayout->getDescriptorPoolSizes(requiredDescriptorPoolSizes); auto newDescriptorPoolSizes = _availableDescriptorPoolSizes; - for (auto& [type, descriptorCount] : descriptorPoolSizes) + for (auto& [type, descriptorCount] : requiredDescriptorPoolSizes) { uint32_t foundDescriptorCount = 0; for (auto& [availableType, availableCount] : newDescriptorPoolSizes) @@ -117,33 +117,39 @@ void DescriptorPool::freeDescriptorSet(ref_ptr ds dsi->_descriptorPool = {}; } -bool DescriptorPool::getAvailability(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes) const +bool DescriptorPool::available(uint32_t& numSets, DescriptorPoolSizes& availableDescriptorPoolSizes) const { std::scoped_lock lock(mutex); if (_availableDescriptorSet == 0) return false; - maxSets += _availableDescriptorSet; + numSets += _availableDescriptorSet; for (auto& [availableType, availableCount] : _availableDescriptorPoolSizes) { if (availableCount > 0) { // increment any entries that are already in the descriptorPoolSizes vector - auto itr = descriptorPoolSizes.begin(); - for (; itr != descriptorPoolSizes.end(); ++itr) - { - if (itr->type == availableType) - { - itr->descriptorCount += availableCount; - break; - } - } + auto itr = std::find_if(availableDescriptorPoolSizes.begin(), availableDescriptorPoolSizes.end(), [&availableType](const VkDescriptorPoolSize& value) { return value.type == availableType; }); + if (itr != availableDescriptorPoolSizes.end()) + itr->descriptorCount += availableCount; + else + availableDescriptorPoolSizes.push_back(VkDescriptorPoolSize{availableType, availableCount}); + } + } - // if none matched add a new entry - if (itr == descriptorPoolSizes.end()) + for (auto& dsi : _recyclingList) + { + if (dsi->_descriptorSetLayout) + { + for (auto& binding : dsi->_descriptorSetLayout->bindings) { - descriptorPoolSizes.push_back(VkDescriptorPoolSize{availableType, availableCount}); + // increment any entries that are already in the descriptorPoolSizes vector + auto itr = std::find_if(availableDescriptorPoolSizes.begin(), availableDescriptorPoolSizes.end(), [&binding](const VkDescriptorPoolSize& value) { return value.type == binding.descriptorType; }); + if (itr != availableDescriptorPoolSizes.end()) + itr->descriptorCount += binding.descriptorCount; + else + availableDescriptorPoolSizes.push_back(VkDescriptorPoolSize{binding.descriptorType, binding.descriptorCount}); } } } @@ -151,6 +157,28 @@ bool DescriptorPool::getAvailability(uint32_t& maxSets, DescriptorPoolSizes& des return true; } +bool DescriptorPool::used(uint32_t& numSets, DescriptorPoolSizes& usedDescriptorPoolSizes) const +{ + if (maxSets == _availableDescriptorSet) return false; + + numSets += maxSets - _availableDescriptorSet; + + for (auto& dps : descriptorPoolSizes) + { + auto itr = std::find_if(_availableDescriptorPoolSizes.begin(), _availableDescriptorPoolSizes.end(), [&dps](const VkDescriptorPoolSize& value) { return value.type == dps.type; }); + if (itr != _availableDescriptorPoolSizes.end()) + { + uint32_t usedDescriptorCount = dps.descriptorCount - itr->descriptorCount; + auto used_itr = std::find_if(usedDescriptorPoolSizes.begin(), usedDescriptorPoolSizes.end(), [&dps](const VkDescriptorPoolSize& value) { return value.type == dps.type; }); + if (used_itr != usedDescriptorPoolSizes.end()) + used_itr += usedDescriptorCount; + else + usedDescriptorPoolSizes.push_back(VkDescriptorPoolSize{dps.type, usedDescriptorCount}); + } + } + return true; +} + void DescriptorPool::report(std::ostream& out, indentation indent) const { out << indent << "DescriptorPool " << this << " {" << std::endl; diff --git a/src/vsg/vk/DescriptorPools.cpp b/src/vsg/vk/DescriptorPools.cpp index 840ce56309..acd0a9ef13 100644 --- a/src/vsg/vk/DescriptorPools.cpp +++ b/src/vsg/vk/DescriptorPools.cpp @@ -27,7 +27,7 @@ DescriptorPools::DescriptorPools(ref_ptr in_device, const ResourceRequir DescriptorPools::~DescriptorPools() { - //report(std::cout); + // report(std::cout); } void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes) @@ -65,7 +65,7 @@ void DescriptorPools::reserve(const ResourceRequirements& requirements) DescriptorPoolSizes available_descriptorPoolSizes; for (auto& descriptorPool : descriptorPools) { - descriptorPool->getAvailability(available_maxSets, available_descriptorPoolSizes); + descriptorPool->available(available_maxSets, available_descriptorPoolSizes); } auto required_maxSets = maxSets; @@ -130,6 +130,23 @@ ref_ptr DescriptorPools::allocateDescriptorSet(De void DescriptorPools::report(std::ostream& out, indentation indent) const { + auto print = [&out, &indent](std::string_view name, uint32_t numSets, const DescriptorPoolSizes& descriptorPoolSizes) { + out << indent << name << " {" << std::endl; + indent += 4; + out << indent << "numSets " << numSets << std::endl; + out << indent << "descriptorPoolSizes " << descriptorPoolSizes.size() << " {" << std::endl; + indent += 4; + for (auto& dps : descriptorPoolSizes) + { + out << indent << "VkDescriptorPoolSize{ " << dps.type << ", " << dps.descriptorCount << " }" << std::endl; + } + indent -= 4; + out << indent << "}" << std::endl; + + indent -= 4; + out << indent << "}" << std::endl; + }; + out << "DescriptorPools::report(..) " << this << " {" << std::endl; indent += 4; @@ -138,11 +155,14 @@ void DescriptorPools::report(std::ostream& out, indentation indent) const indent += 4; for (auto& dps : minimum_descriptorPoolSizes) { - out << indent << "{ " << dps.type << ", " << dps.descriptorCount << " }" << std::endl; + out << indent << "VkDescriptorPoolSize{ " << dps.type << ", " << dps.descriptorCount << " }" << std::endl; } indent -= 4; out << indent << "}" << std::endl; +#if 1 + out << indent << "descriptorPools " << descriptorPools.size() << std::endl; +#else out << indent << "descriptorPools " << descriptorPools.size() << " {" << std::endl; indent += 4; for (auto& dp : descriptorPools) @@ -151,7 +171,63 @@ void DescriptorPools::report(std::ostream& out, indentation indent) const } indent -= 4; out << indent << "}" << std::endl; +#endif + + uint32_t numSets = 0; + DescriptorPoolSizes descriptorPoolSizes; + + allocated(numSets, descriptorPoolSizes); + print("DescriptorPools::allocated()", numSets, descriptorPoolSizes); + + numSets = 0; + descriptorPoolSizes.clear(); + used(numSets, descriptorPoolSizes); + print("DescriptorPools::used()", numSets, descriptorPoolSizes); + + numSets = 0; + descriptorPoolSizes.clear(); + available(numSets, descriptorPoolSizes); + print("DescriptorPools::available()", numSets, descriptorPoolSizes); indent -= 4; out << indent << "}" << std::endl; } + +bool DescriptorPools::available(uint32_t& numSets, DescriptorPoolSizes& availableDescriptorPoolSizes) const +{ + bool result = false; + for (auto& dp : descriptorPools) + { + result = dp->available(numSets, availableDescriptorPoolSizes) | result; + } + return result; +} + +bool DescriptorPools::used(uint32_t& numSets, DescriptorPoolSizes& descriptorPoolSizes) const +{ + bool result = false; + for (auto& dp : descriptorPools) + { + result = dp->used(numSets, descriptorPoolSizes) | result; + } + return result; +} + +bool DescriptorPools::allocated(uint32_t& numSets, DescriptorPoolSizes& descriptorPoolSizes) const +{ + if (descriptorPools.empty()) return false; + + for (auto& dp : descriptorPools) + { + numSets += dp->maxSets; + for (auto& dps : dp->descriptorPoolSizes) + { + auto itr = std::find_if(descriptorPoolSizes.begin(), descriptorPoolSizes.end(), [&dps](const VkDescriptorPoolSize& value) { return value.type == dps.type; }); + if (itr != descriptorPoolSizes.end()) + itr->descriptorCount += dps.descriptorCount; + else + descriptorPoolSizes.push_back(dps); + } + } + return true; +} From 6e6f3a3f909ed140cd0fd5cf379b987a2affdbc7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 16 Jul 2024 16:40:26 +0100 Subject: [PATCH 10/23] Refactor to fix Android compile error. --- src/vsg/vk/DescriptorPool.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vsg/vk/DescriptorPool.cpp b/src/vsg/vk/DescriptorPool.cpp index 8de46d0c80..5a1bc80fe7 100644 --- a/src/vsg/vk/DescriptorPool.cpp +++ b/src/vsg/vk/DescriptorPool.cpp @@ -125,16 +125,16 @@ bool DescriptorPool::available(uint32_t& numSets, DescriptorPoolSizes& available numSets += _availableDescriptorSet; - for (auto& [availableType, availableCount] : _availableDescriptorPoolSizes) + for (auto& dps : descriptorPoolSizes) { - if (availableCount > 0) + if (dps.descriptorCount > 0) { // increment any entries that are already in the descriptorPoolSizes vector - auto itr = std::find_if(availableDescriptorPoolSizes.begin(), availableDescriptorPoolSizes.end(), [&availableType](const VkDescriptorPoolSize& value) { return value.type == availableType; }); + auto itr = std::find_if(availableDescriptorPoolSizes.begin(), availableDescriptorPoolSizes.end(), [&dps](const VkDescriptorPoolSize& value) { return value.type == dps.type; }); if (itr != availableDescriptorPoolSizes.end()) - itr->descriptorCount += availableCount; + itr->descriptorCount += dps.descriptorCount; else - availableDescriptorPoolSizes.push_back(VkDescriptorPoolSize{availableType, availableCount}); + availableDescriptorPoolSizes.push_back(VkDescriptorPoolSize{dps.type, dps.descriptorCount}); } } From 1c0557c4e366d67d0ff9ad05b4990a90b88f2fa3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 16 Jul 2024 19:17:02 +0100 Subject: [PATCH 11/23] Fixed cppcheck issue --- include/vsg/vk/DescriptorPools.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/vsg/vk/DescriptorPools.h b/include/vsg/vk/DescriptorPools.h index 04aae6d8b1..223c071dee 100644 --- a/include/vsg/vk/DescriptorPools.h +++ b/include/vsg/vk/DescriptorPools.h @@ -23,7 +23,7 @@ namespace vsg class VSG_DECLSPEC DescriptorPools : public Inherit { public: - DescriptorPools(ref_ptr in_device, const ResourceRequirements& in_resourceRequirements = {}); + explicit DescriptorPools(ref_ptr in_device, const ResourceRequirements& in_resourceRequirements = {}); ref_ptr device; uint32_t minimum_maxSets = 0; From a5ad9c2be2d5788cad9a9c0cadfeffc298504ca7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 16 Jul 2024 19:33:57 +0100 Subject: [PATCH 12/23] Bumped version to 1.1.7 in prep for merging DescriptorPool branch. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dbed0c9087..2b60388ba8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.7) project(vsg - VERSION 1.1.6 + VERSION 1.1.7 DESCRIPTION "VulkanSceneGraph library" LANGUAGES CXX ) From 407f3672121dc49d8a708cf146ec055511b589ae Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 16 Jul 2024 20:13:50 +0100 Subject: [PATCH 13/23] cppcheck fixes --- src/vsg/vk/DescriptorPools.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vsg/vk/DescriptorPools.cpp b/src/vsg/vk/DescriptorPools.cpp index acd0a9ef13..8de5af1d68 100644 --- a/src/vsg/vk/DescriptorPools.cpp +++ b/src/vsg/vk/DescriptorPools.cpp @@ -37,21 +37,21 @@ void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorP maxSets = minimum_maxSets; } - for (auto& [minimum_type, minimum_descriptorCount] : minimum_descriptorPoolSizes) + for (auto& [type, descriptorCount] : minimum_descriptorPoolSizes) { auto itr = descriptorPoolSizes.begin(); for (; itr != descriptorPoolSizes.end(); ++itr) { - if (itr->type == minimum_type) + if (itr->type == type) { - if (minimum_descriptorCount > itr->descriptorCount) - itr->descriptorCount = minimum_descriptorCount; + if (descriptorCount > itr->descriptorCount) + itr->descriptorCount = descriptorCount; break; } } if (itr == descriptorPoolSizes.end()) { - descriptorPoolSizes.push_back(VkDescriptorPoolSize{minimum_type, minimum_descriptorCount}); + descriptorPoolSizes.push_back(VkDescriptorPoolSize{type, descriptorCount}); } } } @@ -130,7 +130,7 @@ ref_ptr DescriptorPools::allocateDescriptorSet(De void DescriptorPools::report(std::ostream& out, indentation indent) const { - auto print = [&out, &indent](std::string_view name, uint32_t numSets, const DescriptorPoolSizes& descriptorPoolSizes) { + auto print = [&out, &indent](const std::string_view& name, uint32_t numSets, const DescriptorPoolSizes& descriptorPoolSizes) { out << indent << name << " {" << std::endl; indent += 4; out << indent << "numSets " << numSets << std::endl; From 794c78af96f11ab99eb5b7870aa5e3291de6a1db Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 Jul 2024 09:55:06 +0100 Subject: [PATCH 14/23] Added suppression of buggy cppcheck report --- cmake/cppcheck-suppression-list.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/cppcheck-suppression-list.txt b/cmake/cppcheck-suppression-list.txt index ccf3afc76e..47a42ffe89 100644 --- a/cmake/cppcheck-suppression-list.txt +++ b/cmake/cppcheck-suppression-list.txt @@ -109,6 +109,7 @@ unassignedVariable:*src/vsg/core/MemorySlots.cpp unassignedVariable:*src/vsg/vk/Context.cpp unassignedVariable:*src/vsg/app/CompileManager.cpp unassignedVariable:*src/vsg/app/RecordAndSubmitTask.cpp +unassignedVariable:*src/vsg/vk/DescriptorPools.cpp // suppress inappropriate warnings about unreadVariable variables unreadVariable:*/src/vsg/state/DescriptorTexelBufferView.cpp From 6c4210ee8cf34815139f5665dd01cd7e0c745ee0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 Jul 2024 11:43:46 +0100 Subject: [PATCH 15/23] Added stats collection to DescrtiptorPools in prep for using history of reserve(..) calls to guide DescriptorPool allocations. --- include/vsg/vk/DescriptorPools.h | 5 +++++ src/vsg/vk/DescriptorPools.cpp | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/include/vsg/vk/DescriptorPools.h b/include/vsg/vk/DescriptorPools.h index 223c071dee..0e9ed58d36 100644 --- a/include/vsg/vk/DescriptorPools.h +++ b/include/vsg/vk/DescriptorPools.h @@ -30,6 +30,11 @@ namespace vsg DescriptorPoolSizes minimum_descriptorPoolSizes; std::list> descriptorPools; + // totals of all the calls to reserve, used to guide allocation of new DescritproPool + uint32_t reserve_count = 0; + uint32_t reserve_maxSets = 0; + DescriptorPoolSizes reserve_descriptorPoolSizes; + /// check if there are enough Descriptorsets/Descrioptors, if not allocated a new DescriptorPool for these resources void reserve(const ResourceRequirements& requirements); diff --git a/src/vsg/vk/DescriptorPools.cpp b/src/vsg/vk/DescriptorPools.cpp index 8de5af1d68..6317e272a5 100644 --- a/src/vsg/vk/DescriptorPools.cpp +++ b/src/vsg/vk/DescriptorPools.cpp @@ -61,6 +61,26 @@ void DescriptorPools::reserve(const ResourceRequirements& requirements) auto maxSets = requirements.computeNumDescriptorSets(); auto descriptorPoolSizes = requirements.computeDescriptorPoolSizes(); + // update the variables tracing all reserve calls. + ++reserve_count; + reserve_maxSets += maxSets; + for (auto& dps : descriptorPoolSizes) + { + auto itr = std::find_if(reserve_descriptorPoolSizes.begin(), reserve_descriptorPoolSizes.end(), [&dps](const VkDescriptorPoolSize& value) { return value.type == dps.type; }); + if (itr != reserve_descriptorPoolSizes.end()) + itr->descriptorCount += dps.descriptorCount; + else + reserve_descriptorPoolSizes.push_back(dps); + } + + vsg::info("DescriptorPools::reserve() reserve_maxSets = ", reserve_maxSets, " average = ", static_cast(reserve_maxSets) / static_cast(reserve_count), " {"); + for(auto& dps : reserve_descriptorPoolSizes) + { + vsg::info(" { ", dps.type, ", ", dps.descriptorCount, "} average ", static_cast(dps.descriptorCount) / static_cast(reserve_count)); + } + vsg::info("}"); + + // compute the total available resources uint32_t available_maxSets = 0; DescriptorPoolSizes available_descriptorPoolSizes; for (auto& descriptorPool : descriptorPools) @@ -68,6 +88,7 @@ void DescriptorPools::reserve(const ResourceRequirements& requirements) descriptorPool->available(available_maxSets, available_descriptorPoolSizes); } + // compute the additional required resources auto required_maxSets = maxSets; if (available_maxSets < required_maxSets) required_maxSets -= available_maxSets; From 1a5b272f6203d0811a41eec815ab490792fbd960 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 Jul 2024 11:44:40 +0100 Subject: [PATCH 16/23] Ran clang-format --- src/vsg/vk/DescriptorPools.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vsg/vk/DescriptorPools.cpp b/src/vsg/vk/DescriptorPools.cpp index 6317e272a5..d85cee7ea6 100644 --- a/src/vsg/vk/DescriptorPools.cpp +++ b/src/vsg/vk/DescriptorPools.cpp @@ -74,7 +74,7 @@ void DescriptorPools::reserve(const ResourceRequirements& requirements) } vsg::info("DescriptorPools::reserve() reserve_maxSets = ", reserve_maxSets, " average = ", static_cast(reserve_maxSets) / static_cast(reserve_count), " {"); - for(auto& dps : reserve_descriptorPoolSizes) + for (auto& dps : reserve_descriptorPoolSizes) { vsg::info(" { ", dps.type, ", ", dps.descriptorCount, "} average ", static_cast(dps.descriptorCount) / static_cast(reserve_count)); } From 4b13d22c1fddd44dfb423e0e58f19c63e7eab6f3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 Jul 2024 12:33:18 +0100 Subject: [PATCH 17/23] Moved stats reporting to getDescriptorPoolSizesToUse() and added reset to stats collection to ensure stats is just from the last DescriptorPool allocation. --- src/vsg/vk/DescriptorPools.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/vsg/vk/DescriptorPools.cpp b/src/vsg/vk/DescriptorPools.cpp index d85cee7ea6..750d544fd5 100644 --- a/src/vsg/vk/DescriptorPools.cpp +++ b/src/vsg/vk/DescriptorPools.cpp @@ -32,6 +32,13 @@ DescriptorPools::~DescriptorPools() void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes) { + vsg::info("DescriptorPools::getDescriptorPoolSizesToUse() reserve_maxSets = ", reserve_maxSets, " average = ", static_cast(reserve_maxSets) / static_cast(reserve_count), " {"); + for (auto& dps : reserve_descriptorPoolSizes) + { + vsg::info(" { ", dps.type, ", ", dps.descriptorCount, "} average ", static_cast(dps.descriptorCount) / static_cast(reserve_count)); + } + vsg::info("}"); + if (minimum_maxSets > maxSets) { maxSets = minimum_maxSets; @@ -54,6 +61,10 @@ void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorP descriptorPoolSizes.push_back(VkDescriptorPoolSize{type, descriptorCount}); } } + + reserve_count = 0; + reserve_maxSets = 0; + reserve_descriptorPoolSizes.clear(); } void DescriptorPools::reserve(const ResourceRequirements& requirements) @@ -72,14 +83,14 @@ void DescriptorPools::reserve(const ResourceRequirements& requirements) else reserve_descriptorPoolSizes.push_back(dps); } - +#if 0 vsg::info("DescriptorPools::reserve() reserve_maxSets = ", reserve_maxSets, " average = ", static_cast(reserve_maxSets) / static_cast(reserve_count), " {"); for (auto& dps : reserve_descriptorPoolSizes) { vsg::info(" { ", dps.type, ", ", dps.descriptorCount, "} average ", static_cast(dps.descriptorCount) / static_cast(reserve_count)); } vsg::info("}"); - +#endif // compute the total available resources uint32_t available_maxSets = 0; DescriptorPoolSizes available_descriptorPoolSizes; From ea35ae9483b8a28a3148c99ca7372133aae864d4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 Jul 2024 14:40:23 +0100 Subject: [PATCH 18/23] Implemented use of the reserve_maxSet & reserve_descriptorPoolSizes to guiding the size of DescriptorPool to allocate. --- include/vsg/vk/DescriptorPools.h | 1 + src/vsg/vk/DescriptorPools.cpp | 38 +++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/include/vsg/vk/DescriptorPools.h b/include/vsg/vk/DescriptorPools.h index 0e9ed58d36..7d59d3a599 100644 --- a/include/vsg/vk/DescriptorPools.h +++ b/include/vsg/vk/DescriptorPools.h @@ -31,6 +31,7 @@ namespace vsg std::list> descriptorPools; // totals of all the calls to reserve, used to guide allocation of new DescritproPool + uint32_t target_maxSets = 4096; uint32_t reserve_count = 0; uint32_t reserve_maxSets = 0; DescriptorPoolSizes reserve_descriptorPoolSizes; diff --git a/src/vsg/vk/DescriptorPools.cpp b/src/vsg/vk/DescriptorPools.cpp index 750d544fd5..d241717c47 100644 --- a/src/vsg/vk/DescriptorPools.cpp +++ b/src/vsg/vk/DescriptorPools.cpp @@ -32,13 +32,49 @@ DescriptorPools::~DescriptorPools() void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes) { - vsg::info("DescriptorPools::getDescriptorPoolSizesToUse() reserve_maxSets = ", reserve_maxSets, " average = ", static_cast(reserve_maxSets) / static_cast(reserve_count), " {"); + vsg::info("DescriptorPools::getDescriptorPoolSizesToUse() descriptorPools.size() = ", descriptorPools.size() , ", reserve_maxSets = ", reserve_maxSets, " average = ", static_cast(reserve_maxSets) / static_cast(reserve_count), " {"); for (auto& dps : reserve_descriptorPoolSizes) { vsg::info(" { ", dps.type, ", ", dps.descriptorCount, "} average ", static_cast(dps.descriptorCount) / static_cast(reserve_count)); } vsg::info("}"); +#if 1 + if (target_maxSets > reserve_maxSets) + { + vsg::info(" Scaling maxSets to ", target_maxSets); + for (auto& dps : reserve_descriptorPoolSizes) + { + dps.descriptorCount = static_cast(std::ceil(static_cast(dps.descriptorCount) * static_cast(target_maxSets) / static_cast(reserve_maxSets))); + vsg::info(" { ", dps.type, ", ", dps.descriptorCount, "}"); + } + reserve_maxSets = target_maxSets; + } + + if (target_maxSets > maxSets) + { + maxSets = target_maxSets; + } +#endif + for (auto& [type, descriptorCount] : reserve_descriptorPoolSizes) + { + auto itr = descriptorPoolSizes.begin(); + for (; itr != descriptorPoolSizes.end(); ++itr) + { + if (itr->type == type) + { + if (descriptorCount > itr->descriptorCount) + itr->descriptorCount = descriptorCount; + break; + } + } + if (itr == descriptorPoolSizes.end()) + { + descriptorPoolSizes.push_back(VkDescriptorPoolSize{type, descriptorCount}); + } + } + + // add to minimum sizes if required. if (minimum_maxSets > maxSets) { maxSets = minimum_maxSets; From 261e1748e2e6be2b31d591777da42e30fa81cf41 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 Jul 2024 16:08:40 +0100 Subject: [PATCH 19/23] Moved reserve_* handling into block to avoid potential devide by zero. --- src/vsg/vk/DescriptorPools.cpp | 61 +++++++++++++++++----------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/src/vsg/vk/DescriptorPools.cpp b/src/vsg/vk/DescriptorPools.cpp index d241717c47..4c3dc94f43 100644 --- a/src/vsg/vk/DescriptorPools.cpp +++ b/src/vsg/vk/DescriptorPools.cpp @@ -27,52 +27,53 @@ DescriptorPools::DescriptorPools(ref_ptr in_device, const ResourceRequir DescriptorPools::~DescriptorPools() { - // report(std::cout); } void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes) { - vsg::info("DescriptorPools::getDescriptorPoolSizesToUse() descriptorPools.size() = ", descriptorPools.size() , ", reserve_maxSets = ", reserve_maxSets, " average = ", static_cast(reserve_maxSets) / static_cast(reserve_count), " {"); - for (auto& dps : reserve_descriptorPoolSizes) - { - vsg::info(" { ", dps.type, ", ", dps.descriptorCount, "} average ", static_cast(dps.descriptorCount) / static_cast(reserve_count)); - } - vsg::info("}"); -#if 1 - if (target_maxSets > reserve_maxSets) + if (reserve_count > 0) { - vsg::info(" Scaling maxSets to ", target_maxSets); + vsg::info("DescriptorPools::getDescriptorPoolSizesToUse() descriptorPools.size() = ", descriptorPools.size(), ", reserve_maxSets = ", reserve_maxSets, " average = ", static_cast(reserve_maxSets) / static_cast(reserve_count), " {"); for (auto& dps : reserve_descriptorPoolSizes) { - dps.descriptorCount = static_cast(std::ceil(static_cast(dps.descriptorCount) * static_cast(target_maxSets) / static_cast(reserve_maxSets))); - vsg::info(" { ", dps.type, ", ", dps.descriptorCount, "}"); + vsg::info(" { ", dps.type, ", ", dps.descriptorCount, "} average ", static_cast(dps.descriptorCount) / static_cast(reserve_count)); } - reserve_maxSets = target_maxSets; - } + vsg::info("}"); - if (target_maxSets > maxSets) - { - maxSets = target_maxSets; - } -#endif - for (auto& [type, descriptorCount] : reserve_descriptorPoolSizes) - { - auto itr = descriptorPoolSizes.begin(); - for (; itr != descriptorPoolSizes.end(); ++itr) + if (target_maxSets > reserve_maxSets) { - if (itr->type == type) + vsg::info(" Scaling maxSets to ", target_maxSets); + for (auto& dps : reserve_descriptorPoolSizes) { - if (descriptorCount > itr->descriptorCount) - itr->descriptorCount = descriptorCount; - break; + dps.descriptorCount = static_cast(std::ceil(static_cast(dps.descriptorCount) * static_cast(target_maxSets) / static_cast(reserve_maxSets))); + vsg::info(" { ", dps.type, ", ", dps.descriptorCount, "}"); } + reserve_maxSets = target_maxSets; } - if (itr == descriptorPoolSizes.end()) + + if (target_maxSets > maxSets) { - descriptorPoolSizes.push_back(VkDescriptorPoolSize{type, descriptorCount}); + maxSets = target_maxSets; } - } + for (auto& [type, descriptorCount] : reserve_descriptorPoolSizes) + { + auto itr = descriptorPoolSizes.begin(); + for (; itr != descriptorPoolSizes.end(); ++itr) + { + if (itr->type == type) + { + if (descriptorCount > itr->descriptorCount) + itr->descriptorCount = descriptorCount; + break; + } + } + if (itr == descriptorPoolSizes.end()) + { + descriptorPoolSizes.push_back(VkDescriptorPoolSize{type, descriptorCount}); + } + } + } // add to minimum sizes if required. if (minimum_maxSets > maxSets) From a7dd474b0b01ba5d62e7411a63d3a249fd2c0f1c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 Jul 2024 17:33:28 +0100 Subject: [PATCH 20/23] Simplified the DescriptorPools constructor and member variables. --- include/vsg/vk/DescriptorPools.h | 6 ++-- src/vsg/vk/Context.cpp | 2 +- src/vsg/vk/DescriptorPool.cpp | 8 ++++- src/vsg/vk/DescriptorPools.cpp | 51 +++----------------------------- 4 files changed, 14 insertions(+), 53 deletions(-) diff --git a/include/vsg/vk/DescriptorPools.h b/include/vsg/vk/DescriptorPools.h index 7d59d3a599..d10ccff53b 100644 --- a/include/vsg/vk/DescriptorPools.h +++ b/include/vsg/vk/DescriptorPools.h @@ -23,15 +23,13 @@ namespace vsg class VSG_DECLSPEC DescriptorPools : public Inherit { public: - explicit DescriptorPools(ref_ptr in_device, const ResourceRequirements& in_resourceRequirements = {}); + explicit DescriptorPools(ref_ptr in_device); ref_ptr device; - uint32_t minimum_maxSets = 0; - DescriptorPoolSizes minimum_descriptorPoolSizes; std::list> descriptorPools; // totals of all the calls to reserve, used to guide allocation of new DescritproPool - uint32_t target_maxSets = 4096; + uint32_t target_maxSets = 2048; uint32_t reserve_count = 0; uint32_t reserve_maxSets = 0; DescriptorPoolSizes reserve_descriptorPoolSizes; diff --git a/src/vsg/vk/Context.cpp b/src/vsg/vk/Context.cpp index b28ae443c7..4c98fd04d4 100644 --- a/src/vsg/vk/Context.cpp +++ b/src/vsg/vk/Context.cpp @@ -122,7 +122,7 @@ Context::Context(Device* in_device, const ResourceRequirements& in_resourceRequi descriptorPools = device->descriptorPools.ref_ptr(); if (!descriptorPools) { - device->descriptorPools = descriptorPools = DescriptorPools::create(device, in_resourceRequirements); + device->descriptorPools = descriptorPools = DescriptorPools::create(device); vsg::debug("Context::Context() creating new descriptorPools = ", descriptorPools); } else diff --git a/src/vsg/vk/DescriptorPool.cpp b/src/vsg/vk/DescriptorPool.cpp index 5a1bc80fe7..5f008ca111 100644 --- a/src/vsg/vk/DescriptorPool.cpp +++ b/src/vsg/vk/DescriptorPool.cpp @@ -40,7 +40,13 @@ DescriptorPool::DescriptorPool(Device* device, uint32_t in_maxSets, const Descri { throw Exception{"Error: Failed to create DescriptorPool.", result}; } -} + + vsg::info("DescriptorPool::DescriptorPool() ", this, ", maxSets = ", maxSets, " {"); + for (auto& dps : descriptorPoolSizes) + { + vsg::info(" { ", dps.type, ", ", dps.descriptorCount, " }"); + } + vsg::info("}");} DescriptorPool::~DescriptorPool() { diff --git a/src/vsg/vk/DescriptorPools.cpp b/src/vsg/vk/DescriptorPools.cpp index 4c3dc94f43..7cd4c48206 100644 --- a/src/vsg/vk/DescriptorPools.cpp +++ b/src/vsg/vk/DescriptorPools.cpp @@ -18,11 +18,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI using namespace vsg; -DescriptorPools::DescriptorPools(ref_ptr in_device, const ResourceRequirements& in_resourceRequirements) : +DescriptorPools::DescriptorPools(ref_ptr in_device) : device(in_device) { - minimum_maxSets = std::max(1u, in_resourceRequirements.computeNumDescriptorSets()); - minimum_descriptorPoolSizes = in_resourceRequirements.computeDescriptorPoolSizes(); } DescriptorPools::~DescriptorPools() @@ -36,7 +34,7 @@ void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorP vsg::info("DescriptorPools::getDescriptorPoolSizesToUse() descriptorPools.size() = ", descriptorPools.size(), ", reserve_maxSets = ", reserve_maxSets, " average = ", static_cast(reserve_maxSets) / static_cast(reserve_count), " {"); for (auto& dps : reserve_descriptorPoolSizes) { - vsg::info(" { ", dps.type, ", ", dps.descriptorCount, "} average ", static_cast(dps.descriptorCount) / static_cast(reserve_count)); + vsg::info(" { ", dps.type, ", ", dps.descriptorCount, " } average ", static_cast(dps.descriptorCount) / static_cast(reserve_count)); } vsg::info("}"); @@ -46,7 +44,7 @@ void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorP for (auto& dps : reserve_descriptorPoolSizes) { dps.descriptorCount = static_cast(std::ceil(static_cast(dps.descriptorCount) * static_cast(target_maxSets) / static_cast(reserve_maxSets))); - vsg::info(" { ", dps.type, ", ", dps.descriptorCount, "}"); + vsg::info(" { ", dps.type, ", ", dps.descriptorCount, " }"); } reserve_maxSets = target_maxSets; } @@ -75,30 +73,6 @@ void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorP } } - // add to minimum sizes if required. - if (minimum_maxSets > maxSets) - { - maxSets = minimum_maxSets; - } - - for (auto& [type, descriptorCount] : minimum_descriptorPoolSizes) - { - auto itr = descriptorPoolSizes.begin(); - for (; itr != descriptorPoolSizes.end(); ++itr) - { - if (itr->type == type) - { - if (descriptorCount > itr->descriptorCount) - itr->descriptorCount = descriptorCount; - break; - } - } - if (itr == descriptorPoolSizes.end()) - { - descriptorPoolSizes.push_back(VkDescriptorPoolSize{type, descriptorCount}); - } - } - reserve_count = 0; reserve_maxSets = 0; reserve_descriptorPoolSizes.clear(); @@ -120,14 +94,7 @@ void DescriptorPools::reserve(const ResourceRequirements& requirements) else reserve_descriptorPoolSizes.push_back(dps); } -#if 0 - vsg::info("DescriptorPools::reserve() reserve_maxSets = ", reserve_maxSets, " average = ", static_cast(reserve_maxSets) / static_cast(reserve_count), " {"); - for (auto& dps : reserve_descriptorPoolSizes) - { - vsg::info(" { ", dps.type, ", ", dps.descriptorCount, "} average ", static_cast(dps.descriptorCount) / static_cast(reserve_count)); - } - vsg::info("}"); -#endif + // compute the total available resources uint32_t available_maxSets = 0; DescriptorPoolSizes available_descriptorPoolSizes; @@ -219,16 +186,6 @@ void DescriptorPools::report(std::ostream& out, indentation indent) const out << "DescriptorPools::report(..) " << this << " {" << std::endl; indent += 4; - out << indent << "minimum_maxSets = " << minimum_maxSets << std::endl; - out << indent << "minimum_descriptorPoolSizes " << minimum_descriptorPoolSizes.size() << " {" << std::endl; - indent += 4; - for (auto& dps : minimum_descriptorPoolSizes) - { - out << indent << "VkDescriptorPoolSize{ " << dps.type << ", " << dps.descriptorCount << " }" << std::endl; - } - indent -= 4; - out << indent << "}" << std::endl; - #if 1 out << indent << "descriptorPools " << descriptorPools.size() << std::endl; #else From 03bf456948616a670f94a6293fe705fc19bc7aad Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 Jul 2024 18:12:31 +0100 Subject: [PATCH 21/23] Improved naming of maxSets member variables. Implemented scaling of the minimum_maxSets. --- include/vsg/vk/DescriptorPools.h | 5 ++++- src/vsg/vk/DescriptorPools.cpp | 16 ++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/include/vsg/vk/DescriptorPools.h b/include/vsg/vk/DescriptorPools.h index d10ccff53b..4beb0ce287 100644 --- a/include/vsg/vk/DescriptorPools.h +++ b/include/vsg/vk/DescriptorPools.h @@ -28,8 +28,11 @@ namespace vsg ref_ptr device; std::list> descriptorPools; + uint32_t maximum_maxSets = 2048; // hardware dependent? + uint32_t minimum_maxSets = 0; // default + double scale_maxSets = 2.0; // how to scale minimum_maxSets on each successive DescriptorPool allocation. + // totals of all the calls to reserve, used to guide allocation of new DescritproPool - uint32_t target_maxSets = 2048; uint32_t reserve_count = 0; uint32_t reserve_maxSets = 0; DescriptorPoolSizes reserve_descriptorPoolSizes; diff --git a/src/vsg/vk/DescriptorPools.cpp b/src/vsg/vk/DescriptorPools.cpp index 7cd4c48206..362b8f2d83 100644 --- a/src/vsg/vk/DescriptorPools.cpp +++ b/src/vsg/vk/DescriptorPools.cpp @@ -38,20 +38,20 @@ void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorP } vsg::info("}"); - if (target_maxSets > reserve_maxSets) + if (minimum_maxSets > reserve_maxSets) { - vsg::info(" Scaling maxSets to ", target_maxSets); + vsg::info(" Scaling maxSets to ", minimum_maxSets); for (auto& dps : reserve_descriptorPoolSizes) { - dps.descriptorCount = static_cast(std::ceil(static_cast(dps.descriptorCount) * static_cast(target_maxSets) / static_cast(reserve_maxSets))); + dps.descriptorCount = static_cast(std::ceil(static_cast(dps.descriptorCount) * static_cast(minimum_maxSets) / static_cast(reserve_maxSets))); vsg::info(" { ", dps.type, ", ", dps.descriptorCount, " }"); } - reserve_maxSets = target_maxSets; + reserve_maxSets = minimum_maxSets; } - if (target_maxSets > maxSets) + if (minimum_maxSets > maxSets) { - maxSets = target_maxSets; + maxSets = minimum_maxSets; } for (auto& [type, descriptorCount] : reserve_descriptorPoolSizes) @@ -73,6 +73,10 @@ void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorP } } + minimum_maxSets = std::min(maximum_maxSets, static_cast(static_cast(maxSets) * scale_maxSets)); + + vsg::info(" new minimum_maxSets = ", minimum_maxSets); + reserve_count = 0; reserve_maxSets = 0; reserve_descriptorPoolSizes.clear(); From 6f87ef0e25f87e793ed65d0cc50d9d7a174d9945 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 Jul 2024 18:13:30 +0100 Subject: [PATCH 22/23] Ran clang-format --- include/vsg/vk/DescriptorPools.h | 4 ++-- src/vsg/vk/DescriptorPool.cpp | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/vsg/vk/DescriptorPools.h b/include/vsg/vk/DescriptorPools.h index 4beb0ce287..11b0fe1da2 100644 --- a/include/vsg/vk/DescriptorPools.h +++ b/include/vsg/vk/DescriptorPools.h @@ -29,8 +29,8 @@ namespace vsg std::list> descriptorPools; uint32_t maximum_maxSets = 2048; // hardware dependent? - uint32_t minimum_maxSets = 0; // default - double scale_maxSets = 2.0; // how to scale minimum_maxSets on each successive DescriptorPool allocation. + uint32_t minimum_maxSets = 0; // default + double scale_maxSets = 2.0; // how to scale minimum_maxSets on each successive DescriptorPool allocation. // totals of all the calls to reserve, used to guide allocation of new DescritproPool uint32_t reserve_count = 0; diff --git a/src/vsg/vk/DescriptorPool.cpp b/src/vsg/vk/DescriptorPool.cpp index 5f008ca111..f61bb662cc 100644 --- a/src/vsg/vk/DescriptorPool.cpp +++ b/src/vsg/vk/DescriptorPool.cpp @@ -46,7 +46,8 @@ DescriptorPool::DescriptorPool(Device* device, uint32_t in_maxSets, const Descri { vsg::info(" { ", dps.type, ", ", dps.descriptorCount, " }"); } - vsg::info("}");} + vsg::info("}"); +} DescriptorPool::~DescriptorPool() { From 827c567b58e9020c3a05728f1d5cabbc3e08b3d0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 Jul 2024 18:46:16 +0100 Subject: [PATCH 23/23] Removed debug output --- include/vsg/vk/DescriptorPools.h | 6 +++--- src/vsg/vk/DescriptorPool.cpp | 6 +++--- src/vsg/vk/DescriptorPools.cpp | 11 ----------- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/include/vsg/vk/DescriptorPools.h b/include/vsg/vk/DescriptorPools.h index 11b0fe1da2..1ded89cae6 100644 --- a/include/vsg/vk/DescriptorPools.h +++ b/include/vsg/vk/DescriptorPools.h @@ -28,11 +28,11 @@ namespace vsg ref_ptr device; std::list> descriptorPools; - uint32_t maximum_maxSets = 2048; // hardware dependent? - uint32_t minimum_maxSets = 0; // default + uint32_t minimum_maxSets = 0; // minimum value of maxSets when allocating new DescriptoPool. + uint32_t maximum_maxSets = 2048; // maximum value of minimum_maxSets can grow to. double scale_maxSets = 2.0; // how to scale minimum_maxSets on each successive DescriptorPool allocation. - // totals of all the calls to reserve, used to guide allocation of new DescritproPool + // totals of all the calls to reserve(const ResourceRequirements& requirements), used to guide allocation of new DescritproPool uint32_t reserve_count = 0; uint32_t reserve_maxSets = 0; DescriptorPoolSizes reserve_descriptorPoolSizes; diff --git a/src/vsg/vk/DescriptorPool.cpp b/src/vsg/vk/DescriptorPool.cpp index f61bb662cc..4394f8c9f6 100644 --- a/src/vsg/vk/DescriptorPool.cpp +++ b/src/vsg/vk/DescriptorPool.cpp @@ -41,12 +41,12 @@ DescriptorPool::DescriptorPool(Device* device, uint32_t in_maxSets, const Descri throw Exception{"Error: Failed to create DescriptorPool.", result}; } - vsg::info("DescriptorPool::DescriptorPool() ", this, ", maxSets = ", maxSets, " {"); + vsg::debug("DescriptorPool::DescriptorPool() ", this, ", maxSets = ", maxSets, " {"); for (auto& dps : descriptorPoolSizes) { - vsg::info(" { ", dps.type, ", ", dps.descriptorCount, " }"); + vsg::debug(" { ", dps.type, ", ", dps.descriptorCount, " }"); } - vsg::info("}"); + vsg::debug("}"); } DescriptorPool::~DescriptorPool() diff --git a/src/vsg/vk/DescriptorPools.cpp b/src/vsg/vk/DescriptorPools.cpp index 362b8f2d83..6c63672bd8 100644 --- a/src/vsg/vk/DescriptorPools.cpp +++ b/src/vsg/vk/DescriptorPools.cpp @@ -31,20 +31,11 @@ void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorP { if (reserve_count > 0) { - vsg::info("DescriptorPools::getDescriptorPoolSizesToUse() descriptorPools.size() = ", descriptorPools.size(), ", reserve_maxSets = ", reserve_maxSets, " average = ", static_cast(reserve_maxSets) / static_cast(reserve_count), " {"); - for (auto& dps : reserve_descriptorPoolSizes) - { - vsg::info(" { ", dps.type, ", ", dps.descriptorCount, " } average ", static_cast(dps.descriptorCount) / static_cast(reserve_count)); - } - vsg::info("}"); - if (minimum_maxSets > reserve_maxSets) { - vsg::info(" Scaling maxSets to ", minimum_maxSets); for (auto& dps : reserve_descriptorPoolSizes) { dps.descriptorCount = static_cast(std::ceil(static_cast(dps.descriptorCount) * static_cast(minimum_maxSets) / static_cast(reserve_maxSets))); - vsg::info(" { ", dps.type, ", ", dps.descriptorCount, " }"); } reserve_maxSets = minimum_maxSets; } @@ -75,8 +66,6 @@ void DescriptorPools::getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorP minimum_maxSets = std::min(maximum_maxSets, static_cast(static_cast(maxSets) * scale_maxSets)); - vsg::info(" new minimum_maxSets = ", minimum_maxSets); - reserve_count = 0; reserve_maxSets = 0; reserve_descriptorPoolSizes.clear();