From baa02a0701dc1bc2df9cf501d6f6c44c19649b33 Mon Sep 17 00:00:00 2001 From: Michael Saunders Date: Fri, 20 Feb 2026 08:17:59 -0800 Subject: [PATCH 01/80] Add missing export to vsg::Exception struct If VulkanSceneGraph is compiled as a .dylib and used by another .dylib on the Mac where VulkanSceneGraph throws a vsg::Exception the client requesting the service from VulkanSceneGraph is not able to catch the vsg::Exception because the RTTI information is different. This is a known issue with clang. If the symbol is not exported for a shared library the RTTI information will not match that generated by dependent libraries for the same symbol. --- include/vsg/core/Exception.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/vsg/core/Exception.h b/include/vsg/core/Exception.h index 6e40a17cb4..dea3619d3e 100644 --- a/include/vsg/core/Exception.h +++ b/include/vsg/core/Exception.h @@ -12,6 +12,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI */ +#include + #include namespace vsg @@ -19,7 +21,7 @@ namespace vsg /// Exception object that can be thrown from VSG code, such as failed Vulkan calls where the result value will be the VkResult value /// returned from failed Vulkan call. - struct Exception + struct VSG_DECLSPEC Exception { std::string message; int result = 0; From 952acaa854ddaae9ec31ce6006d1c6ace957b74e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 13 Mar 2026 11:25:37 +0000 Subject: [PATCH 02/80] Added report(LogOutput&) methods --- include/vsg/core/MemorySlots.h | 6 +++++- include/vsg/vk/DeviceMemory.h | 2 ++ include/vsg/vk/MemoryBufferPools.h | 2 ++ src/vsg/core/MemorySlots.cpp | 17 +++++++++++------ src/vsg/state/Image.cpp | 2 +- src/vsg/vk/DeviceMemory.cpp | 9 +++++++++ src/vsg/vk/MemoryBufferPools.cpp | 10 ++++++++++ 7 files changed, 40 insertions(+), 8 deletions(-) diff --git a/include/vsg/core/MemorySlots.h b/include/vsg/core/MemorySlots.h index 2680478702..7d3ccab3da 100644 --- a/include/vsg/core/MemorySlots.h +++ b/include/vsg/core/MemorySlots.h @@ -31,6 +31,9 @@ namespace vsg MEMORY_TRACKING_DEFAULT = MEMORY_TRACKING_NO_CHECKS }; + // forward declare + class LogOutput; + /** class used internally by vsg::Allocator, vsg::DeviceMemory and vsg::Buffer to manage suballocation within a block of CPU or GPU memory.*/ class VSG_DECLSPEC MemorySlots { @@ -52,7 +55,8 @@ namespace vsg size_t totalMemorySize() const { return _totalMemorySize; } // debug facilities - void report(std::ostream& out) const; + void report(LogOutput& log) const; + bool check() const; mutable int memoryTracking = MEMORY_TRACKING_DEFAULT; diff --git a/include/vsg/vk/DeviceMemory.h b/include/vsg/vk/DeviceMemory.h index ebd86590c3..3e5d58a6b4 100644 --- a/include/vsg/vk/DeviceMemory.h +++ b/include/vsg/vk/DeviceMemory.h @@ -55,6 +55,8 @@ namespace vsg Device* getDevice() { return _device; } const Device* getDevice() const { return _device; } + void report(LogOutput& out) const; + protected: virtual ~DeviceMemory(); diff --git a/include/vsg/vk/MemoryBufferPools.h b/include/vsg/vk/MemoryBufferPools.h index 765b2315ac..d6c27ebfa7 100644 --- a/include/vsg/vk/MemoryBufferPools.h +++ b/include/vsg/vk/MemoryBufferPools.h @@ -57,6 +57,8 @@ namespace vsg VkResult reserve(ResourceRequirements& requirements); + void report(LogOutput& out) const; + protected: mutable std::mutex _mutex; diff --git a/src/vsg/core/MemorySlots.cpp b/src/vsg/core/MemorySlots.cpp index 366801dab1..25875baf38 100644 --- a/src/vsg/core/MemorySlots.cpp +++ b/src/vsg/core/MemorySlots.cpp @@ -46,7 +46,8 @@ MemorySlots::~MemorySlots() else { info("MemorySlots::~MemorySlots() ", this, ", not all slots restored correctly."); - info_stream([&](auto& fout) { report(fout); }); + LogOutput log; + report(log); } } if (memoryTracking & MEMORY_TRACKING_CHECK_ACTIONS) @@ -98,7 +99,9 @@ bool MemorySlots::check() const if (computedSize != _totalMemorySize) { warn("MemorySlots::check() ", this, " failed, computedSize (", computedSize, ") != _totalMemorySize (", _totalMemorySize, ")"); - warn_stream([&](auto& fout) { report(fout); }); + + LogOutput log; + report(log); return false; } @@ -106,18 +109,20 @@ bool MemorySlots::check() const return true; } -void MemorySlots::report(std::ostream& out) const +void MemorySlots::report(LogOutput& out) const { - out << "MemorySlots::report() " << this << std::endl; + out.enter("MemorySlots::report(...)"); + out("MemorySlots::report() ",this); for (auto& [offset, size] : _offsetSizes) { - out << " available " << offset << ", " << size << std::endl; + out(" available ", offset, ", ", size); } for (auto& [offset, size] : _reservedMemory) { - out << " reserved " << std::dec << offset << ", " << size << std::endl; + out(" reserved ", std::dec, offset, ", ", size); } + out.leave(); } void MemorySlots::insertAvailableSlot(size_t offset, size_t size) diff --git a/src/vsg/state/Image.cpp b/src/vsg/state/Image.cpp index 923557cc12..0cd45d04d1 100644 --- a/src/vsg/state/Image.cpp +++ b/src/vsg/state/Image.cpp @@ -161,7 +161,7 @@ VkResult Image::allocateAndBindMemory(Device* device, VkMemoryPropertyFlags memo auto [allocated, offset] = memory->reserve(memRequirements.size); if (!allocated) { - throw Exception{"Error: Failed to allocate DeviceMemory."}; + throw Exception{"Error: vsg::Image::allocateAndBindMemory() Failed to allocate DeviceMemory."}; } return bind(memory, offset); diff --git a/src/vsg/vk/DeviceMemory.cpp b/src/vsg/vk/DeviceMemory.cpp index 086637fcc1..674a18f9fb 100644 --- a/src/vsg/vk/DeviceMemory.cpp +++ b/src/vsg/vk/DeviceMemory.cpp @@ -190,3 +190,12 @@ size_t DeviceMemory::totalMemorySize() const { return _memorySlots.totalMemorySize(); } + +void DeviceMemory::report(LogOutput& out) const +{ + out.enter("DeviceMemory::report(..)"); + out("_memoryRequirements = { size = ", _memoryRequirements.size, ", alignment = ", _memoryRequirements.alignment, ", _memoryRequirements = ", _memoryRequirements.memoryTypeBits, "}"); + out("_properties = ", _properties); + _memorySlots.report(out); + out.leave(); +} diff --git a/src/vsg/vk/MemoryBufferPools.cpp b/src/vsg/vk/MemoryBufferPools.cpp index e338a0723c..45da327229 100644 --- a/src/vsg/vk/MemoryBufferPools.cpp +++ b/src/vsg/vk/MemoryBufferPools.cpp @@ -314,3 +314,13 @@ VkResult MemoryBufferPools::reserve(ResourceRequirements& requirements) return VK_ERROR_OUT_OF_DEVICE_MEMORY; } } + +void MemoryBufferPools::report(LogOutput& out) const +{ + out.enter("MemoryBufferPools::report(..)"); + for(const auto& memoryPool : memoryPools) + { + memoryPool->report(out); + } + out.leave(); +} From a4f8fd30d11ba4c4ec9612af2d339d96693a4c1b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 9 Mar 2026 11:58:31 +0000 Subject: [PATCH 03/80] Fixed typo bug in DeleteQueue::clear() --- src/vsg/threading/DeleteQueue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vsg/threading/DeleteQueue.cpp b/src/vsg/threading/DeleteQueue.cpp index 8165842082..bd9ecb0d7f 100644 --- a/src/vsg/threading/DeleteQueue.cpp +++ b/src/vsg/threading/DeleteQueue.cpp @@ -86,7 +86,7 @@ void DeleteQueue::clear() // use a swap of the container to keep the time the mutex is acquired as short as possible { std::scoped_lock lock(_mutex); - objectsToDelete.swap(objectsToDelete); + objectsToDelete.swap(_objectsToDelete); } size_t numObjectsToDelete = objectsToDelete.size(); From 8476b31a668a0c46603d18dffd36769b5d107f3f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 9 Mar 2026 18:24:02 +0000 Subject: [PATCH 04/80] Added deleted subgraph count to DeleteQueue::wait_then_clear() and DeleteQueue::clear(). --- include/vsg/threading/DeleteQueue.h | 8 ++++++-- src/vsg/threading/DeleteQueue.cpp | 22 +++++++++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/include/vsg/threading/DeleteQueue.h b/include/vsg/threading/DeleteQueue.h index c87e74e462..096dfefa51 100644 --- a/include/vsg/threading/DeleteQueue.h +++ b/include/vsg/threading/DeleteQueue.h @@ -112,9 +112,13 @@ namespace vsg _cv.notify_one(); } - void wait_then_clear(); + /// wait till there are items to delete then delete objects scheduled for deletion more than retainForFrameCount, + /// return number of objects assigned directly to DeleteQeue that have been deleted (doesn't count children deleted.) + size_t wait_then_clear(); - void clear(); + /// immediately delete objects scheduled for deletion for more than retainForFrameCount, + /// return number of objects assigned directly to DeleteQeue that have been deleted (doesn't count children deleted.) + size_t clear(); protected: virtual ~DeleteQueue(); diff --git a/src/vsg/threading/DeleteQueue.cpp b/src/vsg/threading/DeleteQueue.cpp index bd9ecb0d7f..36536e08b3 100644 --- a/src/vsg/threading/DeleteQueue.cpp +++ b/src/vsg/threading/DeleteQueue.cpp @@ -41,7 +41,7 @@ void DeleteQueue::advance(ref_ptr frameStamp) } } -void DeleteQueue::wait_then_clear() +size_t DeleteQueue::wait_then_clear() { ObjectsToDelete objectsToDelete; std::list> sharedObjectsToPrune; @@ -77,29 +77,41 @@ void DeleteQueue::wait_then_clear() } sharedObjectsToPrune.clear(); } + + return numObjectsToDelete; } -void DeleteQueue::clear() +size_t DeleteQueue::clear() { ObjectsToDelete objectsToDelete; + std::list> sharedObjectsToPrune; // use a swap of the container to keep the time the mutex is acquired as short as possible { std::scoped_lock lock(_mutex); - objectsToDelete.swap(_objectsToDelete); + + auto last_itr = std::find_if(_objectsToDelete.begin(), _objectsToDelete.end(), [&](const ObjectToDelete& otd) { return otd.frameCount > frameCount; }); + + // use a swap of the container to keep the time the mutex is acquired as short as possible + objectsToDelete.splice(objectsToDelete.end(), _objectsToDelete, _objectsToDelete.begin(), last_itr); + + sharedObjectsToPrune.swap(_sharedObjectsToPrune); } size_t numObjectsToDelete = objectsToDelete.size(); //vsg::info("DeleteQueue::clear(), releasing ", nodesToRelease.size()); + objectsToDelete.clear(); if (numObjectsToDelete > 0) { - for (auto& sharedObjects : _sharedObjectsToPrune) + for (auto& sharedObjects : sharedObjectsToPrune) { sharedObjects->prune(); } - _sharedObjectsToPrune.clear(); + sharedObjectsToPrune.clear(); } + + return numObjectsToDelete; } From a061dbb59c556fc928331907cce4cd2902e4e9d4 Mon Sep 17 00:00:00 2001 From: KAlO2 Date: Mon, 23 Mar 2026 21:57:59 +0800 Subject: [PATCH 05/80] fix: correct typo in comment and remove redundant semicolon --- include/vsg/utils/Instrumentation.h | 20 ++++++++++---------- src/vsg/vk/Device.cpp | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/vsg/utils/Instrumentation.h b/include/vsg/utils/Instrumentation.h index ffaebae847..2c10ca52c2 100644 --- a/include/vsg/utils/Instrumentation.h +++ b/include/vsg/utils/Instrumentation.h @@ -54,21 +54,21 @@ namespace vsg virtual ref_ptr shareOrDuplicateForThreadSafety() { return ref_ptr(this); } - virtual void setThreadName(const std::string& /*name*/) const {}; + virtual void setThreadName(const std::string& /*name*/) const {} - virtual void enterFrame(const SourceLocation* /*sl*/, uint64_t& /*reference*/, FrameStamp& /*frameStamp*/) const {}; - virtual void leaveFrame(const SourceLocation* /*sl*/, uint64_t& /*reference*/, FrameStamp& /*frameStamp*/) const {}; + virtual void enterFrame(const SourceLocation* /*sl*/, uint64_t& /*reference*/, FrameStamp& /*frameStamp*/) const {} + virtual void leaveFrame(const SourceLocation* /*sl*/, uint64_t& /*reference*/, FrameStamp& /*frameStamp*/) const {} - virtual void enter(const SourceLocation* /*sl*/, uint64_t& /*reference*/, const Object* /*object*/ = nullptr) const {}; - virtual void leave(const SourceLocation* /*sl*/, uint64_t& /*reference*/, const Object* /*object*/ = nullptr) const {}; + virtual void enter(const SourceLocation* /*sl*/, uint64_t& /*reference*/, const Object* /*object*/ = nullptr) const {} + virtual void leave(const SourceLocation* /*sl*/, uint64_t& /*reference*/, const Object* /*object*/ = nullptr) const {} - virtual void enterCommandBuffer(const SourceLocation* /*sl*/, uint64_t& /*reference*/, CommandBuffer& /*commandBuffer*/) const {}; - virtual void leaveCommandBuffer(const SourceLocation* /*sl*/, uint64_t& /*reference*/, CommandBuffer& /*commandBuffer*/) const {}; + virtual void enterCommandBuffer(const SourceLocation* /*sl*/, uint64_t& /*reference*/, CommandBuffer& /*commandBuffer*/) const {} + virtual void leaveCommandBuffer(const SourceLocation* /*sl*/, uint64_t& /*reference*/, CommandBuffer& /*commandBuffer*/) const {} - virtual void enter(const SourceLocation* /*sl*/, uint64_t& /*reference*/, CommandBuffer& /*commandBuffer*/, const Object* /*object*/ = nullptr) const {}; - virtual void leave(const SourceLocation* /*sl*/, uint64_t& /*reference*/, CommandBuffer& /*commandBuffer*/, const Object* /*object*/ = nullptr) const {}; + virtual void enter(const SourceLocation* /*sl*/, uint64_t& /*reference*/, CommandBuffer& /*commandBuffer*/, const Object* /*object*/ = nullptr) const {} + virtual void leave(const SourceLocation* /*sl*/, uint64_t& /*reference*/, CommandBuffer& /*commandBuffer*/, const Object* /*object*/ = nullptr) const {} - virtual void finish() const {}; + virtual void finish() const {} protected: virtual ~Instrumentation(); diff --git a/src/vsg/vk/Device.cpp b/src/vsg/vk/Device.cpp index 61f00211b5..d843a007d4 100644 --- a/src/vsg/vk/Device.cpp +++ b/src/vsg/vk/Device.cpp @@ -22,7 +22,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI using namespace vsg; -// thread safe container for managing the deviceID for each vsg;:Device +// thread safe container for managing the deviceID for each vsg::Device static std::mutex s_DeviceCountMutex; static std::vector s_ActiveDevices; From 43847571881e63c6d7b6b01ef93f0ccfced1b4c8 Mon Sep 17 00:00:00 2001 From: Carsten Date: Fri, 27 Mar 2026 09:59:04 +0000 Subject: [PATCH 06/80] Fixed inconsistent forward decaration of struct LogOutput. --- include/vsg/core/MemorySlots.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/vsg/core/MemorySlots.h b/include/vsg/core/MemorySlots.h index 7d3ccab3da..59775f5011 100644 --- a/include/vsg/core/MemorySlots.h +++ b/include/vsg/core/MemorySlots.h @@ -32,7 +32,7 @@ namespace vsg }; // forward declare - class LogOutput; + struct LogOutput; /** class used internally by vsg::Allocator, vsg::DeviceMemory and vsg::Buffer to manage suballocation within a block of CPU or GPU memory.*/ class VSG_DECLSPEC MemorySlots From 767ecb1987c3067985f187227cae1015b76d8533 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 27 Mar 2026 10:23:32 +0000 Subject: [PATCH 07/80] Bumped Vulkan SDK version --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d858edc506..9861a58fec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,12 +10,12 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - vulkan-version: [1.3.268.0] + vulkan-version: [1.4.341.1] build-shared: [OFF] include: - build-shared: ON os: windows-latest - vulkan-version: 1.3.268.0 + vulkan-version: 1.4.341.1 continue-on-error: ${{ matrix.vulkan-version == 'latest' }} steps: From eb48cb6fab935b777271aa72bac499811a8a6d2a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 27 Mar 2026 11:26:45 +0000 Subject: [PATCH 08/80] Attempt to temporarily fix automated build by disabled macos --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9861a58fec..ce72efa27d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,8 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, macos-latest, windows-latest] +# os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest, windows-latest] vulkan-version: [1.4.341.1] build-shared: [OFF] include: From 1730bef31385ee6481b1281954e0ca712e88d509 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 27 Mar 2026 11:59:51 +0000 Subject: [PATCH 09/80] Leave Linux as testbuild for now. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ce72efa27d..21a2626241 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: # os: [ubuntu-latest, macos-latest, windows-latest] - os: [ubuntu-latest, windows-latest] + os: [ubuntu-latest] vulkan-version: [1.4.341.1] build-shared: [OFF] include: From 1254c31334849ab3bcd2a53cfb670627917789a6 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 27 Mar 2026 17:36:46 +0000 Subject: [PATCH 10/80] Updated versions of projects pulled in. Temporarily disabled macos and windows due to avoid errors on these platforms. --- .github/workflows/ci.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 21a2626241..d1e55b5fe2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,20 +9,21 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: -# os: [ubuntu-latest, macos-latest, windows-latest] + # os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest] vulkan-version: [1.4.341.1] build-shared: [OFF] - include: - - build-shared: ON - os: windows-latest - vulkan-version: 1.4.341.1 + # include: + # - build-shared: ON + # os: windows-latest + # vulkan-version: 1.4.341.1 + continue-on-error: ${{ matrix.vulkan-version == 'latest' }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup cmake - uses: jwlawson/actions-setup-cmake@v1.12 + uses: jwlawson/actions-setup-cmake@v2.2.0 with: cmake-version: ${{ env.CMakeVersion }} - name: Install Vulkan SDK @@ -31,7 +32,7 @@ jobs: version: ${{ matrix.vulkan-version }} cache: true - name: Add MSBuild to PATH - uses: microsoft/setup-msbuild@v2 + uses: microsoft/setup-msbuild@v3 if: startsWith(matrix.os, 'windows') - name: Build and Install VSG shell: bash From 876ee20f0f424c1afd649cabe0c3e494578fab03 Mon Sep 17 00:00:00 2001 From: Nolan Kramer Date: Sun, 5 Apr 2026 20:27:13 -0700 Subject: [PATCH 11/80] Fix macOS window embedding --- include/vsg/platform/macos/MacOS_Window.h | 2 +- src/vsg/platform/macos/MacOS_Window.mm | 75 +++++++++++++++++++---- 2 files changed, 65 insertions(+), 12 deletions(-) diff --git a/include/vsg/platform/macos/MacOS_Window.h b/include/vsg/platform/macos/MacOS_Window.h index 21b9331680..ddaeaaf0e9 100644 --- a/include/vsg/platform/macos/MacOS_Window.h +++ b/include/vsg/platform/macos/MacOS_Window.h @@ -57,7 +57,7 @@ namespace vsgMacOS const char* instanceExtensionSurfaceName() const override { return "VK_MVK_macos_surface"; } - bool valid() const override { return _window; } + bool valid() const override { return _window || _view; } bool pollEvents(vsg::UIEvents& events) override; diff --git a/src/vsg/platform/macos/MacOS_Window.mm b/src/vsg/platform/macos/MacOS_Window.mm index 8b0da4bea9..4df5927d08 100644 --- a/src/vsg/platform/macos/MacOS_Window.mm +++ b/src/vsg/platform/macos/MacOS_Window.mm @@ -708,10 +708,58 @@ void createApplicationMenus(void) } MacOS_Window::MacOS_Window(vsg::ref_ptr traits) : - Inherit(traits) + Inherit(traits), + _window(nil), + _view(nil), + _metalLayer(nil) { _keyboard = new KeyboardMap; + // When nativeWindow is set, embed into the provided NSView rather than + // creating a standalone NSWindow. This mirrors Win32_Window's handling + // of an external HWND. + if (traits->nativeWindow.has_value()) + { + auto nativeHandle = std::any_cast(traits->nativeWindow); + if (nativeHandle) + { + NSView* externalView = reinterpret_cast(nativeHandle); + _view = (vsg_MacOS_NSView*)externalView; + [_view setWantsLayer:YES]; + + _metalLayer = (CAMetalLayer*)[_view layer]; + if (!_metalLayer || ![_metalLayer isKindOfClass:[CAMetalLayer class]]) + { + _metalLayer = [[CAMetalLayer alloc] init]; + if (!_metalLayer) + { + throw Exception{"Error: vsg::MacOS_Window::MacOS_Window(...) failed to create CAMetalLayer for embedded view.", VK_ERROR_INVALID_EXTERNAL_HANDLE}; + } + [_view setLayer:_metalLayer]; + } + + auto devicePixelScale = _traits->hdpi ? [[_view window] backingScaleFactor] : 1.0f; + [_metalLayer setContentsScale:devicePixelScale]; + + uint32_t finalwidth = traits->width * devicePixelScale; + uint32_t finalheight = traits->height * devicePixelScale; + + if (traits->device) share(traits->device); + + _extent2D.width = finalwidth; + _extent2D.height = finalheight; + + _first_macos_timestamp = [[NSProcessInfo processInfo] systemUptime]; + _first_macos_time_point = vsg::clock::now(); + + vsg::clock::time_point event_time = vsg::clock::now(); + bufferedEvents.emplace_back(vsg::ConfigureWindowEvent::create(this, event_time, _traits->x, _traits->y, finalwidth, finalheight)); + + return; + } + } + + // Standalone window path NSRect contentRect = NSMakeRect(0, 0, traits->width, traits->height); NSWindowStyleMask styleMask = 0; @@ -822,16 +870,20 @@ void createApplicationMenus(void) bool MacOS_Window::pollEvents(vsg::UIEvents& events) { - for (;;) + // Skip NSApp event polling when embedded — the host owns the event loop. + if (_window) { - NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny - untilDate:[NSDate distantPast] - inMode:NSDefaultRunLoopMode - dequeue:YES]; - if (event == nil) - break; - - [NSApp sendEvent:event]; + for (;;) + { + NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny + untilDate:[NSDate distantPast] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + if (event == nil) + break; + + [NSApp sendEvent:event]; + } } return Window::pollEvents(events); @@ -841,7 +893,8 @@ void createApplicationMenus(void) { const NSRect contentRect = [_view frame]; - auto devicePixelScale = _traits->hdpi ? [_window backingScaleFactor] : 1.0f; + NSWindow* hostWindow = _window ? _window : [_view window]; + auto devicePixelScale = _traits->hdpi ? [hostWindow backingScaleFactor] : 1.0f; //[_metalLayer setContentsScale:devicePixelScale]; _extent2D.width = contentRect.size.width * devicePixelScale; From bed923092e1139716a66659c9e6e5ae727f27362 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 10 Apr 2026 14:25:33 +0100 Subject: [PATCH 12/80] Added ResourceSavanger and expiry of stale PagedLOD requests. --- include/vsg/app/CompileManager.h | 17 +++++ include/vsg/core/observer_ptr.h | 3 + include/vsg/io/DatabasePager.h | 16 +++-- include/vsg/nodes/PagedLOD.h | 3 + include/vsg/threading/DeleteQueue.h | 1 + src/vsg/app/CompileManager.cpp | 108 +++++++++++++++++++++++++++- src/vsg/io/DatabasePager.cpp | 93 +++++++++++++++++++++--- src/vsg/threading/DeleteQueue.cpp | 4 ++ 8 files changed, 231 insertions(+), 14 deletions(-) diff --git a/include/vsg/app/CompileManager.h b/include/vsg/app/CompileManager.h index dff3c9f905..4c88bd8e00 100644 --- a/include/vsg/app/CompileManager.h +++ b/include/vsg/app/CompileManager.h @@ -39,6 +39,20 @@ namespace vsg bool requiresViewerUpdate() const; }; + /// ResourceScavanger provides a mechanism for releasing and reusing unused resources + class VSG_DECLSPEC ResourceScavanger : public Inherit + { + public: + + ResourceScavanger(ref_ptr in_databasePager); + + virtual bool scavange(ResourceRequirements& resourceRequirements); + + observer_ptr databasePager; + + uint32_t numFailures = 0; + }; + /// CompileManager is a helper class that compiles subgraphs for the windows/framebuffers associated with the CompileManager. class VSG_DECLSPEC CompileManager : public Inherit { @@ -71,6 +85,9 @@ namespace vsg /// compile all the command graphs in a task CompileResult compileTask(ref_ptr task, const ResourceRequirements& resourceRequirements = {}); + /// mechinism for releasing and reusing used resources + ref_ptr resourceScavenger; + protected: using CompileTraversals = ThreadSafeQueue>; size_t numCompileTraversals = 0; diff --git a/include/vsg/core/observer_ptr.h b/include/vsg/core/observer_ptr.h index c37633d46d..55850f3893 100644 --- a/include/vsg/core/observer_ptr.h +++ b/include/vsg/core/observer_ptr.h @@ -185,6 +185,9 @@ namespace vsg return {}; } + /// We strongly recommend access via ref_ptr<> rather than get(). Only use get() to get access to the raw C pointer when it's know that the object pointed to will remain in memory through use of that raw C pointer. + T* get() const noexcept { return _ptr; } + protected: template friend class observer_ptr; diff --git a/include/vsg/io/DatabasePager.h b/include/vsg/io/DatabasePager.h index 9b01c0649b..05922a302f 100644 --- a/include/vsg/io/DatabasePager.h +++ b/include/vsg/io/DatabasePager.h @@ -104,7 +104,10 @@ namespace vsg void add(ref_ptr plod, const CompileResult& cr); - ref_ptr take_when_available(); + /// prune entries older than specified frameCount + uint32_t prune(uint64_t frameCount); + + ref_ptr take_when_available(uint64_t frameCount); Nodes take_all(CompileResult& result); @@ -138,13 +141,17 @@ namespace vsg ref_ptr compileManager; std::atomic_uint numActiveRequests{0}; - std::atomic_uint64_t frameCount; + std::atomic_uint64_t frameCount{0}; ref_ptr culledPagedLODs; /// for systems with smaller GPU memory limits you may need to reduce the targetMaxNumPagedLODWithHighResSubgraphs to keep memory usage within available limits. uint32_t targetMaxNumPagedLODWithHighResSubgraphs = 1500; + /// number of frames before a PagedLOD with a failed load/compile is attempted to be loaded/compiled again. + uint64_t delayBeforeNextLoadAttempt = 60; + + std::mutex pendingPagedLODMutex; ref_ptr pagedLODContainer; @@ -158,16 +165,17 @@ namespace vsg /// read and delete threads created by start() std::list threads; + ref_ptr _deleteQueue; + ref_ptr _status; + protected: virtual ~DatabasePager(); void requestDiscarded(PagedLOD* plod); - ref_ptr _status; ref_ptr _requestQueue; ref_ptr _toMergeQueue; - ref_ptr _deleteQueue; }; VSG_type_name(vsg::DatabasePager); diff --git a/include/vsg/nodes/PagedLOD.h b/include/vsg/nodes/PagedLOD.h index 607761ffdf..cdd09e30d5 100644 --- a/include/vsg/nodes/PagedLOD.h +++ b/include/vsg/nodes/PagedLOD.h @@ -89,6 +89,9 @@ namespace vsg mutable std::atomic_uint64_t frameHighResLastUsed{0}; mutable std::atomic_uint requestCount{0}; + mutable std::atomic_uint64_t frameNextLoadAttempt{0}; + mutable std::atomic_uint64_t loadAttempts{0}; + enum RequestStatus : unsigned int { NoRequest = 0, diff --git a/include/vsg/threading/DeleteQueue.h b/include/vsg/threading/DeleteQueue.h index 096dfefa51..e77027cc24 100644 --- a/include/vsg/threading/DeleteQueue.h +++ b/include/vsg/threading/DeleteQueue.h @@ -37,6 +37,7 @@ namespace vsg std::atomic_uint64_t frameCount = 0; uint64_t retainForFrameCount = 3; + std::atomic_uint64_t deletedCount = 0; ActivityStatus* getStatus() { return _status; } const ActivityStatus* getStatus() const { return _status; } diff --git a/src/vsg/app/CompileManager.cpp b/src/vsg/app/CompileManager.cpp index cdd28de2ad..e8d4df5ff0 100644 --- a/src/vsg/app/CompileManager.cpp +++ b/src/vsg/app/CompileManager.cpp @@ -21,6 +21,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI using namespace vsg; +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// CompileResult +// void CompileResult::reset() { result = VK_INCOMPLETE; @@ -66,6 +70,75 @@ bool CompileResult::requiresViewerUpdate() const return false; } +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// CompileManager +// + +ResourceScavanger::ResourceScavanger(ref_ptr in_databasePager) : + databasePager(in_databasePager) +{ +} + +bool ResourceScavanger::scavange(ResourceRequirements& resourceRequirements) +{ + ++numFailures; + + bool scavanged = false; + + if (auto ref_databasePager = databasePager.get()) + { + if (!ref_databasePager->_status->active()) return false; + + + uint32_t targetPagedLOD = ref_databasePager->pagedLODContainer->activeList.count; + if (ref_databasePager->pagedLODContainer->inactiveList.count > ref_databasePager->numActiveRequests) targetPagedLOD += ref_databasePager->pagedLODContainer->inactiveList.count - ref_databasePager->numActiveRequests; + + // vsg::info(" ResourceScavanger::scavange(..) activeList.count = ", ref_databasePager->pagedLODContainer->activeList.count, ", inactiveList.count = ", ref_databasePager->pagedLODContainer->inactiveList.count, ", numActiveRequests = ", ref_databasePager->numActiveRequests); + if (targetPagedLOD < ref_databasePager->targetMaxNumPagedLODWithHighResSubgraphs) + { + vsg::info(" ResourceScavanger::scavange(..) resetting, ref_databasePager->targetMaxNumPagedLODWithHighResSubgraphs, to ", targetPagedLOD, " numFailures = ", numFailures); + + ref_databasePager->targetMaxNumPagedLODWithHighResSubgraphs = targetPagedLOD; + } + else + { + // vsg::info(" ResourceScavanger::scavange(ResourceRequirements& resourceRequirements) resourceRequirements.bufferInfos.size() = ", resourceRequirements.bufferInfos.size(), ", resourceRequirements.imageInfos.size() = ", resourceRequirements.imageInfos.size(), " nothing to do. numFailures = ", numFailures); + } + +#if 0 + + return false; +#else + auto before_deletedCount = ref_databasePager->_deleteQueue->deletedCount.load(); + + // vsg::info(" Before sleep: inactiveList.count = ", ref_databasePager->pagedLODContainer->inactiveList.count); + +#if 1 + std::this_thread::sleep_for(std::chrono::milliseconds(16*5)); + uint32_t numDeleted = 0; +#else + //std::this_thread::sleep_for(std::chrono::milliseconds(16*5)); + //std::this_thread::sleep_for(std::chrono::milliseconds(16*24)); + //std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + auto numDeleted = ref_databasePager->_deleteQueue->wait_then_clear(); +#endif + auto after_deletedCount = ref_databasePager->_deleteQueue->deletedCount.load(); + + scavanged = (after_deletedCount > before_deletedCount); + + // vsg::info(" After sleep: inactiveList.count = ", ref_databasePager->pagedLODContainer->inactiveList.count, ", delta =", after_deletedCount - before_deletedCount, ", scavanged = ", scavanged, ", numDeleted = ", numDeleted); + // vsg::info(" Finished ResourceScavanger::scavange(ResourceRequirements& resourceRequirements) resourceRequirements.bufferInfos.size() = ", resourceRequirements.bufferInfos.size(), ", resourceRequirements.imageInfos.size() = ", resourceRequirements.imageInfos.size(), " resetting."); + } +#endif + + return scavanged; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// CompileManager +// CompileManager::CompileManager(Viewer& viewer, ref_ptr hints) { compileTraversals = CompileTraversals::create(viewer.status); @@ -167,6 +240,7 @@ CompileResult CompileManager::compile(ref_ptr object, ContextSelectionFu auto& requirements = collectRequirements.requirements; auto& viewDetailsStack = requirements.viewDetailsStack; + VkResult reserve_result = VK_INCOMPLETE; CompileResult result; result.maxSlots = requirements.maxSlots; result.containsPagedLOD = requirements.containsPagedLOD; @@ -199,9 +273,24 @@ CompileResult CompileManager::compile(ref_ptr object, ContextSelectionFu } } } + } + + for (auto& context : compileTraversal->contexts) + { + reserve_result = context->reserve(requirements); + + // vsg::info(" done reserve context->reserve() ", reserve_result); + if (reserve_result != VK_SUCCESS && resourceScavenger && resourceScavenger->scavange(requirements)) + { + reserve_result = context->reserve(requirements); + } - auto reserveResult = context->reserve(requirements); - if (reserveResult != VK_SUCCESS) throw vsg::Exception{"Context::reserve() failed", reserveResult}; + if (reserve_result != VK_SUCCESS) + { + result.message = vsg::make_string("Context::reserve() failed", reserve_result); + result.result = reserve_result; + return; + } } object->accept(*compileTraversal); @@ -251,6 +340,21 @@ CompileResult CompileManager::compile(ref_ptr object, ContextSelectionFu compileTraversals->add(compileTraversal); + static int s_succeeded = 0; + static int s_failed = 0; + + if (result.result == VK_SUCCESS) + { + ++s_succeeded; + vsg::info("Success : succedded = ", s_succeeded, ", failed = ", s_failed, ", result = { ", result.result, " : ", result.message, " }, reserve_result = ", reserve_result); + } + else + { + s_failed++; + + vsg::info("Failed : succedded = ", s_succeeded, ", failed = ", s_failed, ", result = { ", result.result, " : ", result.message, " }, reserve_result = ", reserve_result); + } + return result; } diff --git a/src/vsg/io/DatabasePager.cpp b/src/vsg/io/DatabasePager.cpp index ee7527b172..03a50a58ea 100644 --- a/src/vsg/io/DatabasePager.cpp +++ b/src/vsg/io/DatabasePager.cpp @@ -394,7 +394,7 @@ void DatabaseQueue::add(ref_ptr plod, const CompileResult& cr) _compileResult.add(cr); } -ref_ptr DatabaseQueue::take_when_available() +ref_ptr DatabaseQueue::take_when_available(uint64_t frameCount) { // debug("DatabaseQueue::take_when_available() A size = ", _queue.size()); @@ -419,20 +419,58 @@ ref_ptr DatabaseQueue::take_when_available() // find the PagedLOD with the highest priority; auto itr = _queue.begin(); + + size_t skipped = 0; + + // find first PagedLOD in queue that can be loaded/compiled + for(; itr != _queue.end(); ++itr) + { + if ((*itr)->frameNextLoadAttempt.load() <= frameCount) break; + ++skipped; + } + + if (itr == _queue.end()) + { + // info("DatabaseQueue::take_when_available(", frameCount, ") no suitable PagedLOD despite ", _queue.size(), " in queue."); + return {}; + } + auto highest_itr = itr++; + // find lowest priority PagedLOD in queue. for (; itr != _queue.end(); ++itr) { - if ((*itr)->priority > (*highest_itr)->priority) highest_itr = itr; + if ((*itr)->frameNextLoadAttempt.load() <= frameCount && (*itr)->priority > (*highest_itr)->priority) highest_itr = itr; } ref_ptr plod = *highest_itr; _queue.erase(highest_itr); - // debug("Returning ", plod.get(), std::dec, ", size = ", _queue.size()); + // info("DatabaseQueue::take_when_available(", frameCount, ") plod = ", plod.get(), std::dec, ", size = ", _queue.size(), " after skipping ", skipped); return plod; } +uint32_t DatabaseQueue::prune(uint64_t frameCount) +{ + std::unique_lock lock(_mutex); + + uint32_t numRemoved = 0; + for (auto itr = _queue.begin(); itr != _queue.end();) + { + if (((*itr)->frameHighResLastUsed.load()+1) < frameCount) + { + // info("pruning ", *itr, ", lastUsed = ", (*itr)->frameHighResLastUsed.load(), " vs ", frameCount, " after ", (*itr)->loadAttempts.load(), " loadAttempts"); + ++numRemoved; + itr = _queue.erase(itr); + } + else + { + ++itr; + } + } + return numRemoved; +} + DatabaseQueue::Nodes DatabaseQueue::take_all(CompileResult& cr) { std::scoped_lock lock(_mutex); @@ -492,21 +530,36 @@ void DatabasePager::start(uint32_t numReadThreads) while (status->active()) { - auto plod = requestQueue->take_when_available(); + auto plod = requestQueue->take_when_available(databasePager.frameCount.load()); if (plod) { CPU_INSTRUMENTATION_L1_NC(databasePager.instrumentation, "DatabasePager read", COLOR_PAGER); uint64_t frameDelta = databasePager.frameCount - plod->frameHighResLastUsed.load(); + + if (frameDelta > 1 || !compare_exchange(plod->requestStatus, PagedLOD::ReadRequest, PagedLOD::Reading)) { - // debug("Expire read request"); + info("Expire read request : databasePager.frameCount = ", databasePager.frameCount, ", plod->frameHighResLastUsed.load() = ", plod->frameHighResLastUsed.load()); databasePager.requestDiscarded(plod); continue; } - auto read_object = vsg::read(plod->filename, plod->options); - auto subgraph = read_object.cast(); + ++plod->loadAttempts; + + ref_ptr subgraph = plod->pending; + ref_ptr read_object; + + if (!subgraph) + { + // vsg::info("read ", subgraph, " from ", plod->filename, " frameDelta = ", frameDelta, ", databasePager.frameCount = ", databasePager.frameCount, ", plod->frameHighResLastUsed.load() = ", plod->frameHighResLastUsed.load(), ", numActiveRequests = ", databasePager.numActiveRequests.load()); + read_object = vsg::read(plod->filename, plod->options); + subgraph = read_object.cast(); + } + else + { + // vsg::info("already read ", subgraph, " from ", plod->filename, " frameDelta = ", frameDelta, ", databasePager.frameCount = ", databasePager.frameCount, ", plod->frameHighResLastUsed.load() = ", plod->frameHighResLastUsed.load(), ", numActiveRequests = ", databasePager.numActiveRequests.load()); + } if (subgraph && compare_exchange(plod->requestStatus, PagedLOD::Reading, PagedLOD::Compiling)) { @@ -522,6 +575,8 @@ void DatabasePager::start(uint32_t numReadThreads) { plod->requestStatus.exchange(PagedLOD::MergeRequest); + // info("DatabaserPager::start() compiled ", subgraph, ", success after ", plod->loadAttempts.load(), " loadAttempts"); + // move to the merge queue; databasePager._toMergeQueue->add(plod, result); } @@ -547,6 +602,11 @@ void DatabasePager::start(uint32_t numReadThreads) databasePager.requestDiscarded(plod); } } + else + { + // sleep for a frame. + std::this_thread::sleep_for(std::chrono::milliseconds(16*2)); + } } debug("Finished DatabaseThread read thread"); }; @@ -574,6 +634,7 @@ void DatabasePager::start(uint32_t numReadThreads) void DatabasePager::request(ref_ptr plod) { +#if 0 ++numActiveRequests; bool hasPending = false; @@ -598,6 +659,16 @@ void DatabasePager::request(ref_ptr plod) { // debug("Attempted DatabasePager::request(", plod.get(), ") but plod.pending is not null."); } +#else + + if (compare_exchange(plod->requestStatus, PagedLOD::NoRequest, PagedLOD::ReadRequest)) + { + // debug("DatabasePager::request(", plod.get(), ") adding to requestQueue ", plod->filename, ", ", plod->priority, " plod=", plod.get()); + _requestQueue->add(plod); + ++numActiveRequests; + } + +#endif } void DatabasePager::requestDiscarded(PagedLOD* plod) @@ -606,7 +677,11 @@ void DatabasePager::requestDiscarded(PagedLOD* plod) //plod->pending = nullptr; plod->requestCount.exchange(0); plod->requestStatus.exchange(PagedLOD::NoRequest); - plod->pending = {}; + + // plod->pending = {}; + + plod->frameNextLoadAttempt = frameCount.load() + delayBeforeNextLoadAttempt; + --numActiveRequests; } @@ -617,6 +692,8 @@ void DatabasePager::updateSceneGraph(ref_ptr frameStamp, CompileResu frameCount.exchange(frameStamp ? frameStamp->frameCount : 0); _deleteQueue->advance(frameStamp); + numActiveRequests -= _requestQueue->prune(frameCount.load()); + auto nodes = _toMergeQueue->take_all(cr); std::list> deleteList; diff --git a/src/vsg/threading/DeleteQueue.cpp b/src/vsg/threading/DeleteQueue.cpp index 36536e08b3..df97f8155e 100644 --- a/src/vsg/threading/DeleteQueue.cpp +++ b/src/vsg/threading/DeleteQueue.cpp @@ -78,6 +78,8 @@ size_t DeleteQueue::wait_then_clear() sharedObjectsToPrune.clear(); } + deletedCount += numObjectsToDelete; + return numObjectsToDelete; } @@ -113,5 +115,7 @@ size_t DeleteQueue::clear() sharedObjectsToPrune.clear(); } + deletedCount += numObjectsToDelete; + return numObjectsToDelete; } From 8e26c1917b48dd92349138680135061f496d53ef Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 10 Apr 2026 16:28:29 +0100 Subject: [PATCH 13/80] Added cusomt alginment version of DeviceMemory::reserve(..) --- include/vsg/vk/DeviceMemory.h | 1 + src/vsg/vk/DeviceMemory.cpp | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/vsg/vk/DeviceMemory.h b/include/vsg/vk/DeviceMemory.h index 3e5d58a6b4..a2db80a092 100644 --- a/include/vsg/vk/DeviceMemory.h +++ b/include/vsg/vk/DeviceMemory.h @@ -44,6 +44,7 @@ namespace vsg const VkMemoryPropertyFlags& getMemoryPropertyFlags() const { return _properties; } MemorySlots::OptionalOffset reserve(VkDeviceSize size); + MemorySlots::OptionalOffset reserve(VkDeviceSize size, VkDeviceSize alignment); void release(VkDeviceSize offset, VkDeviceSize size); bool full() const; diff --git a/src/vsg/vk/DeviceMemory.cpp b/src/vsg/vk/DeviceMemory.cpp index 674a18f9fb..1b557164af 100644 --- a/src/vsg/vk/DeviceMemory.cpp +++ b/src/vsg/vk/DeviceMemory.cpp @@ -87,7 +87,7 @@ DeviceMemory::DeviceMemory(Device* device, const VkMemoryRequirements& memRequir if (VkResult result = vkAllocateMemory(*device, &allocateInfo, _device->getAllocationCallbacks(), &_deviceMemory); result != VK_SUCCESS) { - throw Exception{"Error: Failed to allocate DeviceMemory.", result}; + throw Exception{"Error: Failed to allocate vsg::DeviceMemory.", result}; } { @@ -156,6 +156,12 @@ MemorySlots::OptionalOffset DeviceMemory::reserve(VkDeviceSize size) return _memorySlots.reserve(size, _memoryRequirements.alignment); } +MemorySlots::OptionalOffset DeviceMemory::reserve(VkDeviceSize size, VkDeviceSize alignment) +{ + std::scoped_lock lock(_mutex); + return _memorySlots.reserve(size, alignment); +} + void DeviceMemory::release(VkDeviceSize offset, VkDeviceSize size) { std::scoped_lock lock(_mutex); @@ -194,7 +200,7 @@ size_t DeviceMemory::totalMemorySize() const void DeviceMemory::report(LogOutput& out) const { out.enter("DeviceMemory::report(..)"); - out("_memoryRequirements = { size = ", _memoryRequirements.size, ", alignment = ", _memoryRequirements.alignment, ", _memoryRequirements = ", _memoryRequirements.memoryTypeBits, "}"); + out("_memoryRequirements = { size = ", _memoryRequirements.size, ", alignment = ", _memoryRequirements.alignment, ", memoryTypeBits = ", _memoryRequirements.memoryTypeBits, "}"); out("_properties = ", _properties); _memorySlots.report(out); out.leave(); From 29b2f0865109a54a95021a95fc8e1728dc1bb7bb Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 10 Apr 2026 16:54:11 +0100 Subject: [PATCH 14/80] Added resizing of buffers to fit with available memory and relaxed memory flag relaxation when find available memory --- include/vsg/vk/Device.h | 3 + src/vsg/vk/Device.cpp | 32 +++++ src/vsg/vk/MemoryBufferPools.cpp | 232 +++++++++++++++++++++++-------- 3 files changed, 207 insertions(+), 60 deletions(-) diff --git a/include/vsg/vk/Device.h b/include/vsg/vk/Device.h index f4f77ed176..11623b210a 100644 --- a/include/vsg/vk/Device.h +++ b/include/vsg/vk/Device.h @@ -88,6 +88,9 @@ namespace vsg /// return the amount of memory available in deviceMemoryBufferPools and allocatable on device VkDeviceSize availableMemory(bool includeMemoryPools = true) const; + /// return the amount of remaining memory, compatible with specified flags, available that can be allocated. + VkDeviceSize availableMemory(VkMemoryPropertyFlags memoryPropertiesFlags, double allocatedMemoryLimit = 1.0) const; + // provide observer_ptr to memory buffer, descriptor pools and transferTask so that these can be accessed when required observer_ptr deviceMemoryBufferPools; observer_ptr stagingMemoryBufferPools; diff --git a/src/vsg/vk/Device.cpp b/src/vsg/vk/Device.cpp index d843a007d4..fd69fe5b15 100644 --- a/src/vsg/vk/Device.cpp +++ b/src/vsg/vk/Device.cpp @@ -249,3 +249,35 @@ VkDeviceSize Device::availableMemory(bool includeMemoryPools) const return available; } + +VkDeviceSize Device::availableMemory(VkMemoryPropertyFlags memoryPropertiesFlags, double allocatedMemoryLimit) const +{ + VkPhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget; + memoryBudget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; + memoryBudget.pNext = nullptr; + + VkPhysicalDeviceMemoryProperties2 dmp; + dmp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2; + dmp.pNext = &memoryBudget; + + vkGetPhysicalDeviceMemoryProperties2(*(getPhysicalDevice()), &dmp); + + auto& memoryProperties = dmp.memoryProperties; + + VkDeviceSize availableSpace = 0; + for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i) + { + if ((memoryProperties.memoryTypes[i].propertyFlags & memoryPropertiesFlags) == memoryPropertiesFlags) // supported + { + uint32_t heapIndex = memoryProperties.memoryTypes[i].heapIndex; + + VkDeviceSize heapBudget = static_cast(static_cast(memoryBudget.heapBudget[heapIndex]) * allocatedMemoryLimit); + VkDeviceSize heapUsage = memoryBudget.heapUsage[heapIndex]; + VkDeviceSize heapAvailable = (heapUsage < heapBudget) ? heapBudget - heapUsage : 0; + availableSpace += heapAvailable; + + break; + } + } + return availableSpace; +} diff --git a/src/vsg/vk/MemoryBufferPools.cpp b/src/vsg/vk/MemoryBufferPools.cpp index 45da327229..4016657a70 100644 --- a/src/vsg/vk/MemoryBufferPools.cpp +++ b/src/vsg/vk/MemoryBufferPools.cpp @@ -94,8 +94,19 @@ ref_ptr MemoryBufferPools::reserveBuffer(VkDeviceSize totalSize, VkD } } } +#if 1 + VkDeviceSize availableMemory = device->availableMemory(memoryPropertiesFlags, allocatedMemoryLimit); + if (totalSize > availableMemory) + { + // info("MemoryBufferPools::reserveBuffer(", totalSize, ") insufficient memory ", availableMemory); + return {}; + } + VkDeviceSize deviceSize = std::max(totalSize, std::min(availableMemory, minimumBufferSize)); +#else VkDeviceSize deviceSize = std::max(totalSize, minimumBufferSize); +#endif + bufferInfo->buffer = Buffer::create(deviceSize, bufferUsageFlags, sharingMode); bufferInfo->buffer->compile(device); @@ -144,6 +155,21 @@ MemoryBufferPools::DeviceMemoryOffset MemoryBufferPools::reserveMemory(VkMemoryR ref_ptr deviceMemory; MemorySlots::OptionalOffset reservedSlot(false, 0); +#if 1 + for (auto& memoryPool : memoryPools) + { + if (((memoryPool->getMemoryRequirements().memoryTypeBits & memRequirements.memoryTypeBits) == memRequirements.memoryTypeBits) && + memoryPool->maximumAvailableSpace() >= totalSize) + { + reservedSlot = memoryPool->reserve(totalSize, memRequirements.alignment); + if (reservedSlot.first) + { + deviceMemory = memoryPool; + break; + } + } + } +#else for (auto& memoryPool : memoryPools) { if (memoryPool->getMemoryRequirements().memoryTypeBits == memRequirements.memoryTypeBits && @@ -158,64 +184,35 @@ MemoryBufferPools::DeviceMemoryOffset MemoryBufferPools::reserveMemory(VkMemoryR } } } +#endif if (!deviceMemory) { - VkDeviceSize availableSpace = std::max(minimumDeviceMemorySize, totalSize); - - if (allocatedMemoryLimit < 1.0) +#if 1 + VkDeviceSize availableMemory = device->availableMemory(memoryPropertiesFlags, allocatedMemoryLimit); + if (totalSize > availableMemory) { - VkPhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget; - memoryBudget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; - memoryBudget.pNext = nullptr; - - VkPhysicalDeviceMemoryProperties2 dmp; - dmp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2; - dmp.pNext = &memoryBudget; + info("MemoryBufferPools::reserveBuffer(", totalSize, ") insufficient memory ", availableMemory); + return {}; + } - vkGetPhysicalDeviceMemoryProperties2(*(device->getPhysicalDevice()), &dmp); + VkDeviceSize deviceSize = std::max(totalSize, std::min(availableMemory, minimumDeviceMemorySize)); +#else + VkDeviceSize deviceSize = std::max(totalSize, minimumDeviceMemorySize); +#endif - auto& memoryProperties = dmp.memoryProperties; + if (deviceSize <= availableMemory) + { - for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i) + try { - if ((memoryProperties.memoryTypes[i].propertyFlags & memoryPropertiesFlags) == memoryPropertiesFlags) // supported - { - uint32_t heapIndex = memoryProperties.memoryTypes[i].heapIndex; - - VkDeviceSize heapBudget = static_cast(static_cast(memoryBudget.heapBudget[heapIndex]) * allocatedMemoryLimit); - VkDeviceSize heapUsage = memoryBudget.heapUsage[heapIndex]; - VkDeviceSize heapAvailable = (heapUsage < heapBudget) ? heapBudget - heapUsage : 0; - availableSpace = heapAvailable; - - break; - } + deviceMemory = vsg::DeviceMemory::create(device, memRequirements, memoryPropertiesFlags, pNextAllocInfo); } - - VkDeviceSize minimumSpare = 0; //16*1024*1024; - if (availableSpace < minimumSpare) - availableSpace = 0; - else - availableSpace -= minimumSpare; - } - - if (totalSize <= availableSpace) - { - if (availableSpace < minimumDeviceMemorySize) + catch(...) { - debug("MemoryBufferPools::reserveMemory(", totalSize, ") reducing minimumDeviceMemorySize = ", minimumDeviceMemorySize, " to ", availableSpace); - minimumDeviceMemorySize = availableSpace; + // info("Could not allocate vsg::DeviceMemory(..) memRequirements.size = ", memRequirements.size); } - VkDeviceSize deviceMemorySize = std::max(totalSize, minimumDeviceMemorySize); - - // clamp to an aligned size - deviceMemorySize = ((deviceMemorySize + memRequirements.alignment - 1) / memRequirements.alignment) * memRequirements.alignment; - - //debug("Creating new local DeviceMemory"); - if (memRequirements.size < deviceMemorySize) memRequirements.size = deviceMemorySize; - - deviceMemory = vsg::DeviceMemory::create(device, memRequirements, memoryPropertiesFlags, pNextAllocInfo); if (deviceMemory) { reservedSlot = deviceMemory->reserve(totalSize); @@ -226,14 +223,36 @@ MemoryBufferPools::DeviceMemoryOffset MemoryBufferPools::reserveMemory(VkMemoryR } } } + + // vsg::info(" MemoryBufferPools::reserveMemory(totalSize = ", totalSize, " availableSpace = ", availableSpace, ") deviceMemory = ", deviceMemory); + +#if 0 else if (throwOutOfDeviceMemoryException) { throw vsg::Exception{"MemoryBufferPools::reserve() out of memory", VK_ERROR_OUT_OF_DEVICE_MEMORY}; } +#endif } + if (!reservedSlot.first) { +#if 0 + info("MemoryBufferPools::reserveMemory() failure totalSize = ", totalSize); + + LogOutput output; + output.enter("Failure to allocate, compatible MemoryPools with space {"); + for (auto& memoryPool : memoryPools) + { + if (memoryPool->getMemoryRequirements().memoryTypeBits == memRequirements.memoryTypeBits && + memoryPool->getMemoryRequirements().alignment == memRequirements.alignment && + memoryPool->maximumAvailableSpace() >= totalSize) + { + memoryPool->report(output); + } + } + output.leave(); +#endif debug("MemoryBufferPools::reserveMemory(", totalSize, ") failed, insufficient memory available."); return {}; } @@ -251,36 +270,84 @@ VkResult MemoryBufferPools::reserve(ResourceRequirements& requirements) VkMemoryPropertyFlags memoryPropertiesFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; // VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + decltype(requirements.bufferInfos) failed_bufferInfos; + decltype(requirements.imageInfos) failed_imageInfos; + +#if 1 // allocate bufferInfos VkDeviceSize failedBufferMemory = 0; + bool allocationSuccess = true; for (auto& [properties, bufferInfos] : requirements.bufferInfos) { + VkDeviceSize alignment = 4; + if ((properties.usageFlags & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) != 0) + alignment = limits.minUniformBufferOffsetAlignment; + else if ((properties.usageFlags & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) != 0) + alignment = limits.minStorageBufferOffsetAlignment; + for (auto& bufferInfo : bufferInfos) { if (!bufferInfo->buffer) { - VkDeviceSize alignment = 4; - if ((properties.usageFlags & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) != 0) - alignment = limits.minUniformBufferOffsetAlignment; - else if ((properties.usageFlags & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) != 0) - alignment = limits.minStorageBufferOffsetAlignment; + if (allocationSuccess) + { + debug("MemoryBufferPools::reserve(ResourceRequirements& requirements) properties.usageFlags = ", properties.usageFlags, ", alignment = ", alignment); - debug("MemoryBufferPools::reserve(ResourceRequirements& requirements) properties.usageFlags = ", properties.usageFlags, ", alignment = ", alignment); + auto newBufferInfo = reserveBuffer(bufferInfo->data->dataSize(), alignment, properties.usageFlags, properties.sharingMode, memoryPropertiesFlags); + if (newBufferInfo) + { + bufferInfo->take(*newBufferInfo); - auto newBufferInfo = reserveBuffer(bufferInfo->data->dataSize(), alignment, properties.usageFlags, properties.sharingMode, memoryPropertiesFlags); - if (newBufferInfo) + //info(" ALLOCATED usage = ", properties.usageFlags, ", alignment = ", alignment, ", bufferInfo->data = ", bufferInfo->data, ", offset = ", bufferInfo->offset, ", range = ", bufferInfo->range, ", buffer = ", bufferInfo->buffer, " ----- size = ", computeSize(*bufferInfo)); + } + else + { + // vsg::info("MemoryBufferPools::reserve() failed on ", bufferInfo, ", data = ", bufferInfo->data); + + allocationSuccess = false; + } + } + + if (!allocationSuccess) { - bufferInfo->take(*newBufferInfo); + failed_bufferInfos[properties].insert(bufferInfo); + failedBufferMemory += bufferInfo->computeDataSize(); + // vsg::info("MemoryBufferPools::reserve() failed bufferInfo = ", bufferInfo, ", ", bufferInfo->data, ", size = ", bufferInfo->computeDataSize()); + } + } + } + } - //info(" ALLOCATED usage = ", properties.usageFlags, ", alignment = ", alignment, ", bufferInfo->data = ", bufferInfo->data, ", offset = ", bufferInfo->offset, ", range = ", bufferInfo->range, ", buffer = ", bufferInfo->buffer, " ----- size = ", computeSize(*bufferInfo)); + // allocate images + VkDeviceSize failedImageMemory = 0; + for (auto& imageInfo : requirements.imageInfos) + { + if (imageInfo->imageView && imageInfo->imageView->image && imageInfo->imageView->image->getDeviceMemory(deviceID) == 0) + { + if (allocationSuccess) + { + auto image_result = imageInfo->imageView->image->compile(*this); + if (image_result == VK_SUCCESS && imageInfo->imageView->image->getDeviceMemory(deviceID) != 0) + { + //info(" ALLOCATED imageInfo = ", imageInfo, ", imageView = ", imageInfo->imageView, " ----- size = ", computeSize(*imageInfo), " device memory = ", imageInfo->imageView->image->getDeviceMemory(deviceID), " offset = ", imageInfo->imageView->image->getMemoryOffset(deviceID)); } else { - failedBufferMemory += bufferInfo->computeDataSize(); + vsg::info("MemoryBufferPools::reserve() failed on ", imageInfo, ", data = ", imageInfo->imageView->image->data); + allocationSuccess = false; } } + + if (!allocationSuccess) + { + failed_imageInfos.insert(imageInfo); + + failedImageMemory += imageInfo->computeDataSize(); + // vsg::info("MemoryBufferPools::reserve() failed imageInfo = ", imageInfo, ", image_result = ", image_result, ", data = ", imageInfo->imageView->image->data, ", size = ", imageInfo->computeDataSize()); + } } } +#else // allocate images VkDeviceSize failedImageMemory = 0; @@ -294,23 +361,68 @@ VkResult MemoryBufferPools::reserve(ResourceRequirements& requirements) } else { + failed_imageInfos.insert(imageInfo); + failedImageMemory += imageInfo->computeDataSize(); + // vsg::info("MemoryBufferPools::reserve() failed imageInfo = ", imageInfo, ", ", imageInfo->imageView->image->data, ", size = ", imageInfo->computeDataSize()); } } } + // allocate bufferInfos + VkDeviceSize failedBufferMemory = 0; + for (auto& [properties, bufferInfos] : requirements.bufferInfos) + { + for (auto& bufferInfo : bufferInfos) + { + if (!bufferInfo->buffer) + { + VkDeviceSize alignment = 4; + if ((properties.usageFlags & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) != 0) + alignment = limits.minUniformBufferOffsetAlignment; + else if ((properties.usageFlags & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) != 0) + alignment = limits.minStorageBufferOffsetAlignment; + + debug("MemoryBufferPools::reserve(ResourceRequirements& requirements) properties.usageFlags = ", properties.usageFlags, ", alignment = ", alignment); + + auto newBufferInfo = reserveBuffer(bufferInfo->data->dataSize(), alignment, properties.usageFlags, properties.sharingMode, memoryPropertiesFlags); + if (newBufferInfo) + { + bufferInfo->take(*newBufferInfo); + + //info(" ALLOCATED usage = ", properties.usageFlags, ", alignment = ", alignment, ", bufferInfo->data = ", bufferInfo->data, ", offset = ", bufferInfo->offset, ", range = ", bufferInfo->range, ", buffer = ", bufferInfo->buffer, " ----- size = ", computeSize(*bufferInfo)); + } + else + { + failed_bufferInfos[properties].insert(bufferInfo); + + failedBufferMemory += bufferInfo->computeDataSize(); + // vsg::info("MemoryBufferPools::reserve() failed bufferInfo = ", bufferInfo, ", ", bufferInfo->data, ", size = ", bufferInfo->computeDataSize()); + } + } + } + } + +#endif + VkDeviceSize memoryRequired = failedBufferMemory + failedImageMemory; // all required resources allocated - if (memoryRequired == 0) + if (allocationSuccess) // (memoryRequired == 0) { //info("MemoryBufferPools::reserve() memoryRequired = ", memoryRequired); return VK_SUCCESS; } else { - //VkDeviceSize memoryAvailable = device->availableMemory(false); - //info("MemoryBufferPools::reserve() out of memory: memoryAvailable = ", memoryAvailable, " memoryRequired = ", memoryRequired); + requirements.bufferInfos.swap(failed_bufferInfos); + requirements.imageInfos.swap(failed_imageInfos); + + // LogOutput output; + // report(output); + + // VkDeviceSize memoryAvailable = device->availableMemory(false); + // info("MemoryBufferPools::reserve() out of memory: memoryAvailable = ", memoryAvailable, " memoryRequired = ", memoryRequired); return VK_ERROR_OUT_OF_DEVICE_MEMORY; } } From a82478d6f935c2a9acdfc5f27d0fceccadeb8cbe Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 10 Apr 2026 19:00:22 +0100 Subject: [PATCH 15/80] Added default use of ResourceScavanger --- include/vsg/app/CompileManager.h | 6 ++---- src/vsg/app/CompileManager.cpp | 31 +++---------------------------- src/vsg/app/Viewer.cpp | 1 + 3 files changed, 6 insertions(+), 32 deletions(-) diff --git a/include/vsg/app/CompileManager.h b/include/vsg/app/CompileManager.h index 4c88bd8e00..1aa483ef74 100644 --- a/include/vsg/app/CompileManager.h +++ b/include/vsg/app/CompileManager.h @@ -39,18 +39,16 @@ namespace vsg bool requiresViewerUpdate() const; }; - /// ResourceScavanger provides a mechanism for releasing and reusing unused resources + /// ResourceScavanger provides a mechanism for releasing and reusing unused resources when allocation of required GPU memory fails. class VSG_DECLSPEC ResourceScavanger : public Inherit { public: - ResourceScavanger(ref_ptr in_databasePager); virtual bool scavange(ResourceRequirements& resourceRequirements); + uint64_t sleepDuration = 16*5; /// milliseconds sleep to make after adjusting load targets to allow other threads to free up space, default to 5 frames at 60fps observer_ptr databasePager; - - uint32_t numFailures = 0; }; /// CompileManager is a helper class that compiles subgraphs for the windows/framebuffers associated with the CompileManager. diff --git a/src/vsg/app/CompileManager.cpp b/src/vsg/app/CompileManager.cpp index e8d4df5ff0..d241541cf8 100644 --- a/src/vsg/app/CompileManager.cpp +++ b/src/vsg/app/CompileManager.cpp @@ -80,57 +80,32 @@ ResourceScavanger::ResourceScavanger(ref_ptr in_databasePager) : { } -bool ResourceScavanger::scavange(ResourceRequirements& resourceRequirements) +bool ResourceScavanger::scavange(ResourceRequirements& /*resourceRequirements*/) { - ++numFailures; - bool scavanged = false; if (auto ref_databasePager = databasePager.get()) { if (!ref_databasePager->_status->active()) return false; - uint32_t targetPagedLOD = ref_databasePager->pagedLODContainer->activeList.count; if (ref_databasePager->pagedLODContainer->inactiveList.count > ref_databasePager->numActiveRequests) targetPagedLOD += ref_databasePager->pagedLODContainer->inactiveList.count - ref_databasePager->numActiveRequests; - // vsg::info(" ResourceScavanger::scavange(..) activeList.count = ", ref_databasePager->pagedLODContainer->activeList.count, ", inactiveList.count = ", ref_databasePager->pagedLODContainer->inactiveList.count, ", numActiveRequests = ", ref_databasePager->numActiveRequests); if (targetPagedLOD < ref_databasePager->targetMaxNumPagedLODWithHighResSubgraphs) { - vsg::info(" ResourceScavanger::scavange(..) resetting, ref_databasePager->targetMaxNumPagedLODWithHighResSubgraphs, to ", targetPagedLOD, " numFailures = ", numFailures); + info(" ResourceScavanger::scavange(..) resetting, ref_databasePager->targetMaxNumPagedLODWithHighResSubgraphs, to ", targetPagedLOD); ref_databasePager->targetMaxNumPagedLODWithHighResSubgraphs = targetPagedLOD; } - else - { - // vsg::info(" ResourceScavanger::scavange(ResourceRequirements& resourceRequirements) resourceRequirements.bufferInfos.size() = ", resourceRequirements.bufferInfos.size(), ", resourceRequirements.imageInfos.size() = ", resourceRequirements.imageInfos.size(), " nothing to do. numFailures = ", numFailures); - } - -#if 0 - return false; -#else auto before_deletedCount = ref_databasePager->_deleteQueue->deletedCount.load(); - // vsg::info(" Before sleep: inactiveList.count = ", ref_databasePager->pagedLODContainer->inactiveList.count); + if (sleepDuration > 0) std::this_thread::sleep_for(std::chrono::milliseconds(sleepDuration)); -#if 1 - std::this_thread::sleep_for(std::chrono::milliseconds(16*5)); - uint32_t numDeleted = 0; -#else - //std::this_thread::sleep_for(std::chrono::milliseconds(16*5)); - //std::this_thread::sleep_for(std::chrono::milliseconds(16*24)); - //std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - auto numDeleted = ref_databasePager->_deleteQueue->wait_then_clear(); -#endif auto after_deletedCount = ref_databasePager->_deleteQueue->deletedCount.load(); scavanged = (after_deletedCount > before_deletedCount); - - // vsg::info(" After sleep: inactiveList.count = ", ref_databasePager->pagedLODContainer->inactiveList.count, ", delta =", after_deletedCount - before_deletedCount, ", scavanged = ", scavanged, ", numDeleted = ", numDeleted); - // vsg::info(" Finished ResourceScavanger::scavange(ResourceRequirements& resourceRequirements) resourceRequirements.bufferInfos.size() = ", resourceRequirements.bufferInfos.size(), ", resourceRequirements.imageInfos.size() = ", resourceRequirements.imageInfos.size(), " resetting."); } -#endif return scavanged; } diff --git a/src/vsg/app/Viewer.cpp b/src/vsg/app/Viewer.cpp index 07a599860f..1d2c45b927 100644 --- a/src/vsg/app/Viewer.cpp +++ b/src/vsg/app/Viewer.cpp @@ -383,6 +383,7 @@ CompileResult Viewer::compile(ref_ptr hints) if (databasePager && !databasePager->compileManager) { databasePager->compileManager = compileManager; + compileManager->resourceScavenger = ResourceScavanger::create(databasePager); } for (auto& task : recordAndSubmitTasks) From c3e2d2624fc9126498b9e15aa11c4e65eb0ec89d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 10 Apr 2026 19:02:26 +0100 Subject: [PATCH 16/80] Fixed typos --- include/vsg/app/CompileManager.h | 10 +++++----- src/vsg/app/CompileManager.cpp | 14 +++++++------- src/vsg/app/Viewer.cpp | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/vsg/app/CompileManager.h b/include/vsg/app/CompileManager.h index 1aa483ef74..518fd13d21 100644 --- a/include/vsg/app/CompileManager.h +++ b/include/vsg/app/CompileManager.h @@ -39,13 +39,13 @@ namespace vsg bool requiresViewerUpdate() const; }; - /// ResourceScavanger provides a mechanism for releasing and reusing unused resources when allocation of required GPU memory fails. - class VSG_DECLSPEC ResourceScavanger : public Inherit + /// ResourceScavenger provides a mechanism for releasing and reusing unused resources when allocation of required GPU memory fails. + class VSG_DECLSPEC ResourceScavenger : public Inherit { public: - ResourceScavanger(ref_ptr in_databasePager); + ResourceScavenger(ref_ptr in_databasePager); - virtual bool scavange(ResourceRequirements& resourceRequirements); + virtual bool scavenge(ResourceRequirements& resourceRequirements); uint64_t sleepDuration = 16*5; /// milliseconds sleep to make after adjusting load targets to allow other threads to free up space, default to 5 frames at 60fps observer_ptr databasePager; @@ -84,7 +84,7 @@ namespace vsg CompileResult compileTask(ref_ptr task, const ResourceRequirements& resourceRequirements = {}); /// mechinism for releasing and reusing used resources - ref_ptr resourceScavenger; + ref_ptr resourceScavenger; protected: using CompileTraversals = ThreadSafeQueue>; diff --git a/src/vsg/app/CompileManager.cpp b/src/vsg/app/CompileManager.cpp index d241541cf8..a84ba2dbbf 100644 --- a/src/vsg/app/CompileManager.cpp +++ b/src/vsg/app/CompileManager.cpp @@ -75,14 +75,14 @@ bool CompileResult::requiresViewerUpdate() const // CompileManager // -ResourceScavanger::ResourceScavanger(ref_ptr in_databasePager) : +ResourceScavenger::ResourceScavenger(ref_ptr in_databasePager) : databasePager(in_databasePager) { } -bool ResourceScavanger::scavange(ResourceRequirements& /*resourceRequirements*/) +bool ResourceScavenger::scavenge(ResourceRequirements& /*resourceRequirements*/) { - bool scavanged = false; + bool scavenged = false; if (auto ref_databasePager = databasePager.get()) { @@ -93,7 +93,7 @@ bool ResourceScavanger::scavange(ResourceRequirements& /*resourceRequirements*/) if (targetPagedLOD < ref_databasePager->targetMaxNumPagedLODWithHighResSubgraphs) { - info(" ResourceScavanger::scavange(..) resetting, ref_databasePager->targetMaxNumPagedLODWithHighResSubgraphs, to ", targetPagedLOD); + info(" ResourceScavenger::scavenge(..) resetting, ref_databasePager->targetMaxNumPagedLODWithHighResSubgraphs, to ", targetPagedLOD); ref_databasePager->targetMaxNumPagedLODWithHighResSubgraphs = targetPagedLOD; } @@ -104,10 +104,10 @@ bool ResourceScavanger::scavange(ResourceRequirements& /*resourceRequirements*/) auto after_deletedCount = ref_databasePager->_deleteQueue->deletedCount.load(); - scavanged = (after_deletedCount > before_deletedCount); + scavenged = (after_deletedCount > before_deletedCount); } - return scavanged; + return scavenged; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -255,7 +255,7 @@ CompileResult CompileManager::compile(ref_ptr object, ContextSelectionFu reserve_result = context->reserve(requirements); // vsg::info(" done reserve context->reserve() ", reserve_result); - if (reserve_result != VK_SUCCESS && resourceScavenger && resourceScavenger->scavange(requirements)) + if (reserve_result != VK_SUCCESS && resourceScavenger && resourceScavenger->scavenge(requirements)) { reserve_result = context->reserve(requirements); } diff --git a/src/vsg/app/Viewer.cpp b/src/vsg/app/Viewer.cpp index 1d2c45b927..b091835b9d 100644 --- a/src/vsg/app/Viewer.cpp +++ b/src/vsg/app/Viewer.cpp @@ -383,7 +383,7 @@ CompileResult Viewer::compile(ref_ptr hints) if (databasePager && !databasePager->compileManager) { databasePager->compileManager = compileManager; - compileManager->resourceScavenger = ResourceScavanger::create(databasePager); + compileManager->resourceScavenger = ResourceScavenger::create(databasePager); } for (auto& task : recordAndSubmitTasks) From 5b36ddf45af199c3b4268ed8d365c0495a0d19b7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 10 Apr 2026 19:02:50 +0100 Subject: [PATCH 17/80] Ran clang-format --- include/vsg/app/CompileManager.h | 2 +- include/vsg/io/DatabasePager.h | 2 -- src/vsg/core/MemorySlots.cpp | 2 +- src/vsg/io/DatabasePager.cpp | 7 +++---- src/vsg/io/json.cpp | 8 ++++---- src/vsg/state/BufferInfo.cpp | 4 +--- src/vsg/state/DescriptorBuffer.cpp | 2 +- src/vsg/ui/FrameStamp.cpp | 1 - src/vsg/vk/MemoryBufferPools.cpp | 24 +++++++++++------------- 9 files changed, 22 insertions(+), 30 deletions(-) diff --git a/include/vsg/app/CompileManager.h b/include/vsg/app/CompileManager.h index 518fd13d21..c0ece90ac7 100644 --- a/include/vsg/app/CompileManager.h +++ b/include/vsg/app/CompileManager.h @@ -47,7 +47,7 @@ namespace vsg virtual bool scavenge(ResourceRequirements& resourceRequirements); - uint64_t sleepDuration = 16*5; /// milliseconds sleep to make after adjusting load targets to allow other threads to free up space, default to 5 frames at 60fps + uint64_t sleepDuration = 16 * 5; /// milliseconds sleep to make after adjusting load targets to allow other threads to free up space, default to 5 frames at 60fps observer_ptr databasePager; }; diff --git a/include/vsg/io/DatabasePager.h b/include/vsg/io/DatabasePager.h index 05922a302f..21091b5268 100644 --- a/include/vsg/io/DatabasePager.h +++ b/include/vsg/io/DatabasePager.h @@ -151,7 +151,6 @@ namespace vsg /// number of frames before a PagedLOD with a failed load/compile is attempted to be loaded/compiled again. uint64_t delayBeforeNextLoadAttempt = 60; - std::mutex pendingPagedLODMutex; ref_ptr pagedLODContainer; @@ -173,7 +172,6 @@ namespace vsg void requestDiscarded(PagedLOD* plod); - ref_ptr _requestQueue; ref_ptr _toMergeQueue; }; diff --git a/src/vsg/core/MemorySlots.cpp b/src/vsg/core/MemorySlots.cpp index 25875baf38..60313ec3bb 100644 --- a/src/vsg/core/MemorySlots.cpp +++ b/src/vsg/core/MemorySlots.cpp @@ -112,7 +112,7 @@ bool MemorySlots::check() const void MemorySlots::report(LogOutput& out) const { out.enter("MemorySlots::report(...)"); - out("MemorySlots::report() ",this); + out("MemorySlots::report() ", this); for (auto& [offset, size] : _offsetSizes) { out(" available ", offset, ", ", size); diff --git a/src/vsg/io/DatabasePager.cpp b/src/vsg/io/DatabasePager.cpp index 03a50a58ea..40d9a4f7e3 100644 --- a/src/vsg/io/DatabasePager.cpp +++ b/src/vsg/io/DatabasePager.cpp @@ -423,7 +423,7 @@ ref_ptr DatabaseQueue::take_when_available(uint64_t frameCount) size_t skipped = 0; // find first PagedLOD in queue that can be loaded/compiled - for(; itr != _queue.end(); ++itr) + for (; itr != _queue.end(); ++itr) { if ((*itr)->frameNextLoadAttempt.load() <= frameCount) break; ++skipped; @@ -457,7 +457,7 @@ uint32_t DatabaseQueue::prune(uint64_t frameCount) uint32_t numRemoved = 0; for (auto itr = _queue.begin(); itr != _queue.end();) { - if (((*itr)->frameHighResLastUsed.load()+1) < frameCount) + if (((*itr)->frameHighResLastUsed.load() + 1) < frameCount) { // info("pruning ", *itr, ", lastUsed = ", (*itr)->frameHighResLastUsed.load(), " vs ", frameCount, " after ", (*itr)->loadAttempts.load(), " loadAttempts"); ++numRemoved; @@ -537,7 +537,6 @@ void DatabasePager::start(uint32_t numReadThreads) uint64_t frameDelta = databasePager.frameCount - plod->frameHighResLastUsed.load(); - if (frameDelta > 1 || !compare_exchange(plod->requestStatus, PagedLOD::ReadRequest, PagedLOD::Reading)) { info("Expire read request : databasePager.frameCount = ", databasePager.frameCount, ", plod->frameHighResLastUsed.load() = ", plod->frameHighResLastUsed.load()); @@ -605,7 +604,7 @@ void DatabasePager::start(uint32_t numReadThreads) else { // sleep for a frame. - std::this_thread::sleep_for(std::chrono::milliseconds(16*2)); + std::this_thread::sleep_for(std::chrono::milliseconds(16 * 2)); } } debug("Finished DatabaseThread read thread"); diff --git a/src/vsg/io/json.cpp b/src/vsg/io/json.cpp index 0476c1c87d..d5be3bafdd 100644 --- a/src/vsg/io/json.cpp +++ b/src/vsg/io/json.cpp @@ -75,11 +75,11 @@ ref_ptr json::_read(std::istream& fin, ref_ptr) const warn("Parsing error, could not find opening { or [."); } - if ( !parser.warnings.empty() ) + if (!parser.warnings.empty()) { - warn( "JSONParser recorded following warnings:" ); - for ( auto w : parser.warnings ) - warn( "\t", w ); + warn("JSONParser recorded following warnings:"); + for (auto w : parser.warnings) + warn("\t", w); } return result; } diff --git a/src/vsg/state/BufferInfo.cpp b/src/vsg/state/BufferInfo.cpp index 58246d9249..7b4c8af496 100644 --- a/src/vsg/state/BufferInfo.cpp +++ b/src/vsg/state/BufferInfo.cpp @@ -84,7 +84,7 @@ void BufferInfo::take(BufferInfo& src) if (buffer && !parent) { - bool identical = (buffer==src.buffer && offset==src.offset && range==src.range); + bool identical = (buffer == src.buffer && offset == src.offset && range == src.range); if (!identical) { @@ -106,7 +106,6 @@ void BufferInfo::take(BufferInfo& src) src.range = 0; } - void BufferInfo::release() { if (parent) @@ -225,7 +224,6 @@ bool vsg::createBufferAndTransferData(Context& context, const BufferInfoList& bu else if (usage == VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) alignment = device->getPhysicalDevice()->getProperties().limits.minStorageBufferOffsetAlignment; - debug("vsg::createBufferAndTransferData(Context& context, const BufferInfoList& bufferInfoList, VkBufferUsageFlags usage, VkSharingMode sharingMode) usage = ", usage, ", alignment = ", alignment); //transferTask = nullptr; diff --git a/src/vsg/state/DescriptorBuffer.cpp b/src/vsg/state/DescriptorBuffer.cpp index 3d3ad666e7..3bbd0295e9 100644 --- a/src/vsg/state/DescriptorBuffer.cpp +++ b/src/vsg/state/DescriptorBuffer.cpp @@ -140,7 +140,7 @@ void DescriptorBuffer::compile(Context& context) VkDeviceSize totalSize = 0; - debug("DescriptorBuffer::compile() bufferUsageFlags = ",bufferUsageFlags, ", alignment = ", alignment); + debug("DescriptorBuffer::compile() bufferUsageFlags = ", bufferUsageFlags, ", alignment = ", alignment); // compute the total size of BufferInfo that needs to be allocated. { diff --git a/src/vsg/ui/FrameStamp.cpp b/src/vsg/ui/FrameStamp.cpp index cc62e02ce1..c270b511d9 100644 --- a/src/vsg/ui/FrameStamp.cpp +++ b/src/vsg/ui/FrameStamp.cpp @@ -22,7 +22,6 @@ FrameStamp::FrameStamp(const FrameStamp& rhs, const CopyOp& copyop) : { } - void FrameStamp::read(Input& input) { Object::read(input); diff --git a/src/vsg/vk/MemoryBufferPools.cpp b/src/vsg/vk/MemoryBufferPools.cpp index 4016657a70..3e7a0d547b 100644 --- a/src/vsg/vk/MemoryBufferPools.cpp +++ b/src/vsg/vk/MemoryBufferPools.cpp @@ -107,7 +107,6 @@ ref_ptr MemoryBufferPools::reserveBuffer(VkDeviceSize totalSize, VkD VkDeviceSize deviceSize = std::max(totalSize, minimumBufferSize); #endif - bufferInfo->buffer = Buffer::create(deviceSize, bufferUsageFlags, sharingMode); bufferInfo->buffer->compile(device); @@ -156,19 +155,19 @@ MemoryBufferPools::DeviceMemoryOffset MemoryBufferPools::reserveMemory(VkMemoryR MemorySlots::OptionalOffset reservedSlot(false, 0); #if 1 - for (auto& memoryPool : memoryPools) + for (auto& memoryPool : memoryPools) + { + if (((memoryPool->getMemoryRequirements().memoryTypeBits & memRequirements.memoryTypeBits) == memRequirements.memoryTypeBits) && + memoryPool->maximumAvailableSpace() >= totalSize) { - if (((memoryPool->getMemoryRequirements().memoryTypeBits & memRequirements.memoryTypeBits) == memRequirements.memoryTypeBits) && - memoryPool->maximumAvailableSpace() >= totalSize) + reservedSlot = memoryPool->reserve(totalSize, memRequirements.alignment); + if (reservedSlot.first) { - reservedSlot = memoryPool->reserve(totalSize, memRequirements.alignment); - if (reservedSlot.first) - { - deviceMemory = memoryPool; - break; - } + deviceMemory = memoryPool; + break; } } + } #else for (auto& memoryPool : memoryPools) { @@ -208,7 +207,7 @@ MemoryBufferPools::DeviceMemoryOffset MemoryBufferPools::reserveMemory(VkMemoryR { deviceMemory = vsg::DeviceMemory::create(device, memRequirements, memoryPropertiesFlags, pNextAllocInfo); } - catch(...) + catch (...) { // info("Could not allocate vsg::DeviceMemory(..) memRequirements.size = ", memRequirements.size); } @@ -234,7 +233,6 @@ MemoryBufferPools::DeviceMemoryOffset MemoryBufferPools::reserveMemory(VkMemoryR #endif } - if (!reservedSlot.first) { #if 0 @@ -430,7 +428,7 @@ VkResult MemoryBufferPools::reserve(ResourceRequirements& requirements) void MemoryBufferPools::report(LogOutput& out) const { out.enter("MemoryBufferPools::report(..)"); - for(const auto& memoryPool : memoryPools) + for (const auto& memoryPool : memoryPools) { memoryPool->report(out); } From 2e507ac732015fc8c531f423bd881ab2109c2b62 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 10 Apr 2026 19:45:29 +0100 Subject: [PATCH 18/80] Moved tracking of successful and failed compiles into public interface. --- include/vsg/app/CompileManager.h | 5 +++++ src/vsg/app/CompileManager.cpp | 16 +++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/include/vsg/app/CompileManager.h b/include/vsg/app/CompileManager.h index c0ece90ac7..dc04398107 100644 --- a/include/vsg/app/CompileManager.h +++ b/include/vsg/app/CompileManager.h @@ -86,7 +86,12 @@ namespace vsg /// mechinism for releasing and reusing used resources ref_ptr resourceScavenger; + std::atomic_uint successfulCompileCount{0}; + std::atomic_uint failedCompileCount{0}; + protected: + ~CompileManager(); + using CompileTraversals = ThreadSafeQueue>; size_t numCompileTraversals = 0; ref_ptr compileTraversals; diff --git a/src/vsg/app/CompileManager.cpp b/src/vsg/app/CompileManager.cpp index a84ba2dbbf..1c497c09d8 100644 --- a/src/vsg/app/CompileManager.cpp +++ b/src/vsg/app/CompileManager.cpp @@ -132,6 +132,11 @@ CompileManager::CompileManager(Viewer& viewer, ref_ptr hints) #endif } +CompileManager::~CompileManager() +{ + vsg::info("CompileManager::~CompileManager() successfulCompileCount= ", successfulCompileCount, ", failedCompileCount = ", failedCompileCount); +} + CompileManager::CompileTraversals::container_type CompileManager::takeCompileTraversals(size_t count) { CompileTraversals::container_type cts; @@ -315,19 +320,16 @@ CompileResult CompileManager::compile(ref_ptr object, ContextSelectionFu compileTraversals->add(compileTraversal); - static int s_succeeded = 0; - static int s_failed = 0; + int s_succeeded = 0; + int s_failed = 0; if (result.result == VK_SUCCESS) { - ++s_succeeded; - vsg::info("Success : succedded = ", s_succeeded, ", failed = ", s_failed, ", result = { ", result.result, " : ", result.message, " }, reserve_result = ", reserve_result); + ++successfulCompileCount; } else { - s_failed++; - - vsg::info("Failed : succedded = ", s_succeeded, ", failed = ", s_failed, ", result = { ", result.result, " : ", result.message, " }, reserve_result = ", reserve_result); + ++failedCompileCount; } return result; From 9ae1d07ce2bfdd60133ba885e04f740b79245b39 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 11 Apr 2026 12:26:31 +0100 Subject: [PATCH 19/80] cppcheck fixes --- include/vsg/app/CompileManager.h | 2 +- src/vsg/core/MemorySlots.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/vsg/app/CompileManager.h b/include/vsg/app/CompileManager.h index dc04398107..f23c1dcdcf 100644 --- a/include/vsg/app/CompileManager.h +++ b/include/vsg/app/CompileManager.h @@ -43,7 +43,7 @@ namespace vsg class VSG_DECLSPEC ResourceScavenger : public Inherit { public: - ResourceScavenger(ref_ptr in_databasePager); + explicit ResourceScavenger(ref_ptr in_databasePager); virtual bool scavenge(ResourceRequirements& resourceRequirements); diff --git a/src/vsg/core/MemorySlots.cpp b/src/vsg/core/MemorySlots.cpp index 60313ec3bb..1622a70797 100644 --- a/src/vsg/core/MemorySlots.cpp +++ b/src/vsg/core/MemorySlots.cpp @@ -100,8 +100,8 @@ bool MemorySlots::check() const { warn("MemorySlots::check() ", this, " failed, computedSize (", computedSize, ") != _totalMemorySize (", _totalMemorySize, ")"); - LogOutput log; - report(log); + LogOutput output; + report(output); return false; } From e536d748f94a6e6085176c17973b81599f456150 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 11 Apr 2026 12:27:11 +0100 Subject: [PATCH 20/80] Removed no longer required variables --- src/vsg/app/CompileManager.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/vsg/app/CompileManager.cpp b/src/vsg/app/CompileManager.cpp index 1c497c09d8..cf87eb5f96 100644 --- a/src/vsg/app/CompileManager.cpp +++ b/src/vsg/app/CompileManager.cpp @@ -320,9 +320,6 @@ CompileResult CompileManager::compile(ref_ptr object, ContextSelectionFu compileTraversals->add(compileTraversal); - int s_succeeded = 0; - int s_failed = 0; - if (result.result == VK_SUCCESS) { ++successfulCompileCount; From 70aba52e7cdf7ddb3129ea14065cbb4e1d1cc033 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 11 Apr 2026 14:58:02 +0100 Subject: [PATCH 21/80] Quietened down debug output. --- src/vsg/app/CompileManager.cpp | 3 +- src/vsg/vk/DeviceMemory.cpp | 2 +- src/vsg/vk/MemoryBufferPools.cpp | 131 ++----------------------------- 3 files changed, 11 insertions(+), 125 deletions(-) diff --git a/src/vsg/app/CompileManager.cpp b/src/vsg/app/CompileManager.cpp index cf87eb5f96..50a3d40326 100644 --- a/src/vsg/app/CompileManager.cpp +++ b/src/vsg/app/CompileManager.cpp @@ -84,6 +84,7 @@ bool ResourceScavenger::scavenge(ResourceRequirements& /*resourceRequirements*/) { bool scavenged = false; + // get raw C pointer to avoid a database pager thread invoking scavenger and keeping the database pager alive and pausing destruction if (auto ref_databasePager = databasePager.get()) { if (!ref_databasePager->_status->active()) return false; @@ -93,7 +94,7 @@ bool ResourceScavenger::scavenge(ResourceRequirements& /*resourceRequirements*/) if (targetPagedLOD < ref_databasePager->targetMaxNumPagedLODWithHighResSubgraphs) { - info(" ResourceScavenger::scavenge(..) resetting, ref_databasePager->targetMaxNumPagedLODWithHighResSubgraphs, to ", targetPagedLOD); + debug("ResourceScavenger::scavenge(..) resetting databasePager->targetMaxNumPagedLODWithHighResSubgraphs to ", targetPagedLOD); ref_databasePager->targetMaxNumPagedLODWithHighResSubgraphs = targetPagedLOD; } diff --git a/src/vsg/vk/DeviceMemory.cpp b/src/vsg/vk/DeviceMemory.cpp index 1b557164af..621b0b6f18 100644 --- a/src/vsg/vk/DeviceMemory.cpp +++ b/src/vsg/vk/DeviceMemory.cpp @@ -93,7 +93,7 @@ DeviceMemory::DeviceMemory(Device* device, const VkMemoryRequirements& memRequir { std::scoped_lock lock(s_DeviceMemoryListMutex); s_DeviceMemoryList.emplace_back(this); - vsg::debug("DeviceMemory::DeviceMemory() added to s_DeviceMemoryList, s_DeviceMemoryList.size() = ", s_DeviceMemoryList.size()); + debug("DeviceMemory::DeviceMemory() added to s_DeviceMemoryList, s_DeviceMemoryList.size() = ", s_DeviceMemoryList.size()); } } diff --git a/src/vsg/vk/MemoryBufferPools.cpp b/src/vsg/vk/MemoryBufferPools.cpp index 3e7a0d547b..01f0a2df9a 100644 --- a/src/vsg/vk/MemoryBufferPools.cpp +++ b/src/vsg/vk/MemoryBufferPools.cpp @@ -94,7 +94,7 @@ ref_ptr MemoryBufferPools::reserveBuffer(VkDeviceSize totalSize, VkD } } } -#if 1 + VkDeviceSize availableMemory = device->availableMemory(memoryPropertiesFlags, allocatedMemoryLimit); if (totalSize > availableMemory) { @@ -103,9 +103,6 @@ ref_ptr MemoryBufferPools::reserveBuffer(VkDeviceSize totalSize, VkD } VkDeviceSize deviceSize = std::max(totalSize, std::min(availableMemory, minimumBufferSize)); -#else - VkDeviceSize deviceSize = std::max(totalSize, minimumBufferSize); -#endif bufferInfo->buffer = Buffer::create(deviceSize, bufferUsageFlags, sharingMode); bufferInfo->buffer->compile(device); @@ -154,7 +151,6 @@ MemoryBufferPools::DeviceMemoryOffset MemoryBufferPools::reserveMemory(VkMemoryR ref_ptr deviceMemory; MemorySlots::OptionalOffset reservedSlot(false, 0); -#if 1 for (auto& memoryPool : memoryPools) { if (((memoryPool->getMemoryRequirements().memoryTypeBits & memRequirements.memoryTypeBits) == memRequirements.memoryTypeBits) && @@ -168,37 +164,18 @@ MemoryBufferPools::DeviceMemoryOffset MemoryBufferPools::reserveMemory(VkMemoryR } } } -#else - for (auto& memoryPool : memoryPools) - { - if (memoryPool->getMemoryRequirements().memoryTypeBits == memRequirements.memoryTypeBits && - memoryPool->getMemoryRequirements().alignment == memRequirements.alignment && - memoryPool->maximumAvailableSpace() >= totalSize) - { - reservedSlot = memoryPool->reserve(totalSize); - if (reservedSlot.first) - { - deviceMemory = memoryPool; - break; - } - } - } -#endif if (!deviceMemory) { -#if 1 + VkDeviceSize availableMemory = device->availableMemory(memoryPropertiesFlags, allocatedMemoryLimit); if (totalSize > availableMemory) { - info("MemoryBufferPools::reserveBuffer(", totalSize, ") insufficient memory ", availableMemory); + debug("MemoryBufferPools::reserveBuffer(", totalSize, ") insufficient memory ", availableMemory); return {}; } VkDeviceSize deviceSize = std::max(totalSize, std::min(availableMemory, minimumDeviceMemorySize)); -#else - VkDeviceSize deviceSize = std::max(totalSize, minimumDeviceMemorySize); -#endif if (deviceSize <= availableMemory) { @@ -235,22 +212,6 @@ MemoryBufferPools::DeviceMemoryOffset MemoryBufferPools::reserveMemory(VkMemoryR if (!reservedSlot.first) { -#if 0 - info("MemoryBufferPools::reserveMemory() failure totalSize = ", totalSize); - - LogOutput output; - output.enter("Failure to allocate, compatible MemoryPools with space {"); - for (auto& memoryPool : memoryPools) - { - if (memoryPool->getMemoryRequirements().memoryTypeBits == memRequirements.memoryTypeBits && - memoryPool->getMemoryRequirements().alignment == memRequirements.alignment && - memoryPool->maximumAvailableSpace() >= totalSize) - { - memoryPool->report(output); - } - } - output.leave(); -#endif debug("MemoryBufferPools::reserveMemory(", totalSize, ") failed, insufficient memory available."); return {}; } @@ -271,9 +232,8 @@ VkResult MemoryBufferPools::reserve(ResourceRequirements& requirements) decltype(requirements.bufferInfos) failed_bufferInfos; decltype(requirements.imageInfos) failed_imageInfos; -#if 1 + // allocate bufferInfos - VkDeviceSize failedBufferMemory = 0; bool allocationSuccess = true; for (auto& [properties, bufferInfos] : requirements.bufferInfos) { @@ -295,13 +255,10 @@ VkResult MemoryBufferPools::reserve(ResourceRequirements& requirements) if (newBufferInfo) { bufferInfo->take(*newBufferInfo); - - //info(" ALLOCATED usage = ", properties.usageFlags, ", alignment = ", alignment, ", bufferInfo->data = ", bufferInfo->data, ", offset = ", bufferInfo->offset, ", range = ", bufferInfo->range, ", buffer = ", bufferInfo->buffer, " ----- size = ", computeSize(*bufferInfo)); } else { - // vsg::info("MemoryBufferPools::reserve() failed on ", bufferInfo, ", data = ", bufferInfo->data); - + debug("MemoryBufferPools::reserve() failed on ", bufferInfo, ", data = ", bufferInfo->data); allocationSuccess = false; } } @@ -309,15 +266,12 @@ VkResult MemoryBufferPools::reserve(ResourceRequirements& requirements) if (!allocationSuccess) { failed_bufferInfos[properties].insert(bufferInfo); - failedBufferMemory += bufferInfo->computeDataSize(); - // vsg::info("MemoryBufferPools::reserve() failed bufferInfo = ", bufferInfo, ", ", bufferInfo->data, ", size = ", bufferInfo->computeDataSize()); } } } } // allocate images - VkDeviceSize failedImageMemory = 0; for (auto& imageInfo : requirements.imageInfos) { if (imageInfo->imageView && imageInfo->imageView->image && imageInfo->imageView->image->getDeviceMemory(deviceID) == 0) @@ -325,13 +279,9 @@ VkResult MemoryBufferPools::reserve(ResourceRequirements& requirements) if (allocationSuccess) { auto image_result = imageInfo->imageView->image->compile(*this); - if (image_result == VK_SUCCESS && imageInfo->imageView->image->getDeviceMemory(deviceID) != 0) - { - //info(" ALLOCATED imageInfo = ", imageInfo, ", imageView = ", imageInfo->imageView, " ----- size = ", computeSize(*imageInfo), " device memory = ", imageInfo->imageView->image->getDeviceMemory(deviceID), " offset = ", imageInfo->imageView->image->getMemoryOffset(deviceID)); - } - else + if (image_result != VK_SUCCESS || imageInfo->imageView->image->getDeviceMemory(deviceID) == 0) { - vsg::info("MemoryBufferPools::reserve() failed on ", imageInfo, ", data = ", imageInfo->imageView->image->data); + debug("MemoryBufferPools::reserve() failed on ", imageInfo, ", data = ", imageInfo->imageView->image->data); allocationSuccess = false; } } @@ -339,76 +289,13 @@ VkResult MemoryBufferPools::reserve(ResourceRequirements& requirements) if (!allocationSuccess) { failed_imageInfos.insert(imageInfo); - - failedImageMemory += imageInfo->computeDataSize(); - // vsg::info("MemoryBufferPools::reserve() failed imageInfo = ", imageInfo, ", image_result = ", image_result, ", data = ", imageInfo->imageView->image->data, ", size = ", imageInfo->computeDataSize()); - } - } - } -#else - - // allocate images - VkDeviceSize failedImageMemory = 0; - for (auto& imageInfo : requirements.imageInfos) - { - if (imageInfo->imageView && imageInfo->imageView->image && imageInfo->imageView->image->getDeviceMemory(deviceID) == 0) - { - if (imageInfo->imageView->image->compile(*this) == VK_SUCCESS && imageInfo->imageView->image->getDeviceMemory(deviceID) != 0) - { - //info(" ALLOCATED imageInfo = ", imageInfo, ", imageView = ", imageInfo->imageView, " ----- size = ", computeSize(*imageInfo), " device memory = ", imageInfo->imageView->image->getDeviceMemory(deviceID), " offset = ", imageInfo->imageView->image->getMemoryOffset(deviceID)); - } - else - { - failed_imageInfos.insert(imageInfo); - - failedImageMemory += imageInfo->computeDataSize(); - // vsg::info("MemoryBufferPools::reserve() failed imageInfo = ", imageInfo, ", ", imageInfo->imageView->image->data, ", size = ", imageInfo->computeDataSize()); } } } - // allocate bufferInfos - VkDeviceSize failedBufferMemory = 0; - for (auto& [properties, bufferInfos] : requirements.bufferInfos) - { - for (auto& bufferInfo : bufferInfos) - { - if (!bufferInfo->buffer) - { - VkDeviceSize alignment = 4; - if ((properties.usageFlags & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) != 0) - alignment = limits.minUniformBufferOffsetAlignment; - else if ((properties.usageFlags & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) != 0) - alignment = limits.minStorageBufferOffsetAlignment; - - debug("MemoryBufferPools::reserve(ResourceRequirements& requirements) properties.usageFlags = ", properties.usageFlags, ", alignment = ", alignment); - - auto newBufferInfo = reserveBuffer(bufferInfo->data->dataSize(), alignment, properties.usageFlags, properties.sharingMode, memoryPropertiesFlags); - if (newBufferInfo) - { - bufferInfo->take(*newBufferInfo); - - //info(" ALLOCATED usage = ", properties.usageFlags, ", alignment = ", alignment, ", bufferInfo->data = ", bufferInfo->data, ", offset = ", bufferInfo->offset, ", range = ", bufferInfo->range, ", buffer = ", bufferInfo->buffer, " ----- size = ", computeSize(*bufferInfo)); - } - else - { - failed_bufferInfos[properties].insert(bufferInfo); - - failedBufferMemory += bufferInfo->computeDataSize(); - // vsg::info("MemoryBufferPools::reserve() failed bufferInfo = ", bufferInfo, ", ", bufferInfo->data, ", size = ", bufferInfo->computeDataSize()); - } - } - } - } - -#endif - - VkDeviceSize memoryRequired = failedBufferMemory + failedImageMemory; - // all required resources allocated - if (allocationSuccess) // (memoryRequired == 0) + if (allocationSuccess) { - //info("MemoryBufferPools::reserve() memoryRequired = ", memoryRequired); return VK_SUCCESS; } else @@ -419,8 +306,6 @@ VkResult MemoryBufferPools::reserve(ResourceRequirements& requirements) // LogOutput output; // report(output); - // VkDeviceSize memoryAvailable = device->availableMemory(false); - // info("MemoryBufferPools::reserve() out of memory: memoryAvailable = ", memoryAvailable, " memoryRequired = ", memoryRequired); return VK_ERROR_OUT_OF_DEVICE_MEMORY; } } From 953a92ae93aff54d12997daf6982d8456060fdc3 Mon Sep 17 00:00:00 2001 From: Mikhail Arepev Date: Sat, 11 Apr 2026 22:42:18 +0300 Subject: [PATCH 22/80] Fix typo in CompileResult::add() --- src/vsg/app/CompileManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vsg/app/CompileManager.cpp b/src/vsg/app/CompileManager.cpp index cdd28de2ad..a6b6a3e2f9 100644 --- a/src/vsg/app/CompileManager.cpp +++ b/src/vsg/app/CompileManager.cpp @@ -50,7 +50,7 @@ void CompileResult::add(const CompileResult& cr) binDetails.bins.insert(src_binDetails.bins.begin(), src_binDetails.bins.end()); } - dynamicData.add(dynamicData); + dynamicData.add(cr.dynamicData); } bool CompileResult::requiresViewerUpdate() const From b76bb1e4522eba4eeeea13036156dd73888bf87f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 12 Apr 2026 11:44:47 +0100 Subject: [PATCH 23/80] Fixed cppcheck warning --- src/vsg/core/MemorySlots.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vsg/core/MemorySlots.cpp b/src/vsg/core/MemorySlots.cpp index 1622a70797..46c2d5e7e0 100644 --- a/src/vsg/core/MemorySlots.cpp +++ b/src/vsg/core/MemorySlots.cpp @@ -46,8 +46,8 @@ MemorySlots::~MemorySlots() else { info("MemorySlots::~MemorySlots() ", this, ", not all slots restored correctly."); - LogOutput log; - report(log); + LogOutput output; + report(output); } } if (memoryTracking & MEMORY_TRACKING_CHECK_ACTIONS) From 8fc0eb040930250b3ce7f7467842c4b863f207e8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 13 Apr 2026 15:06:10 +0100 Subject: [PATCH 24/80] Removed unused method --- include/vsg/vk/Device.h | 3 --- src/vsg/vk/Device.cpp | 44 ----------------------------------------- 2 files changed, 47 deletions(-) diff --git a/include/vsg/vk/Device.h b/include/vsg/vk/Device.h index 11623b210a..0c48c01e53 100644 --- a/include/vsg/vk/Device.h +++ b/include/vsg/vk/Device.h @@ -85,9 +85,6 @@ namespace vsg /// return true if Device was created with specified extension bool supportsDeviceExtension(const char* extensionName) const; - /// return the amount of memory available in deviceMemoryBufferPools and allocatable on device - VkDeviceSize availableMemory(bool includeMemoryPools = true) const; - /// return the amount of remaining memory, compatible with specified flags, available that can be allocated. VkDeviceSize availableMemory(VkMemoryPropertyFlags memoryPropertiesFlags, double allocatedMemoryLimit = 1.0) const; diff --git a/src/vsg/vk/Device.cpp b/src/vsg/vk/Device.cpp index fd69fe5b15..9fe8625979 100644 --- a/src/vsg/vk/Device.cpp +++ b/src/vsg/vk/Device.cpp @@ -206,50 +206,6 @@ bool Device::supportsDeviceExtension(const char* extensionName) const return (std::find_if(enabledExtensions.begin(), enabledExtensions.end(), compare) != enabledExtensions.end()); } -VkDeviceSize Device::availableMemory(bool includeMemoryPools) const -{ - VkDeviceSize available = 0; - - VkPhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget; - memoryBudget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; - memoryBudget.pNext = nullptr; - - VkPhysicalDeviceMemoryProperties2 dmp; - dmp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2; - dmp.pNext = &memoryBudget; - - vkGetPhysicalDeviceMemoryProperties2(*(getPhysicalDevice()), &dmp); - - auto& memoryProperties = dmp.memoryProperties; - - VkMemoryPropertyFlags requiredPropertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - - std::set compatibleHeaps; - for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i) - { - if ((memoryProperties.memoryTypes[i].propertyFlags & requiredPropertyFlags) == requiredPropertyFlags) // supported - { - compatibleHeaps.insert(memoryProperties.memoryTypes[i].heapIndex); - } - } - - for (const auto& heapIndex : compatibleHeaps) - { - VkDeviceSize heapAvailable = memoryBudget.heapBudget[heapIndex] - memoryBudget.heapUsage[heapIndex]; - available += heapAvailable; - } - - if (includeMemoryPools) - { - if (auto pool = deviceMemoryBufferPools.ref_ptr()) - { - available += pool->computeMemoryTotalAvailable(); - } - } - - return available; -} - VkDeviceSize Device::availableMemory(VkMemoryPropertyFlags memoryPropertiesFlags, double allocatedMemoryLimit) const { VkPhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget; From 32ed7c74f33bc63d572d34cc4a0981f41d6c364f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 13 Apr 2026 17:05:21 +0100 Subject: [PATCH 25/80] Cleaned up naming --- include/vsg/io/DatabasePager.h | 4 ++-- src/vsg/app/CompileManager.cpp | 6 +++--- src/vsg/io/DatabasePager.cpp | 30 +++++++++++++++--------------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/vsg/io/DatabasePager.h b/include/vsg/io/DatabasePager.h index 21091b5268..667a896753 100644 --- a/include/vsg/io/DatabasePager.h +++ b/include/vsg/io/DatabasePager.h @@ -164,8 +164,8 @@ namespace vsg /// read and delete threads created by start() std::list threads; - ref_ptr _deleteQueue; - ref_ptr _status; + ref_ptr status; + ref_ptr deleteQueue; protected: virtual ~DatabasePager(); diff --git a/src/vsg/app/CompileManager.cpp b/src/vsg/app/CompileManager.cpp index 9a1cf0536b..742e8020d1 100644 --- a/src/vsg/app/CompileManager.cpp +++ b/src/vsg/app/CompileManager.cpp @@ -87,7 +87,7 @@ bool ResourceScavenger::scavenge(ResourceRequirements& /*resourceRequirements*/) // get raw C pointer to avoid a database pager thread invoking scavenger and keeping the database pager alive and pausing destruction if (auto ref_databasePager = databasePager.get()) { - if (!ref_databasePager->_status->active()) return false; + if (!ref_databasePager->status->active()) return false; uint32_t targetPagedLOD = ref_databasePager->pagedLODContainer->activeList.count; if (ref_databasePager->pagedLODContainer->inactiveList.count > ref_databasePager->numActiveRequests) targetPagedLOD += ref_databasePager->pagedLODContainer->inactiveList.count - ref_databasePager->numActiveRequests; @@ -99,11 +99,11 @@ bool ResourceScavenger::scavenge(ResourceRequirements& /*resourceRequirements*/) ref_databasePager->targetMaxNumPagedLODWithHighResSubgraphs = targetPagedLOD; } - auto before_deletedCount = ref_databasePager->_deleteQueue->deletedCount.load(); + auto before_deletedCount = ref_databasePager->deleteQueue->deletedCount.load(); if (sleepDuration > 0) std::this_thread::sleep_for(std::chrono::milliseconds(sleepDuration)); - auto after_deletedCount = ref_databasePager->_deleteQueue->deletedCount.load(); + auto after_deletedCount = ref_databasePager->deleteQueue->deletedCount.load(); scavenged = (after_deletedCount > before_deletedCount); } diff --git a/src/vsg/io/DatabasePager.cpp b/src/vsg/io/DatabasePager.cpp index 40d9a4f7e3..c5fd04e450 100644 --- a/src/vsg/io/DatabasePager.cpp +++ b/src/vsg/io/DatabasePager.cpp @@ -487,13 +487,13 @@ DatabaseQueue::Nodes DatabaseQueue::take_all(CompileResult& cr) // DatabasePager::DatabasePager() { - if (!_status) _status = ActivityStatus::create(); + if (!status) status = ActivityStatus::create(); culledPagedLODs = CulledPagedLODs::create(); - _requestQueue = DatabaseQueue::create(_status); - _toMergeQueue = DatabaseQueue::create(_status); - _deleteQueue = DeleteQueue::create(_status); + _requestQueue = DatabaseQueue::create(status); + _toMergeQueue = DatabaseQueue::create(status); + deleteQueue = DeleteQueue::create(status); pagedLODContainer = PagedLODContainer::create(4000); } @@ -502,7 +502,7 @@ DatabasePager::~DatabasePager() { debug("DatabasePager::~DatabasePager()"); - _status->set(false); + status->set(false); for (auto& thread : threads) { @@ -522,15 +522,15 @@ void DatabasePager::start(uint32_t numReadThreads) // // set up read thread(s) // - auto readThread = [](ref_ptr requestQueue, ref_ptr status, DatabasePager& databasePager, const std::string& threadName) { + auto readThread = [](DatabasePager& databasePager, const std::string& threadName) { debug("Started DatabaseThread read thread"); auto local_instrumentation = shareOrDuplicateForThreadSafety(databasePager.instrumentation); if (local_instrumentation) local_instrumentation->setThreadName(threadName); - while (status->active()) + while (databasePager.status->active()) { - auto plod = requestQueue->take_when_available(databasePager.frameCount.load()); + auto plod = databasePager._requestQueue->take_when_available(databasePager.frameCount.load()); if (plod) { CPU_INSTRUMENTATION_L1_NC(databasePager.instrumentation, "DatabasePager read", COLOR_PAGER); @@ -610,25 +610,25 @@ void DatabasePager::start(uint32_t numReadThreads) debug("Finished DatabaseThread read thread"); }; - auto deleteThread = [](ref_ptr deleteQueue, ref_ptr status, const DatabasePager& databasePager, const std::string& threadName) { + auto deleteThread = [](DatabasePager& databasePager, const std::string& threadName) { debug("Started DatabaseThread deletethread"); auto local_instrumentation = shareOrDuplicateForThreadSafety(databasePager.instrumentation); if (local_instrumentation) local_instrumentation->setThreadName(threadName); - while (status->active()) + while (databasePager.status->active()) { - deleteQueue->wait_then_clear(); + databasePager.deleteQueue->wait_then_clear(); } debug("Finished DatabaseThread delete thread"); }; for (uint32_t i = 0; i < numReadThreads; ++i) { - threads.emplace_back(readThread, std::ref(_requestQueue), std::ref(_status), std::ref(*this), make_string("DatabasePager read thread ", i)); + threads.emplace_back(readThread, std::ref(*this), make_string("DatabasePager read thread ", i)); } - threads.emplace_back(deleteThread, std::ref(_deleteQueue), std::ref(_status), std::ref(*this), "DatabasePager delete thread "); + threads.emplace_back(deleteThread, std::ref(*this), "DatabasePager delete thread "); } void DatabasePager::request(ref_ptr plod) @@ -689,7 +689,7 @@ void DatabasePager::updateSceneGraph(ref_ptr frameStamp, CompileResu CPU_INSTRUMENTATION_L1(instrumentation); frameCount.exchange(frameStamp ? frameStamp->frameCount : 0); - _deleteQueue->advance(frameStamp); + deleteQueue->advance(frameStamp); numActiveRequests -= _requestQueue->prune(frameCount.load()); @@ -815,5 +815,5 @@ void DatabasePager::updateSceneGraph(ref_ptr frameStamp, CompileResu debug("DatabasePager::updateSceneGraph() nothing to merge"); } - if (!deleteList.empty() || !sharedObjectsToPrune.empty()) _deleteQueue->add_prune(deleteList, sharedObjectsToPrune); + if (!deleteList.empty() || !sharedObjectsToPrune.empty()) deleteQueue->add_prune(deleteList, sharedObjectsToPrune); } From 318e436dca48d9253110b4e8ff2b96ccbe9698ec Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 13 Apr 2026 17:05:41 +0100 Subject: [PATCH 26/80] Ran clang-format --- src/vsg/vk/MemoryBufferPools.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vsg/vk/MemoryBufferPools.cpp b/src/vsg/vk/MemoryBufferPools.cpp index 01f0a2df9a..e81ca6e227 100644 --- a/src/vsg/vk/MemoryBufferPools.cpp +++ b/src/vsg/vk/MemoryBufferPools.cpp @@ -232,7 +232,6 @@ VkResult MemoryBufferPools::reserve(ResourceRequirements& requirements) decltype(requirements.bufferInfos) failed_bufferInfos; decltype(requirements.imageInfos) failed_imageInfos; - // allocate bufferInfos bool allocationSuccess = true; for (auto& [properties, bufferInfos] : requirements.bufferInfos) From b9ef913477888525f7975f052e1efaf05cc8ee10 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 13 Apr 2026 19:13:26 +0100 Subject: [PATCH 27/80] Fixed spelling errors in headers --- include/vsg/app/CompileManager.h | 2 +- include/vsg/core/type_name.h | 2 +- include/vsg/nodes/InstanceNode.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/vsg/app/CompileManager.h b/include/vsg/app/CompileManager.h index f23c1dcdcf..ee61ac9dbc 100644 --- a/include/vsg/app/CompileManager.h +++ b/include/vsg/app/CompileManager.h @@ -83,7 +83,7 @@ namespace vsg /// compile all the command graphs in a task CompileResult compileTask(ref_ptr task, const ResourceRequirements& resourceRequirements = {}); - /// mechinism for releasing and reusing used resources + /// mechanism for releasing and reusing used resources ref_ptr resourceScavenger; std::atomic_uint successfulCompileCount{0}; diff --git a/include/vsg/core/type_name.h b/include/vsg/core/type_name.h index 318a49baa1..4972050d23 100644 --- a/include/vsg/core/type_name.h +++ b/include/vsg/core/type_name.h @@ -49,7 +49,7 @@ namespace vsg template<> constexpr const char* vsg::type_name() noexcept { return #T; } \ template<> constexpr const char* vsg::type_name() noexcept { return "const "#T; } - /// convinience function for adding a space in front of the type_name string. + /// convenience function for adding a space in front of the type_name string. template std::string space_type_name(const T&) { return std::string(" ") + type_name(); } diff --git a/include/vsg/nodes/InstanceNode.h b/include/vsg/nodes/InstanceNode.h index dea9962742..caadc408ce 100644 --- a/include/vsg/nodes/InstanceNode.h +++ b/include/vsg/nodes/InstanceNode.h @@ -21,10 +21,10 @@ namespace vsg { /// InstanceNode provides a mechanism for specifying the translations, rotations and scales (transform arrays) of subgraph - /// that contains InstanceDraw leaf node(s) that utlize the InstanceNode's per instance transform arrays combined with the + /// that contains InstanceDraw leaf node(s) that utilize the InstanceNode's per instance transform arrays combined with the /// InstanceDraw nodes per vertex arrays. /// - /// InstanceNode only work correctly when the child subgraphs that obey these contraints: + /// InstanceNode only work correctly when the child subgraphs that obey these constraints: /// 1. Do not contain any Transform nodes /// 2. Do not contain any Culling nodes /// 3. Do not contain any InstanceNode nodes From ed0c597388dddcd17c0d51649cab64af9a57decd Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 13 Apr 2026 19:15:53 +0100 Subject: [PATCH 28/80] Fixed spelling errors --- src/vsg/io/JSONParser.cpp | 2 +- src/vsg/vk/Instance.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vsg/io/JSONParser.cpp b/src/vsg/io/JSONParser.cpp index dee3ee2872..770a707ff4 100644 --- a/src/vsg/io/JSONParser.cpp +++ b/src/vsg/io/JSONParser.cpp @@ -370,7 +370,7 @@ void JSONParser::read_object(JSONParser::Schema& schema) break; } - // make sure next charater is the {name : value} deliminator + // make sure next character is the {name : value} deliminator if (buffer[pos] != ':') { warning("read_object() deliminator error buffer[", pos, "] = ", buffer[pos]); diff --git a/src/vsg/vk/Instance.cpp b/src/vsg/vk/Instance.cpp index d34e3b9297..9c500ed371 100644 --- a/src/vsg/vk/Instance.cpp +++ b/src/vsg/vk/Instance.cpp @@ -156,7 +156,7 @@ Instance::Instance(Names instanceExtensions, Names layers, uint32_t vulkanApiVer std::vector enabledValidationFeatures; std::vector disabledValidationFeatures; - // syncronization validation requires VkValidationFeaturesEXT + // synchronization validation requires VkValidationFeaturesEXT if (containsInstanceLayerName(layers, "VK_LAYER_KHRONOS_synchronization2")) enabledValidationFeatures.push_back(VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT); // set up the VkValidationFeaturesEXT if required From 8d05c1058d53b60307f72ab99e223a1c4d15163b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 13 Apr 2026 19:49:08 +0100 Subject: [PATCH 29/80] Removed old code --- src/vsg/io/DatabasePager.cpp | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/src/vsg/io/DatabasePager.cpp b/src/vsg/io/DatabasePager.cpp index c5fd04e450..0299628bad 100644 --- a/src/vsg/io/DatabasePager.cpp +++ b/src/vsg/io/DatabasePager.cpp @@ -633,41 +633,12 @@ void DatabasePager::start(uint32_t numReadThreads) void DatabasePager::request(ref_ptr plod) { -#if 0 - ++numActiveRequests; - - bool hasPending = false; - { - std::scoped_lock lock(pendingPagedLODMutex); - hasPending = plod->pending.valid(); - } - - if (!hasPending) - { - if (compare_exchange(plod->requestStatus, PagedLOD::NoRequest, PagedLOD::ReadRequest)) - { - // debug("DatabasePager::request(", plod.get(), ") adding to requestQueue ", plod->filename, ", ", plod->priority, " plod=", plod.get()); - _requestQueue->add(plod); - } - else - { - // debug("Attempted DatabasePager::request(", plod.get(), ") but plod.requestState() = ", plod->requestStatus.load(), " is not NoRequest"); - } - } - else - { - // debug("Attempted DatabasePager::request(", plod.get(), ") but plod.pending is not null."); - } -#else - if (compare_exchange(plod->requestStatus, PagedLOD::NoRequest, PagedLOD::ReadRequest)) { - // debug("DatabasePager::request(", plod.get(), ") adding to requestQueue ", plod->filename, ", ", plod->priority, " plod=", plod.get()); + debug("DatabasePager::request(", plod.get(), ") adding to requestQueue ", plod->filename, ", ", plod->priority, " plod=", plod.get()); _requestQueue->add(plod); ++numActiveRequests; } - -#endif } void DatabasePager::requestDiscarded(PagedLOD* plod) From 24f21dab153448337115672c5f543d521b423521 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 14 Apr 2026 10:56:53 +0100 Subject: [PATCH 30/80] Replaced using namespace tracy with local tracy:: usage --- include/vsg/utils/TracyInstrumentation.h | 40 +++++++++++------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/include/vsg/utils/TracyInstrumentation.h b/include/vsg/utils/TracyInstrumentation.h index 3f9d8aff74..1d6bd86132 100644 --- a/include/vsg/utils/TracyInstrumentation.h +++ b/include/vsg/utils/TracyInstrumentation.h @@ -17,8 +17,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include -using namespace tracy; - namespace vsg { @@ -35,7 +33,7 @@ namespace vsg class TracyContexts : public Inherit { public: - VkCtx* getOrCreateContext(CommandBuffer& commandBuffer) const + tracy::VkCtx* getOrCreateContext(CommandBuffer& commandBuffer) const { std::scoped_lock lock(mutex); @@ -79,7 +77,7 @@ namespace vsg } mutable std::mutex mutex; - mutable std::map, std::pair> ctxMap; + mutable std::map, std::pair> ctxMap; protected: ~TracyContexts() @@ -111,7 +109,7 @@ namespace vsg ref_ptr settings; ref_ptr contexts; - mutable VkCtx* ctx = nullptr; + mutable tracy::VkCtx* ctx = nullptr; bool requiresCollection = false; ref_ptr shareOrDuplicateForThreadSafety() override @@ -151,9 +149,9 @@ namespace vsg reference = 1; # endif - TracyQueuePrepare(QueueType::ZoneBegin); - MemWrite(&item->zoneBegin.time, tracy::Profiler::GetTime()); - MemWrite(&item->zoneBegin.srcloc, (uint64_t)slcloc); + TracyQueuePrepare(tracy::QueueType::ZoneBegin); + tracy::MemWrite(&item->zoneBegin.time, tracy::Profiler::GetTime()); + tracy::MemWrite(&item->zoneBegin.srcloc, (uint64_t)slcloc); TracyQueueCommit(zoneBeginThread); } @@ -165,8 +163,8 @@ namespace vsg if (reference == 0) return; # endif - TracyQueuePrepare(QueueType::ZoneEnd); - MemWrite(&item->zoneEnd.time, tracy::Profiler::GetTime()); + TracyQueuePrepare(tracy::QueueType::ZoneEnd); + tracy::MemWrite(&item->zoneEnd.time, tracy::Profiler::GetTime()); TracyQueueCommit(zoneEndThread); } @@ -210,12 +208,12 @@ namespace vsg CONTEXT_VK_FUNCTION_WRAPPER(vkCmdWriteTimestamp(cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, ctx->GetQueryPool(), queryId)); auto item = tracy::Profiler::QueueSerial(); - MemWrite(&item->hdr.type, QueueType::GpuZoneBeginSerial); - MemWrite(&item->gpuZoneBegin.cpuTime, tracy::Profiler::GetTime()); - MemWrite(&item->gpuZoneBegin.srcloc, (uint64_t)slcloc); - MemWrite(&item->gpuZoneBegin.thread, GetThreadHandle()); - MemWrite(&item->gpuZoneBegin.queryId, uint16_t(queryId)); - MemWrite(&item->gpuZoneBegin.context, ctx->GetId()); + tracy::MemWrite(&item->hdr.type, tracy::QueueType::GpuZoneBeginSerial); + tracy::MemWrite(&item->gpuZoneBegin.cpuTime, tracy::Profiler::GetTime()); + tracy::MemWrite(&item->gpuZoneBegin.srcloc, (uint64_t)slcloc); + tracy::MemWrite(&item->gpuZoneBegin.thread, tracy::GetThreadHandle()); + tracy::MemWrite(&item->gpuZoneBegin.queryId, uint16_t(queryId)); + tracy::MemWrite(&item->gpuZoneBegin.context, ctx->GetId()); tracy::Profiler::QueueSerialFinish(); } @@ -231,11 +229,11 @@ namespace vsg CONTEXT_VK_FUNCTION_WRAPPER(vkCmdWriteTimestamp(cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, ctx->GetQueryPool(), queryId)); auto item = tracy::Profiler::QueueSerial(); - MemWrite(&item->hdr.type, QueueType::GpuZoneEndSerial); - MemWrite(&item->gpuZoneEnd.cpuTime, tracy::Profiler::GetTime()); - MemWrite(&item->gpuZoneEnd.thread, GetThreadHandle()); - MemWrite(&item->gpuZoneEnd.queryId, uint16_t(queryId)); - MemWrite(&item->gpuZoneEnd.context, ctx->GetId()); + tracy::MemWrite(&item->hdr.type, tracy::QueueType::GpuZoneEndSerial); + tracy::MemWrite(&item->gpuZoneEnd.cpuTime, tracy::Profiler::GetTime()); + tracy::MemWrite(&item->gpuZoneEnd.thread, tracy::GetThreadHandle()); + tracy::MemWrite(&item->gpuZoneEnd.queryId, uint16_t(queryId)); + tracy::MemWrite(&item->gpuZoneEnd.context, ctx->GetId()); tracy::Profiler::QueueSerialFinish(); } }; From 94ca4d948c511de73de60cf958860020b66ebdfd Mon Sep 17 00:00:00 2001 From: Mikhail Arepev Date: Tue, 14 Apr 2026 23:34:47 +0300 Subject: [PATCH 31/80] Reset PagedLODs requestStatus and requestCount when they are pruned from queue --- src/vsg/io/DatabasePager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vsg/io/DatabasePager.cpp b/src/vsg/io/DatabasePager.cpp index 0299628bad..4b3fd61da8 100644 --- a/src/vsg/io/DatabasePager.cpp +++ b/src/vsg/io/DatabasePager.cpp @@ -461,6 +461,8 @@ uint32_t DatabaseQueue::prune(uint64_t frameCount) { // info("pruning ", *itr, ", lastUsed = ", (*itr)->frameHighResLastUsed.load(), " vs ", frameCount, " after ", (*itr)->loadAttempts.load(), " loadAttempts"); ++numRemoved; + (*itr)->requestCount.exchange(0); + (*itr)->requestStatus.exchange(PagedLOD::NoRequest); itr = _queue.erase(itr); } else From 82f6d501d4117793e43ce19b41af920e8f562140 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 15 Apr 2026 09:41:39 +0100 Subject: [PATCH 32/80] Added serialization support for std::set --- include/vsg/io/stream.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/include/vsg/io/stream.h b/include/vsg/io/stream.h index b1cf8c0251..97afdb2392 100644 --- a/include/vsg/io/stream.h +++ b/include/vsg/io/stream.h @@ -30,6 +30,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include +#include namespace vsg { @@ -333,4 +334,28 @@ namespace vsg return output; } + template + std::ostream& operator<<(std::ostream& output, const std::set& values) + { + if (values.empty()) + output << "{}"; + else + { + output << "{ "; + + bool first = true; + for(auto& value : values) + { + if (!first) output << ", "; + else first = false; + + output << value; + } + + output << " }"; + } + return output; + } + + } // namespace vsg From 8d0133009af0188d5adf3a3cf7a98ade6988b915 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 15 Apr 2026 10:22:26 +0100 Subject: [PATCH 33/80] Removed erroneous header version check --- include/vsg/vk/vulkan.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/include/vsg/vk/vulkan.h b/include/vsg/vk/vulkan.h index 2c25d49214..121bc1a731 100644 --- a/include/vsg/vk/vulkan.h +++ b/include/vsg/vk/vulkan.h @@ -308,12 +308,6 @@ typedef struct VkPhysicalDeviceBufferDeviceAddressFeaturesEXT } VkPhysicalDeviceBufferDeviceAddressFeaturesEXT; #endif -//////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Definitions not provided prior to 1.1.106 -// -#if VK_HEADER_VERSION < 105 - #define VK_EXT_host_query_reset 1 #define VK_EXT_HOST_QUERY_RESET_SPEC_VERSION 1 #define VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME "VK_EXT_host_query_reset" @@ -325,9 +319,6 @@ typedef struct VkPhysicalDeviceHostQueryResetFeaturesEXT { typedef void (VKAPI_PTR *PFN_vkResetQueryPoolEXT)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); - - - #endif //////////////////////////////////////////////////////////////////////////////////////////////////// From b05787b4f78a43ff81c5b0fd5a3909eebe2b4213 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 15 Apr 2026 10:27:27 +0100 Subject: [PATCH 34/80] Fixed comment --- include/vsg/vk/vulkan.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/vsg/vk/vulkan.h b/include/vsg/vk/vulkan.h index 121bc1a731..80c95447b3 100644 --- a/include/vsg/vk/vulkan.h +++ b/include/vsg/vk/vulkan.h @@ -894,7 +894,7 @@ typedef VkResult(VKAPI_PTR* PFN_vkCreateRenderPass2KHR_Compatibility)(VkDevice d typedef VkDeviceAddress(VKAPI_PTR* PFN_vkGetBufferDeviceAddressKHR_Compatibility)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); // -// Definitions not provided prior to 1.3.211 +// Definitions not provided prior to 1.3.204 // #if VK_HEADER_VERSION < 204 #define VK_API_VERSION_1_3 VK_MAKE_VERSION(1, 3, 0) From e8d09173076e63e393f680c3040bd2fb6c82f3ec Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 15 Apr 2026 10:53:33 +0100 Subject: [PATCH 35/80] Removed stray #endif --- include/vsg/vk/vulkan.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/vsg/vk/vulkan.h b/include/vsg/vk/vulkan.h index 80c95447b3..58377c02dc 100644 --- a/include/vsg/vk/vulkan.h +++ b/include/vsg/vk/vulkan.h @@ -306,7 +306,6 @@ typedef struct VkPhysicalDeviceBufferDeviceAddressFeaturesEXT VkBool32 bufferDeviceAddressCaptureReplay; VkBool32 bufferDeviceAddressMultiDevice; } VkPhysicalDeviceBufferDeviceAddressFeaturesEXT; -#endif #define VK_EXT_host_query_reset 1 #define VK_EXT_HOST_QUERY_RESET_SPEC_VERSION 1 From 0db4ca368a3194089a2d07e2ad2536a506dbf444 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 15 Apr 2026 11:07:01 +0100 Subject: [PATCH 36/80] Moved the definition of VK_EXT_validation_features into non versioned check to workout lack of information which version. --- include/vsg/vk/vulkan.h | 77 +++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 41 deletions(-) diff --git a/include/vsg/vk/vulkan.h b/include/vsg/vk/vulkan.h index 58377c02dc..e1608f401d 100644 --- a/include/vsg/vk/vulkan.h +++ b/include/vsg/vk/vulkan.h @@ -289,6 +289,42 @@ typedef struct VkPhysicalDeviceFloatControlsPropertiesKHR #endif +#ifndef VK_EXT_validation_features + +#define VK_EXT_validation_features 1 +#define VK_EXT_VALIDATION_FEATURES_SPEC_VERSION 4 +#define VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME "VK_EXT_validation_features" + +typedef enum VkValidationFeatureEnableEXT { + VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT = 0, + VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT = 1, + VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT = 2, + VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT = 3, + VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT = 4, + VK_VALIDATION_FEATURE_ENABLE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkValidationFeatureEnableEXT; + +typedef enum VkValidationFeatureDisableEXT { + VK_VALIDATION_FEATURE_DISABLE_ALL_EXT = 0, + VK_VALIDATION_FEATURE_DISABLE_SHADERS_EXT = 1, + VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT = 2, + VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT = 3, + VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT = 4, + VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT = 5, + VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT = 6, + VK_VALIDATION_FEATURE_DISABLE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkValidationFeatureDisableEXT; +typedef struct VkValidationFeaturesEXT { + VkStructureType sType; + const void* pNext; + uint32_t enabledValidationFeatureCount; + const VkValidationFeatureEnableEXT* pEnabledValidationFeatures; + uint32_t disabledValidationFeatureCount; + const VkValidationFeatureDisableEXT* pDisabledValidationFeatures; +} VkValidationFeaturesEXT; + +#endif + //////////////////////////////////////////////////////////////////////////////////////////////////// // // Definitions not provided prior to 1.1.106 @@ -563,47 +599,6 @@ typedef enum VkRayTracingShaderGroupTypeKHR #endif - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Definitions not provided prior to 1.2.150 -// -#if VK_HEADER_VERSION < 150 - -#define VK_EXT_validation_features 1 -#define VK_EXT_VALIDATION_FEATURES_SPEC_VERSION 4 -#define VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME "VK_EXT_validation_features" - -typedef enum VkValidationFeatureEnableEXT { - VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT = 0, - VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT = 1, - VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT = 2, - VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT = 3, - VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT = 4, - VK_VALIDATION_FEATURE_ENABLE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkValidationFeatureEnableEXT; - -typedef enum VkValidationFeatureDisableEXT { - VK_VALIDATION_FEATURE_DISABLE_ALL_EXT = 0, - VK_VALIDATION_FEATURE_DISABLE_SHADERS_EXT = 1, - VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT = 2, - VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT = 3, - VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT = 4, - VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT = 5, - VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT = 6, - VK_VALIDATION_FEATURE_DISABLE_MAX_ENUM_EXT = 0x7FFFFFFF -} VkValidationFeatureDisableEXT; -typedef struct VkValidationFeaturesEXT { - VkStructureType sType; - const void* pNext; - uint32_t enabledValidationFeatureCount; - const VkValidationFeatureEnableEXT* pEnabledValidationFeatures; - uint32_t disabledValidationFeatureCount; - const VkValidationFeatureDisableEXT* pDisabledValidationFeatures; -} VkValidationFeaturesEXT; - -#endif - //////////////////////////////////////////////////////////////////////////////////////////////////// // // Definitions not provided prior to 1.2.162 From 470f15461e32f3aef1b2623f59b0c74e952aac8c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 15 Apr 2026 12:07:47 +0100 Subject: [PATCH 37/80] Added handling of revisions of VK_EXT_validation_features extension --- include/vsg/vk/vulkan.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/vsg/vk/vulkan.h b/include/vsg/vk/vulkan.h index e1608f401d..8891878715 100644 --- a/include/vsg/vk/vulkan.h +++ b/include/vsg/vk/vulkan.h @@ -323,6 +323,13 @@ typedef struct VkValidationFeaturesEXT { const VkValidationFeatureDisableEXT* pDisabledValidationFeatures; } VkValidationFeaturesEXT; +#else + +#if (VK_EXT_VALIDATION_FEATURES_SPEC_VERSION < 4) +#define VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT static_cast(4) +#endif + + #endif //////////////////////////////////////////////////////////////////////////////////////////////////// From 4f3804d644119a8dcddd4cf11f265186b1d94146 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 15 Apr 2026 13:55:02 +0100 Subject: [PATCH 38/80] Removed unused entries that were causing conflicts --- include/vsg/vk/vulkan.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/vsg/vk/vulkan.h b/include/vsg/vk/vulkan.h index 8891878715..b110de3d96 100644 --- a/include/vsg/vk/vulkan.h +++ b/include/vsg/vk/vulkan.h @@ -415,10 +415,6 @@ typedef enum VkDescriptorBindingFlagBits { VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT = 0x00000002, VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT = 0x00000004, VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT = 0x00000008, - VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, - VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT, - VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT, - VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT, VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VkDescriptorBindingFlagBits; typedef VkFlags VkDescriptorBindingFlags; From 762f97abf2b3948d4b8b4da3d9d4e4c76e32c5e8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 15 Apr 2026 15:04:54 +0100 Subject: [PATCH 39/80] Added compatility with vulan_core.h older than 1.1.97 --- include/vsg/vk/vulkan.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/vsg/vk/vulkan.h b/include/vsg/vk/vulkan.h index b110de3d96..1afa8e30ce 100644 --- a/include/vsg/vk/vulkan.h +++ b/include/vsg/vk/vulkan.h @@ -149,6 +149,12 @@ typedef struct VkMemoryPriorityAllocateInfoEXT { float priority; } VkMemoryPriorityAllocateInfoEXT; + +#define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT VkStructureType(1000202000) +#define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_EXT VkStructureType(1000202001) +#define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT VkStructureType(1000237000) +#define VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT VkStructureType(1000247000) + #endif //////////////////////////////////////////////////////////////////////////////////////////////////// From ba3ee37ab313280e3dd03a170ad9da057d2310e4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 16 Apr 2026 15:51:59 +0100 Subject: [PATCH 40/80] Refactore how GraphicsPipelineCongfigurator::compare() handles the shaderHints->defines and descriptorConfigurator->defines together to avoid failure to match compatible configurations. --- include/vsg/state/ShaderModule.h | 2 + src/vsg/state/ShaderModule.cpp | 12 ++- .../utils/GraphicsPipelineConfigurator.cpp | 96 ++++++++++++++++++- 3 files changed, 104 insertions(+), 6 deletions(-) diff --git a/include/vsg/state/ShaderModule.h b/include/vsg/state/ShaderModule.h index a57ff2e295..c55e2407ae 100644 --- a/include/vsg/state/ShaderModule.h +++ b/include/vsg/state/ShaderModule.h @@ -59,6 +59,8 @@ namespace vsg public: ref_ptr clone(const CopyOp& copyop = {}) const override { return ShaderCompileSettings::create(*this, copyop); } + + virtual int compare_except_defines(const Object& rhs_object) const; int compare(const Object& rhs_object) const override; void read(Input& input) override; diff --git a/src/vsg/state/ShaderModule.cpp b/src/vsg/state/ShaderModule.cpp index e3f566e0e3..2a666ba3a6 100644 --- a/src/vsg/state/ShaderModule.cpp +++ b/src/vsg/state/ShaderModule.cpp @@ -40,7 +40,7 @@ ShaderCompileSettings::ShaderCompileSettings(const ShaderCompileSettings& rhs, c { } -int ShaderCompileSettings::compare(const Object& rhs_object) const +int ShaderCompileSettings::compare_except_defines(const Object& rhs_object) const { int result = Object::compare(rhs_object); if (result != 0) return result; @@ -54,7 +54,15 @@ int ShaderCompileSettings::compare(const Object& rhs_object) const if ((result = compare_value(target, rhs.target))) return result; if ((result = compare_value(forwardCompatible, rhs.forwardCompatible))) return result; if ((result = compare_value(generateDebugInfo, rhs.generateDebugInfo))) return result; - if ((result = compare_value(optimize, rhs.optimize))) return result; + return compare_value(optimize, rhs.optimize); +} + +int ShaderCompileSettings::compare(const Object& rhs_object) const +{ + int result = compare_except_defines(rhs_object); + if (result != 0) return result; + + const auto& rhs = static_cast(rhs_object); return compare_container(defines, rhs.defines); } diff --git a/src/vsg/utils/GraphicsPipelineConfigurator.cpp b/src/vsg/utils/GraphicsPipelineConfigurator.cpp index c15e3aa99c..0349d2b912 100644 --- a/src/vsg/utils/GraphicsPipelineConfigurator.cpp +++ b/src/vsg/utils/GraphicsPipelineConfigurator.cpp @@ -535,8 +535,98 @@ int GraphicsPipelineConfigurator::compare(const Object& rhs_object) const if ((result = compare_value(baseAttributeBinding, rhs.baseAttributeBinding))) return result; if ((result = compare_pointer(shaderSet, rhs.shaderSet))) return result; - if ((result = compare_pointer(shaderHints, rhs.shaderHints))) return result; - if ((result = compare_pointer_container(inheritedState, rhs.inheritedState))) return result; + // + // defines settings for ShaderHints may not yet be in final state, so comparing them between compatible GraphicsPipelineConfigurator + // objects can lead is not returning a match when just comparing shaderHint->defines. + // To resolve this do the shint hint compare wihtout the defines, and then do the comparison of defines + // by handling both the respective descriptorConfigurator->defines and shaderHints->defines when comparing to the rhs. + // + // The compare_shaderHints, IteratorPair and Iterator structs all exist in service of this mutliset comparison. + // + + auto compare_shaderHints = [](const ref_ptr& lsh, const ref_ptr& rsh) -> int + { + if (lsh == rsh) return 0; + return lsh ? (rsh ? lsh->compare_except_defines(*rsh) : 1) : (rsh ? -1 : 0); + }; + + if ((result = compare_shaderHints(shaderHints, rhs.shaderHints))) return result; + + struct IteratorPair + { + using iterator = std::set::const_iterator; + iterator itr; + iterator end; + + explicit IteratorPair(const std::set& values) : itr(values.begin()), end(values.end()) {} + + bool valid() const { return itr != end; } + }; + + struct Iterator + { + IteratorPair lhs; + IteratorPair rhs; + + explicit Iterator(IteratorPair in_lhs, IteratorPair in_rhs) : lhs(in_lhs), rhs(in_rhs) {} + + bool valid() const { return lhs.valid() || rhs.valid(); } + + /// only call when valid() return true + const std::string& value() const + { + if (lhs.valid()) + { + if (rhs.valid()) + { + if (*lhs.itr < *rhs.itr) return *lhs.itr; + else if (*rhs.itr < *lhs.itr ) return *rhs.itr; + else { return *rhs.itr; } + } + else return *lhs.itr; + } + else return *rhs.itr; + } + + bool advance() + { + if (lhs.valid()) + { + if (rhs.valid()) + { + if (*lhs.itr < *rhs.itr) lhs.itr++; + else if (*rhs.itr < *lhs.itr) rhs.itr++; + else { ++lhs.itr; ++rhs.itr; } + } + else lhs.itr++; + } + else if (rhs.valid()) rhs.itr++; + + return valid(); + } + }; + + auto local_compare = [](Iterator ilhs, Iterator irhs) -> int + { + while(ilhs.valid() && irhs.valid()) + { + const auto& lhs_value = ilhs.value(); + const auto& rhs_value = irhs.value(); + if (lhs_value < rhs_value) return -1; + else if (lhs_value > rhs_value) return 1; + + ilhs.advance(); + irhs.advance(); + } + + if (ilhs.valid()) return 1; + return irhs.valid() ? -1 : 0; + }; + + result = local_compare(Iterator(IteratorPair(descriptorConfigurator->defines), IteratorPair(shaderHints->defines)), + Iterator(IteratorPair(rhs.descriptorConfigurator->defines), IteratorPair(rhs.shaderHints->defines))); + + if (result) return result; return compare_pointer(descriptorConfigurator, rhs.descriptorConfigurator); } @@ -612,8 +702,6 @@ void GraphicsPipelineConfigurator::_assignInheritedSets() void GraphicsPipelineConfigurator::init() { - // if (!descriptorConfigurator) descriptorConfigurator = DescriptorConfigurator::create(shaderSet); - _assignInheritedSets(); if (descriptorConfigurator) From e8e1e10380ece93ab4d64757460d2cfb9935bf15 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 17 Apr 2026 09:00:10 +0100 Subject: [PATCH 41/80] Ran clang-format --- include/vsg/io/stream.h | 11 ++-- src/vsg/app/CompileManager.cpp | 7 ++- .../utils/GraphicsPipelineConfigurator.cpp | 50 ++++++++++++------- 3 files changed, 44 insertions(+), 24 deletions(-) diff --git a/include/vsg/io/stream.h b/include/vsg/io/stream.h index 97afdb2392..6aa98ccde8 100644 --- a/include/vsg/io/stream.h +++ b/include/vsg/io/stream.h @@ -29,8 +29,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include -#include #include +#include namespace vsg { @@ -344,10 +344,12 @@ namespace vsg output << "{ "; bool first = true; - for(auto& value : values) + for (auto& value : values) { - if (!first) output << ", "; - else first = false; + if (!first) + output << ", "; + else + first = false; output << value; } @@ -357,5 +359,4 @@ namespace vsg return output; } - } // namespace vsg diff --git a/src/vsg/app/CompileManager.cpp b/src/vsg/app/CompileManager.cpp index 742e8020d1..5799abeec8 100644 --- a/src/vsg/app/CompileManager.cpp +++ b/src/vsg/app/CompileManager.cpp @@ -227,11 +227,16 @@ CompileResult CompileManager::compile(ref_ptr object, ContextSelectionFu result.containsPagedLOD = requirements.containsPagedLOD; result.views = requirements.views; result.dynamicData = requirements.dynamicData; + result.message = "Nothing assigned yet."; auto compileTraversal = compileTraversals->take_when_available(); // if no CompileTraversals are available abort compile - if (!compileTraversal) return result; + if (!compileTraversal) + { + info("Unable to aquire compileTraversal."); + return result; + } auto run_compile_traversal = [&]() -> void { try diff --git a/src/vsg/utils/GraphicsPipelineConfigurator.cpp b/src/vsg/utils/GraphicsPipelineConfigurator.cpp index 0349d2b912..705f335ca8 100644 --- a/src/vsg/utils/GraphicsPipelineConfigurator.cpp +++ b/src/vsg/utils/GraphicsPipelineConfigurator.cpp @@ -544,8 +544,7 @@ int GraphicsPipelineConfigurator::compare(const Object& rhs_object) const // The compare_shaderHints, IteratorPair and Iterator structs all exist in service of this mutliset comparison. // - auto compare_shaderHints = [](const ref_ptr& lsh, const ref_ptr& rsh) -> int - { + auto compare_shaderHints = [](const ref_ptr& lsh, const ref_ptr& rsh) -> int { if (lsh == rsh) return 0; return lsh ? (rsh ? lsh->compare_except_defines(*rsh) : 1) : (rsh ? -1 : 0); }; @@ -558,7 +557,8 @@ int GraphicsPipelineConfigurator::compare(const Object& rhs_object) const iterator itr; iterator end; - explicit IteratorPair(const std::set& values) : itr(values.begin()), end(values.end()) {} + explicit IteratorPair(const std::set& values) : + itr(values.begin()), end(values.end()) {} bool valid() const { return itr != end; } }; @@ -568,7 +568,8 @@ int GraphicsPipelineConfigurator::compare(const Object& rhs_object) const IteratorPair lhs; IteratorPair rhs; - explicit Iterator(IteratorPair in_lhs, IteratorPair in_rhs) : lhs(in_lhs), rhs(in_rhs) {} + explicit Iterator(IteratorPair in_lhs, IteratorPair in_rhs) : + lhs(in_lhs), rhs(in_rhs) {} bool valid() const { return lhs.valid() || rhs.valid(); } @@ -579,13 +580,17 @@ int GraphicsPipelineConfigurator::compare(const Object& rhs_object) const { if (rhs.valid()) { - if (*lhs.itr < *rhs.itr) return *lhs.itr; - else if (*rhs.itr < *lhs.itr ) return *rhs.itr; + if (*lhs.itr < *rhs.itr) + return *lhs.itr; + else if (*rhs.itr < *lhs.itr) + return *rhs.itr; else { return *rhs.itr; } } - else return *lhs.itr; + else + return *lhs.itr; } - else return *rhs.itr; + else + return *rhs.itr; } bool advance() @@ -594,26 +599,35 @@ int GraphicsPipelineConfigurator::compare(const Object& rhs_object) const { if (rhs.valid()) { - if (*lhs.itr < *rhs.itr) lhs.itr++; - else if (*rhs.itr < *lhs.itr) rhs.itr++; - else { ++lhs.itr; ++rhs.itr; } + if (*lhs.itr < *rhs.itr) + lhs.itr++; + else if (*rhs.itr < *lhs.itr) + rhs.itr++; + else + { + ++lhs.itr; + ++rhs.itr; + } } - else lhs.itr++; + else + lhs.itr++; } - else if (rhs.valid()) rhs.itr++; + else if (rhs.valid()) + rhs.itr++; return valid(); } }; - auto local_compare = [](Iterator ilhs, Iterator irhs) -> int - { - while(ilhs.valid() && irhs.valid()) + auto local_compare = [](Iterator ilhs, Iterator irhs) -> int { + while (ilhs.valid() && irhs.valid()) { const auto& lhs_value = ilhs.value(); const auto& rhs_value = irhs.value(); - if (lhs_value < rhs_value) return -1; - else if (lhs_value > rhs_value) return 1; + if (lhs_value < rhs_value) + return -1; + else if (lhs_value > rhs_value) + return 1; ilhs.advance(); irhs.advance(); From c4750ff3dba79037a9ddd79f881d66705bd8da58 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 17 Apr 2026 09:57:38 +0100 Subject: [PATCH 42/80] cppcheck fixes --- include/vsg/io/stream.h | 4 ++-- src/vsg/utils/GraphicsPipelineConfigurator.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/vsg/io/stream.h b/include/vsg/io/stream.h index 6aa98ccde8..66c7ef3e51 100644 --- a/include/vsg/io/stream.h +++ b/include/vsg/io/stream.h @@ -344,14 +344,14 @@ namespace vsg output << "{ "; bool first = true; - for (auto& value : values) + for (const auto& v : values) { if (!first) output << ", "; else first = false; - output << value; + output << v; } output << " }"; diff --git a/src/vsg/utils/GraphicsPipelineConfigurator.cpp b/src/vsg/utils/GraphicsPipelineConfigurator.cpp index 705f335ca8..1aafd47b95 100644 --- a/src/vsg/utils/GraphicsPipelineConfigurator.cpp +++ b/src/vsg/utils/GraphicsPipelineConfigurator.cpp @@ -600,9 +600,9 @@ int GraphicsPipelineConfigurator::compare(const Object& rhs_object) const if (rhs.valid()) { if (*lhs.itr < *rhs.itr) - lhs.itr++; + ++lhs.itr; else if (*rhs.itr < *lhs.itr) - rhs.itr++; + ++rhs.itr; else { ++lhs.itr; @@ -610,10 +610,10 @@ int GraphicsPipelineConfigurator::compare(const Object& rhs_object) const } } else - lhs.itr++; + ++lhs.itr; } else if (rhs.valid()) - rhs.itr++; + ++rhs.itr; return valid(); } From 3bf9066215d349cd13d981f49476d41d976e978d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 22 Apr 2026 17:34:21 +0100 Subject: [PATCH 43/80] Added clone method for meta data. --- include/vsg/core/Object.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/vsg/core/Object.h b/include/vsg/core/Object.h index b29a643b36..242ff12380 100644 --- a/include/vsg/core/Object.h +++ b/include/vsg/core/Object.h @@ -283,4 +283,15 @@ namespace vsg return new_object.template cast(); } + /// clone a named meta data object stored within an object's Auxliary object if available, others default construct object + template + ref_ptr clone(const std::string& key, C container) + { + if (container) + { + if (auto prototype = container->template getRefObject(key)) return vsg::clone(prototype); + } + return T::create(); + } + } // namespace vsg From 2594b01c40e21840cf598bfc00cce58003db13bd Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 22 Apr 2026 18:46:59 +0100 Subject: [PATCH 44/80] Fixed handling of null pointers --- .../utils/GraphicsPipelineConfigurator.cpp | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/vsg/utils/GraphicsPipelineConfigurator.cpp b/src/vsg/utils/GraphicsPipelineConfigurator.cpp index 1aafd47b95..7723c0b136 100644 --- a/src/vsg/utils/GraphicsPipelineConfigurator.cpp +++ b/src/vsg/utils/GraphicsPipelineConfigurator.cpp @@ -557,8 +557,31 @@ int GraphicsPipelineConfigurator::compare(const Object& rhs_object) const iterator itr; iterator end; - explicit IteratorPair(const std::set& values) : - itr(values.begin()), end(values.end()) {} + explicit IteratorPair(const ref_ptr& hints) + { + if (hints) + { + itr = hints->defines.begin(); + end = hints->defines.end(); + } + else + { + itr = end = {}; + } + } + + explicit IteratorPair(const ref_ptr& config) + { + if (config) + { + itr = config->defines.begin(); + end = config->defines.end(); + } + else + { + itr = end = {}; + } + } bool valid() const { return itr != end; } }; @@ -637,8 +660,8 @@ int GraphicsPipelineConfigurator::compare(const Object& rhs_object) const return irhs.valid() ? -1 : 0; }; - result = local_compare(Iterator(IteratorPair(descriptorConfigurator->defines), IteratorPair(shaderHints->defines)), - Iterator(IteratorPair(rhs.descriptorConfigurator->defines), IteratorPair(rhs.shaderHints->defines))); + result = local_compare(Iterator(IteratorPair(descriptorConfigurator), IteratorPair(shaderHints)), + Iterator(IteratorPair(rhs.descriptorConfigurator), IteratorPair(rhs.shaderHints))); if (result) return result; From 57281cde5371a7920c59034f90fc6b07d6358489 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 7 May 2026 16:01:23 +0100 Subject: [PATCH 45/80] Refactord how CompileResults::maxSlots is managed to ensure changes from the DatabasePager gets passed on to updateViewer(..) --- include/vsg/app/CompileManager.h | 3 ++- include/vsg/vk/Slots.h | 9 ++++++++- src/vsg/app/CompileManager.cpp | 16 ++++++++++++++-- src/vsg/app/CompileTraversal.cpp | 4 ++-- src/vsg/app/RecordAndSubmitTask.cpp | 2 +- src/vsg/app/Viewer.cpp | 9 +++++++-- src/vsg/state/ViewDependentState.cpp | 2 +- src/vsg/vk/Context.cpp | 2 +- src/vsg/vk/ResourceRequirements.cpp | 2 +- 9 files changed, 37 insertions(+), 12 deletions(-) diff --git a/include/vsg/app/CompileManager.h b/include/vsg/app/CompileManager.h index ee61ac9dbc..fb9a6d6827 100644 --- a/include/vsg/app/CompileManager.h +++ b/include/vsg/app/CompileManager.h @@ -20,6 +20,7 @@ namespace vsg // forward declare class RecordAndSubmitTask; + class Viewer; /// CompileResult struct encapsulates the results of compile traversal. /// Used to help guide further operations done with the compiled subgraph. @@ -36,7 +37,7 @@ namespace vsg void reset(); void add(const CompileResult& cr); - bool requiresViewerUpdate() const; + bool requiresViewerUpdate(const Viewer* viewer = nullptr) const; }; /// ResourceScavenger provides a mechanism for releasing and reusing unused resources when allocation of required GPU memory fails. diff --git a/include/vsg/vk/Slots.h b/include/vsg/vk/Slots.h index 410cfaedb9..9f9e5a8f09 100644 --- a/include/vsg/vk/Slots.h +++ b/include/vsg/vk/Slots.h @@ -29,11 +29,18 @@ namespace vsg return view > state ? view : state; } - void merge(const Slots& rhs) + /// update this Slots object to hold the maximum state and view value of this and rhs Slots objects. + void update(const Slots& rhs) { if (rhs.state > state) state = rhs.state; if (rhs.view > view) view = rhs.view; } + + /// return true if this Slots object is less that rhs Slots object and needs to be updated by calling this Slots::merge(rhs). + bool requiresUpdate(const Slots& rhs) const + { + return rhs.state > state || rhs.view > view; + } }; } // namespace vsg diff --git a/src/vsg/app/CompileManager.cpp b/src/vsg/app/CompileManager.cpp index 5799abeec8..0a3c148539 100644 --- a/src/vsg/app/CompileManager.cpp +++ b/src/vsg/app/CompileManager.cpp @@ -41,7 +41,7 @@ void CompileResult::add(const CompileResult& cr) result = cr.result; } - maxSlots.merge(cr.maxSlots); + maxSlots.update(cr.maxSlots); if (!containsPagedLOD) containsPagedLOD = cr.containsPagedLOD; @@ -57,7 +57,7 @@ void CompileResult::add(const CompileResult& cr) dynamicData.add(cr.dynamicData); } -bool CompileResult::requiresViewerUpdate() const +bool CompileResult::requiresViewerUpdate(const Viewer* viewer) const { if (result == VK_INCOMPLETE) return false; @@ -67,6 +67,18 @@ bool CompileResult::requiresViewerUpdate() const { if (!binDetails.indices.empty() || !binDetails.bins.empty()) return true; } + + if (viewer) + { + for (const auto& task : viewer->recordAndSubmitTasks) + { + for (const auto& commandGraph : task->commandGraphs) + { + if (commandGraph->maxSlots.requiresUpdate(maxSlots)) return true; + } + } + } + return false; } diff --git a/src/vsg/app/CompileTraversal.cpp b/src/vsg/app/CompileTraversal.cpp index 9eecb70761..4d30a65375 100644 --- a/src/vsg/app/CompileTraversal.cpp +++ b/src/vsg/app/CompileTraversal.cpp @@ -325,7 +325,7 @@ void CompileTraversal::apply(CommandGraph& commandGraph) for (const auto& context : contexts) { - commandGraph.maxSlots.merge(context->resourceRequirements.maxSlots); + commandGraph.maxSlots.update(context->resourceRequirements.maxSlots); } commandGraph.traverse(*this); @@ -339,7 +339,7 @@ void CompileTraversal::apply(SecondaryCommandGraph& secondaryCommandGraph) for (auto& context : contexts) { - secondaryCommandGraph.maxSlots.merge(context->resourceRequirements.maxSlots); + secondaryCommandGraph.maxSlots.update(context->resourceRequirements.maxSlots); // save previous states to be restored after traversal auto previousRenderPass = context->renderPass; diff --git a/src/vsg/app/RecordAndSubmitTask.cpp b/src/vsg/app/RecordAndSubmitTask.cpp index 8aa2a30531..d61d9685e6 100644 --- a/src/vsg/app/RecordAndSubmitTask.cpp +++ b/src/vsg/app/RecordAndSubmitTask.cpp @@ -306,7 +306,7 @@ void vsg::updateTasks(RecordAndSubmitTasks& tasks, ref_ptr compi { for (const auto& commandGraph : task->commandGraphs) { - commandGraph->maxSlots.merge(compileResult.maxSlots); + commandGraph->maxSlots.update(compileResult.maxSlots); } } diff --git a/src/vsg/app/Viewer.cpp b/src/vsg/app/Viewer.cpp index b091835b9d..f1da140180 100644 --- a/src/vsg/app/Viewer.cpp +++ b/src/vsg/app/Viewer.cpp @@ -794,17 +794,22 @@ void Viewer::update() { CPU_INSTRUMENTATION_L1_NC(instrumentation, "Viewer update", COLOR_UPDATE); + CompileResult cr; + // merge any updates from the DatabasePager for (const auto& task : recordAndSubmitTasks) { if (task->databasePager) { - CompileResult cr; task->databasePager->updateSceneGraph(_frameStamp, cr); - if (cr.requiresViewerUpdate()) updateViewer(*this, cr); } } + if (cr.requiresViewerUpdate(this)) + { + updateViewer(*this, cr); + } + // run update operations updateOperations->run(); diff --git a/src/vsg/state/ViewDependentState.cpp b/src/vsg/state/ViewDependentState.cpp index 984664b316..801cd28ff4 100644 --- a/src/vsg/state/ViewDependentState.cpp +++ b/src/vsg/state/ViewDependentState.cpp @@ -421,7 +421,7 @@ void ViewDependentState::update(ResourceRequirements& requirements) { if (preRenderCommandGraph) { - preRenderCommandGraph->maxSlots.merge(requirements.maxSlots); + preRenderCommandGraph->maxSlots.update(requirements.maxSlots); } } diff --git a/src/vsg/vk/Context.cpp b/src/vsg/vk/Context.cpp index dc4d9b8b68..38e4c5ef5b 100644 --- a/src/vsg/vk/Context.cpp +++ b/src/vsg/vk/Context.cpp @@ -201,7 +201,7 @@ VkResult Context::reserve(ResourceRequirements& requirements) if (deviceMemoryBufferPools->compileTraversalUseReserve) result = deviceMemoryBufferPools->reserve(requirements); - resourceRequirements.maxSlots.merge(requirements.maxSlots); + resourceRequirements.maxSlots.update(requirements.maxSlots); descriptorPools->reserve(requirements); diff --git a/src/vsg/vk/ResourceRequirements.cpp b/src/vsg/vk/ResourceRequirements.cpp index 6a5bb6ae76..9b02299488 100644 --- a/src/vsg/vk/ResourceRequirements.cpp +++ b/src/vsg/vk/ResourceRequirements.cpp @@ -66,7 +66,7 @@ DescriptorPoolSizes ResourceRequirements::computeDescriptorPoolSizes() const void ResourceRequirements::apply(const ResourceHints& resourceHints) { - maxSlots.merge(resourceHints.maxSlots); + maxSlots.update(resourceHints.maxSlots); if (!resourceHints.descriptorPoolSizes.empty() || resourceHints.numDescriptorSets > 0) { From a88393620e7893fd8a8d559718c8565ac451421f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 May 2026 08:55:47 +0100 Subject: [PATCH 46/80] Ran clang-format --- include/vsg/core/IntrusiveAllocator.h | 2 +- src/vsg/app/CompileManager.cpp | 2 +- src/vsg/app/CompileTraversal.cpp | 2 +- src/vsg/core/IntrusiveAllocator.cpp | 2 +- src/vsg/utils/GraphicsPipelineConfigurator.cpp | 3 ++- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/vsg/core/IntrusiveAllocator.h b/include/vsg/core/IntrusiveAllocator.h index 131a33a320..1603bd9fda 100644 --- a/include/vsg/core/IntrusiveAllocator.h +++ b/include/vsg/core/IntrusiveAllocator.h @@ -142,7 +142,7 @@ namespace vsg struct VSG_DECLSPEC SlotTester { SlotTester(Element* in_mem, size_t in_head) : - mem(in_mem), head(in_head){}; + mem(in_mem), head(in_head) {}; const Element* mem = nullptr; size_t head = 0; diff --git a/src/vsg/app/CompileManager.cpp b/src/vsg/app/CompileManager.cpp index 0a3c148539..9c6b0d23a6 100644 --- a/src/vsg/app/CompileManager.cpp +++ b/src/vsg/app/CompileManager.cpp @@ -246,7 +246,7 @@ CompileResult CompileManager::compile(ref_ptr object, ContextSelectionFu // if no CompileTraversals are available abort compile if (!compileTraversal) { - info("Unable to aquire compileTraversal."); + debug("Unable to aquire compileTraversal."); return result; } diff --git a/src/vsg/app/CompileTraversal.cpp b/src/vsg/app/CompileTraversal.cpp index 4d30a65375..9694c36f2a 100644 --- a/src/vsg/app/CompileTraversal.cpp +++ b/src/vsg/app/CompileTraversal.cpp @@ -189,7 +189,7 @@ void CompileTraversal::add(const Viewer& viewer, const ResourceRequirements& res ref_ptr transferTask; AddViews(CompileTraversal* in_ct, const ResourceRequirements& in_rr) : - ct(in_ct), resourceRequirements(in_rr){}; + ct(in_ct), resourceRequirements(in_rr) {}; const char* className() const noexcept override { return "vsg::CompileTraversal::AddViews"; } diff --git a/src/vsg/core/IntrusiveAllocator.cpp b/src/vsg/core/IntrusiveAllocator.cpp index f28124898a..aac14a35bd 100644 --- a/src/vsg/core/IntrusiveAllocator.cpp +++ b/src/vsg/core/IntrusiveAllocator.cpp @@ -431,7 +431,7 @@ bool IntrusiveAllocator::MemoryBlock::deallocate(void* ptr, std::size_t /*size*/ memory[P].next += memory[C].next; if (N != 0) memory[N].previous = memory[P].next; - // freeList linked list entries will not need updating. + // freeList linked list entries will not need updating. #if DEBUG_ALLOCATOR if (!validate()) diff --git a/src/vsg/utils/GraphicsPipelineConfigurator.cpp b/src/vsg/utils/GraphicsPipelineConfigurator.cpp index 7723c0b136..0a5a698272 100644 --- a/src/vsg/utils/GraphicsPipelineConfigurator.cpp +++ b/src/vsg/utils/GraphicsPipelineConfigurator.cpp @@ -607,7 +607,8 @@ int GraphicsPipelineConfigurator::compare(const Object& rhs_object) const return *lhs.itr; else if (*rhs.itr < *lhs.itr) return *rhs.itr; - else { return *rhs.itr; } + else + return *rhs.itr; } else return *lhs.itr; From 28cbb3b7dee3f27787530b4e2bbf13d49c2f23c1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 May 2026 09:25:22 +0100 Subject: [PATCH 47/80] Fixed cppcheck build and updated version for 1.1.15 dev release --- CMakeLists.txt | 2 +- cmake/cppcheck-suppression-list.txt | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c15ccf73c..213141bc84 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.10) project(vsg - VERSION 1.1.14 + VERSION 1.1.15 DESCRIPTION "VulkanSceneGraph library" LANGUAGES CXX ) diff --git a/cmake/cppcheck-suppression-list.txt b/cmake/cppcheck-suppression-list.txt index 6cb1322f6e..e08ee2adca 100644 --- a/cmake/cppcheck-suppression-list.txt +++ b/cmake/cppcheck-suppression-list.txt @@ -9,7 +9,6 @@ invalidPointerCast:*/include/vsg/core/Data.h invalidPointerCast:*/include/vsg/core/Array.h invalidPointerCast:*/include/vsg/core/Array2D.h invalidPointerCast:*/include/vsg/core/Array3D.h -invalidPointerCast:*/include/vsg/core/Array3D.h invalidPointerCast:*/src/vsg/commands/CopyAndReleaseImage.cpp // suppress inappropriate stl algorithm suggestions From 1abe428f36199c6e7c7ac8f865a6b7621041822f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 May 2026 10:39:22 +0100 Subject: [PATCH 48/80] Changes inspired by cppckeck --- include/vsg/maths/box.h | 2 +- include/vsg/maths/mat2.h | 6 +++--- include/vsg/maths/mat3.h | 6 +++--- include/vsg/maths/mat4.h | 6 +++--- include/vsg/maths/plane.h | 2 +- include/vsg/maths/quat.h | 2 +- include/vsg/maths/sphere.h | 2 +- include/vsg/maths/vec2.h | 2 +- include/vsg/maths/vec3.h | 2 +- include/vsg/maths/vec4.h | 2 +- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/include/vsg/maths/box.h b/include/vsg/maths/box.h index 80ab988d01..25fecafa54 100644 --- a/include/vsg/maths/box.h +++ b/include/vsg/maths/box.h @@ -42,7 +42,7 @@ namespace vsg constexpr t_box& operator=(const t_box&) = default; - constexpr std::size_t size() const { return 6; } + constexpr static std::size_t size() { return 6; } value_type& operator[](std::size_t i) { return data()[i]; } value_type operator[](std::size_t i) const { return data()[i]; } diff --git a/include/vsg/maths/mat2.h b/include/vsg/maths/mat2.h index dd011a9781..d9f8693e68 100644 --- a/include/vsg/maths/mat2.h +++ b/include/vsg/maths/mat2.h @@ -59,9 +59,9 @@ namespace vsg value[1] = rhs[1]; } - constexpr std::size_t size() const { return 4; } - constexpr std::size_t columns() const { return 2; } - constexpr std::size_t rows() const { return 2; } + constexpr static std::size_t size() { return 4; } + constexpr static std::size_t columns() { return 2; } + constexpr static std::size_t rows() { return 2; } column_type& operator[](std::size_t c) { return value[c]; } const column_type& operator[](std::size_t c) const { return value[c]; } diff --git a/include/vsg/maths/mat3.h b/include/vsg/maths/mat3.h index 95a9020513..510e1e2e4f 100644 --- a/include/vsg/maths/mat3.h +++ b/include/vsg/maths/mat3.h @@ -66,9 +66,9 @@ namespace vsg value[2] = rhs[2]; } - constexpr std::size_t size() const { return 9; } - constexpr std::size_t columns() const { return 3; } - constexpr std::size_t rows() const { return 3; } + constexpr static std::size_t size() { return 9; } + constexpr static std::size_t columns() { return 3; } + constexpr static std::size_t rows() { return 3; } column_type& operator[](std::size_t c) { return value[c]; } const column_type& operator[](std::size_t c) const { return value[c]; } diff --git a/include/vsg/maths/mat4.h b/include/vsg/maths/mat4.h index 8174d094b2..83257afc54 100644 --- a/include/vsg/maths/mat4.h +++ b/include/vsg/maths/mat4.h @@ -75,9 +75,9 @@ namespace vsg value[3] = rhs[3]; } - constexpr std::size_t size() const { return 16; } - constexpr std::size_t columns() const { return 4; } - constexpr std::size_t rows() const { return 4; } + constexpr static std::size_t size() { return 16; } + constexpr static std::size_t columns() { return 4; } + constexpr static std::size_t rows() { return 4; } column_type& operator[](std::size_t c) { return value[c]; } const column_type& operator[](std::size_t c) const { return value[c]; } diff --git a/include/vsg/maths/plane.h b/include/vsg/maths/plane.h index 1c28ea47b7..5ce9d44675 100644 --- a/include/vsg/maths/plane.h +++ b/include/vsg/maths/plane.h @@ -77,7 +77,7 @@ namespace vsg constexpr explicit t_plane(const t_vec4& v) : value{v[0], v[1], v[2], v[3]} {} - constexpr std::size_t size() const { return 4; } + constexpr static std::size_t size() { return 4; } value_type& operator[](std::size_t i) { return value[i]; } value_type operator[](std::size_t i) const { return value[i]; } diff --git a/include/vsg/maths/quat.h b/include/vsg/maths/quat.h index a4a3aad531..ca42f8e47f 100644 --- a/include/vsg/maths/quat.h +++ b/include/vsg/maths/quat.h @@ -65,7 +65,7 @@ namespace vsg constexpr t_quat& operator=(const t_quat&) = default; - constexpr std::size_t size() const { return 4; } + constexpr static std::size_t size() { return 4; } value_type& operator[](std::size_t i) { return value[i]; } value_type operator[](std::size_t i) const { return value[i]; } diff --git a/include/vsg/maths/sphere.h b/include/vsg/maths/sphere.h index 7de13c45c3..9ec6604ee9 100644 --- a/include/vsg/maths/sphere.h +++ b/include/vsg/maths/sphere.h @@ -74,7 +74,7 @@ namespace vsg constexpr t_sphere(R sx, R sy, R sz, R sd) : value{sx, sy, sz, sd} {} - constexpr std::size_t size() const { return 4; } + constexpr static std::size_t size() { return 4; } value_type& operator[](std::size_t i) { return value[i]; } value_type operator[](std::size_t i) const { return value[i]; } diff --git a/include/vsg/maths/vec2.h b/include/vsg/maths/vec2.h index b39e5ff9fc..c83379a82a 100644 --- a/include/vsg/maths/vec2.h +++ b/include/vsg/maths/vec2.h @@ -68,7 +68,7 @@ namespace vsg constexpr explicit t_vec2(const t_vec2& v) : value{static_cast(v.x), static_cast(v.y)} {} - constexpr std::size_t size() const { return 2; } + constexpr static std::size_t size() { return 2; } value_type& operator[](std::size_t i) { return value[i]; } value_type operator[](std::size_t i) const { return value[i]; } diff --git a/include/vsg/maths/vec3.h b/include/vsg/maths/vec3.h index 0aa38a3c37..8599501879 100644 --- a/include/vsg/maths/vec3.h +++ b/include/vsg/maths/vec3.h @@ -67,7 +67,7 @@ namespace vsg constexpr explicit t_vec3(const t_vec3& v) : value{static_cast(v.x), static_cast(v.y), static_cast(v.z)} {} - constexpr std::size_t size() const { return 3; } + constexpr static std::size_t size() { return 3; } value_type& operator[](std::size_t i) { return value[i]; } value_type operator[](std::size_t i) const { return value[i]; } diff --git a/include/vsg/maths/vec4.h b/include/vsg/maths/vec4.h index f502896225..9ff9202f3c 100644 --- a/include/vsg/maths/vec4.h +++ b/include/vsg/maths/vec4.h @@ -78,7 +78,7 @@ namespace vsg constexpr t_vec4(const t_vec3& v, value_type in_w) : value{static_cast(v.x), static_cast(v.y), static_cast(v.z), in_w} {} - constexpr std::size_t size() const { return 4; } + constexpr static std::size_t size() { return 4; } value_type& operator[](std::size_t i) { return value[i]; } value_type operator[](std::size_t i) const { return value[i]; } From db6c9972715d3c3e528854f6ee95340707fbc7bd Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 May 2026 10:44:35 +0100 Subject: [PATCH 49/80] cppcheck suggested changes --- include/vsg/core/Allocator.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/vsg/core/Allocator.h b/include/vsg/core/Allocator.h index 4bf93d9941..a93e2e16ce 100644 --- a/include/vsg/core/Allocator.h +++ b/include/vsg/core/Allocator.h @@ -105,12 +105,12 @@ namespace vsg using other = allocator_affinity_adapter; }; - value_type* allocate(std::size_t n) + static value_type* allocate(std::size_t n) { return static_cast(vsg::allocate(n * sizeof(value_type), A)); } - void deallocate(value_type* ptr, std::size_t n) + static void deallocate(value_type* ptr, std::size_t n) { vsg::deallocate(ptr, n * sizeof(value_type)); } From d319760f161c6b08529c634570459e2b2ee8813d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 May 2026 11:14:58 +0100 Subject: [PATCH 50/80] cppcheck fixes --- include/vsg/app/RecordTraversal.h | 2 +- include/vsg/core/Array.h | 2 +- include/vsg/core/Array2D.h | 2 +- include/vsg/core/Array3D.h | 2 +- include/vsg/core/Data.h | 2 +- include/vsg/core/Value.h | 2 +- include/vsg/io/ObjectFactory.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/vsg/app/RecordTraversal.h b/include/vsg/app/RecordTraversal.h index 42527d4f55..ccd15bd1eb 100644 --- a/include/vsg/app/RecordTraversal.h +++ b/include/vsg/app/RecordTraversal.h @@ -185,7 +185,7 @@ namespace vsg ref_ptr viewDependentState; protected: - virtual ~RecordTraversal(); + ~RecordTraversal() override; }; } // namespace vsg diff --git a/include/vsg/core/Array.h b/include/vsg/core/Array.h index 6fcc98fbe2..7ced4d5f73 100644 --- a/include/vsg/core/Array.h +++ b/include/vsg/core/Array.h @@ -344,7 +344,7 @@ namespace vsg const_iterator end() const { return const_iterator{data(_size), properties.stride}; } protected: - virtual ~Array() + ~Array() override { _delete(); } diff --git a/include/vsg/core/Array2D.h b/include/vsg/core/Array2D.h index 203a800828..6e557b89ad 100644 --- a/include/vsg/core/Array2D.h +++ b/include/vsg/core/Array2D.h @@ -340,7 +340,7 @@ namespace vsg const_iterator end() const { return const_iterator{data(_width * _height), properties.stride}; } protected: - virtual ~Array2D() + ~Array2D() override { _delete(); } diff --git a/include/vsg/core/Array3D.h b/include/vsg/core/Array3D.h index 1e1c26befa..fdd764f37c 100644 --- a/include/vsg/core/Array3D.h +++ b/include/vsg/core/Array3D.h @@ -356,7 +356,7 @@ namespace vsg const_iterator end() const { return const_iterator{data(_width * _height * _depth), properties.stride}; } protected: - virtual ~Array3D() + ~Array3D() override { _delete(); } diff --git a/include/vsg/core/Data.h b/include/vsg/core/Data.h index 8777ba3e24..8da44f29b9 100644 --- a/include/vsg/core/Data.h +++ b/include/vsg/core/Data.h @@ -227,7 +227,7 @@ namespace vsg const MipmapLayout* getMipmapLayout() const; protected: - virtual ~Data() {} + ~Data() override {} void _copy(const Data& rhs); void _clear(); diff --git a/include/vsg/core/Value.h b/include/vsg/core/Value.h index 0b60876db7..a5c02bd704 100644 --- a/include/vsg/core/Value.h +++ b/include/vsg/core/Value.h @@ -162,7 +162,7 @@ namespace vsg void set(const value_type& value) { _value = value; } protected: - virtual ~Value() {} + ~Value() override {} private: value_type _value; diff --git a/include/vsg/io/ObjectFactory.h b/include/vsg/io/ObjectFactory.h index ab8ec2dbf8..4ba6ce907a 100644 --- a/include/vsg/io/ObjectFactory.h +++ b/include/vsg/io/ObjectFactory.h @@ -46,7 +46,7 @@ namespace vsg static ref_ptr& instance(); protected: - virtual ~ObjectFactory(); + ~ObjectFactory() override; CreateMap _createMap; }; From c46e0fb249fe99e1ed87942976e6eb54265d4444 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 May 2026 12:17:33 +0100 Subject: [PATCH 51/80] cppcheck fixes --- include/vsg/io/Logger.h | 2 +- include/vsg/nodes/Bin.h | 2 +- include/vsg/nodes/CullGroup.h | 2 +- include/vsg/nodes/CullNode.h | 2 +- include/vsg/nodes/DepthSorted.h | 2 +- include/vsg/nodes/Geometry.h | 2 +- include/vsg/nodes/Group.h | 2 +- include/vsg/nodes/InstanceDraw.h | 2 +- include/vsg/nodes/InstanceDrawIndexed.h | 2 +- include/vsg/nodes/InstanceNode.h | 2 +- include/vsg/nodes/InstrumentationNode.h | 2 +- include/vsg/nodes/LOD.h | 2 +- include/vsg/nodes/Layer.h | 2 +- include/vsg/nodes/Node.h | 2 +- include/vsg/nodes/PagedLOD.h | 2 +- include/vsg/nodes/QuadGroup.h | 2 +- include/vsg/nodes/RegionOfInterest.h | 2 +- include/vsg/nodes/StateGroup.h | 2 +- include/vsg/nodes/Switch.h | 2 +- include/vsg/nodes/VertexDraw.h | 2 +- include/vsg/nodes/VertexIndexDraw.h | 2 +- include/vsg/utils/Instrumentation.h | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/include/vsg/io/Logger.h b/include/vsg/io/Logger.h index 8791f901ff..84f5231fed 100644 --- a/include/vsg/io/Logger.h +++ b/include/vsg/io/Logger.h @@ -232,7 +232,7 @@ namespace vsg void log_stream(Level msg_level, PrintToStreamFunction print); protected: - virtual ~Logger(); + ~Logger() override; std::mutex _mutex; std::ostringstream _stream; diff --git a/include/vsg/nodes/Bin.h b/include/vsg/nodes/Bin.h index 8840237f40..4b8eca0f38 100644 --- a/include/vsg/nodes/Bin.h +++ b/include/vsg/nodes/Bin.h @@ -51,7 +51,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~Bin(); + ~Bin() override; std::vector _matrices; std::vector _stateCommands; diff --git a/include/vsg/nodes/CullGroup.h b/include/vsg/nodes/CullGroup.h index 3e8cb28fc4..ed344cd36e 100644 --- a/include/vsg/nodes/CullGroup.h +++ b/include/vsg/nodes/CullGroup.h @@ -36,7 +36,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~CullGroup(); + ~CullGroup() override; }; VSG_type_name(vsg::CullGroup); diff --git a/include/vsg/nodes/CullNode.h b/include/vsg/nodes/CullNode.h index 71ce22e3de..ff851f288b 100644 --- a/include/vsg/nodes/CullNode.h +++ b/include/vsg/nodes/CullNode.h @@ -43,7 +43,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~CullNode(); + ~CullNode() override; }; VSG_type_name(vsg::CullNode); diff --git a/include/vsg/nodes/DepthSorted.h b/include/vsg/nodes/DepthSorted.h index ca9a9f7bdd..8e50c93134 100644 --- a/include/vsg/nodes/DepthSorted.h +++ b/include/vsg/nodes/DepthSorted.h @@ -46,7 +46,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~DepthSorted(); + ~DepthSorted() override; }; VSG_type_name(vsg::DepthSorted); diff --git a/include/vsg/nodes/Geometry.h b/include/vsg/nodes/Geometry.h index 0483e16286..ce40c599b3 100644 --- a/include/vsg/nodes/Geometry.h +++ b/include/vsg/nodes/Geometry.h @@ -54,7 +54,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~Geometry(); + ~Geometry() override; vk_buffer _vulkanData; VkIndexType indexType = VK_INDEX_TYPE_UINT16; diff --git a/include/vsg/nodes/Group.h b/include/vsg/nodes/Group.h index 1cd46fef7d..ff1e625974 100644 --- a/include/vsg/nodes/Group.h +++ b/include/vsg/nodes/Group.h @@ -59,7 +59,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~Group(); + ~Group() override; }; VSG_type_name(vsg::Group); diff --git a/include/vsg/nodes/InstanceDraw.h b/include/vsg/nodes/InstanceDraw.h index 4c56c7ee98..c50fbb06a2 100644 --- a/include/vsg/nodes/InstanceDraw.h +++ b/include/vsg/nodes/InstanceDraw.h @@ -48,7 +48,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~InstanceDraw(); + ~InstanceDraw() override; }; VSG_type_name(vsg::InstanceDraw) diff --git a/include/vsg/nodes/InstanceDrawIndexed.h b/include/vsg/nodes/InstanceDrawIndexed.h index 88401443cc..07ee3aab1d 100644 --- a/include/vsg/nodes/InstanceDrawIndexed.h +++ b/include/vsg/nodes/InstanceDrawIndexed.h @@ -51,7 +51,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~InstanceDrawIndexed(); + ~InstanceDrawIndexed() override; VkIndexType indexType = VK_INDEX_TYPE_UINT16; }; diff --git a/include/vsg/nodes/InstanceNode.h b/include/vsg/nodes/InstanceNode.h index caadc408ce..5399defda8 100644 --- a/include/vsg/nodes/InstanceNode.h +++ b/include/vsg/nodes/InstanceNode.h @@ -76,7 +76,7 @@ namespace vsg void compile(Context& context) override; protected: - virtual ~InstanceNode(); + ~InstanceNode() override; }; VSG_type_name(vsg::InstanceNode); diff --git a/include/vsg/nodes/InstrumentationNode.h b/include/vsg/nodes/InstrumentationNode.h index 9ea80e156e..f336637f7c 100644 --- a/include/vsg/nodes/InstrumentationNode.h +++ b/include/vsg/nodes/InstrumentationNode.h @@ -50,7 +50,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~InstrumentationNode(); + ~InstrumentationNode() override; uint32_t _level = 1; uint_color _color; diff --git a/include/vsg/nodes/LOD.h b/include/vsg/nodes/LOD.h index da3d25f7f6..c7274da216 100644 --- a/include/vsg/nodes/LOD.h +++ b/include/vsg/nodes/LOD.h @@ -66,7 +66,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~LOD(); + ~LOD() override; }; VSG_type_name(vsg::LOD); diff --git a/include/vsg/nodes/Layer.h b/include/vsg/nodes/Layer.h index 6f19c579ee..2de68f7885 100644 --- a/include/vsg/nodes/Layer.h +++ b/include/vsg/nodes/Layer.h @@ -52,7 +52,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~Layer(); + ~Layer() override; }; VSG_type_name(vsg::Layer); diff --git a/include/vsg/nodes/Node.h b/include/vsg/nodes/Node.h index b6d25b0936..ea1470f91c 100644 --- a/include/vsg/nodes/Node.h +++ b/include/vsg/nodes/Node.h @@ -33,7 +33,7 @@ namespace vsg static void operator delete(void* ptr); protected: - virtual ~Node(); + ~Node() override; }; VSG_type_name(vsg::Node); diff --git a/include/vsg/nodes/PagedLOD.h b/include/vsg/nodes/PagedLOD.h index cdd09e30d5..5c929fe5eb 100644 --- a/include/vsg/nodes/PagedLOD.h +++ b/include/vsg/nodes/PagedLOD.h @@ -78,7 +78,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~PagedLOD(); + ~PagedLOD() override; public: ref_ptr options; diff --git a/include/vsg/nodes/QuadGroup.h b/include/vsg/nodes/QuadGroup.h index 902008fd22..f4836c00d1 100644 --- a/include/vsg/nodes/QuadGroup.h +++ b/include/vsg/nodes/QuadGroup.h @@ -52,7 +52,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~QuadGroup(); + ~QuadGroup() override; }; VSG_type_name(vsg::QuadGroup); diff --git a/include/vsg/nodes/RegionOfInterest.h b/include/vsg/nodes/RegionOfInterest.h index 93d767d03c..2b54605d1c 100644 --- a/include/vsg/nodes/RegionOfInterest.h +++ b/include/vsg/nodes/RegionOfInterest.h @@ -50,7 +50,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~RegionOfInterest(); + ~RegionOfInterest() override; }; VSG_type_name(vsg::RegionOfInterest); diff --git a/include/vsg/nodes/StateGroup.h b/include/vsg/nodes/StateGroup.h index fb3dfd71aa..2f1f9044b4 100644 --- a/include/vsg/nodes/StateGroup.h +++ b/include/vsg/nodes/StateGroup.h @@ -81,7 +81,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~StateGroup(); + ~StateGroup() override; }; VSG_type_name(vsg::StateGroup); diff --git a/include/vsg/nodes/Switch.h b/include/vsg/nodes/Switch.h index 39264e7481..009f4c0743 100644 --- a/include/vsg/nodes/Switch.h +++ b/include/vsg/nodes/Switch.h @@ -69,7 +69,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~Switch(); + ~Switch() override; }; VSG_type_name(vsg::Switch); diff --git a/include/vsg/nodes/VertexDraw.h b/include/vsg/nodes/VertexDraw.h index 0a26df4a6d..6db79b5412 100644 --- a/include/vsg/nodes/VertexDraw.h +++ b/include/vsg/nodes/VertexDraw.h @@ -50,7 +50,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~VertexDraw(); + ~VertexDraw() override; vk_buffer _vulkanData; }; diff --git a/include/vsg/nodes/VertexIndexDraw.h b/include/vsg/nodes/VertexIndexDraw.h index f5b0ec9f70..b9e06be9ec 100644 --- a/include/vsg/nodes/VertexIndexDraw.h +++ b/include/vsg/nodes/VertexIndexDraw.h @@ -53,7 +53,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~VertexIndexDraw(); + ~VertexIndexDraw() override; vk_buffer _vulkanData; VkIndexType indexType = VK_INDEX_TYPE_UINT16; diff --git a/include/vsg/utils/Instrumentation.h b/include/vsg/utils/Instrumentation.h index 2c10ca52c2..36d1e013c9 100644 --- a/include/vsg/utils/Instrumentation.h +++ b/include/vsg/utils/Instrumentation.h @@ -71,7 +71,7 @@ namespace vsg virtual void finish() const {} protected: - virtual ~Instrumentation(); + ~Instrumentation() override; }; VSG_type_name(vsg::Instrumentation); From fde64f46b691ed2d8d927bd028669627ca68b9d3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 May 2026 12:37:32 +0100 Subject: [PATCH 52/80] cppcheck fixes --- include/vsg/core/Array.h | 12 ++++++------ include/vsg/core/Array2D.h | 12 ++++++------ include/vsg/core/Array3D.h | 12 ++++++------ include/vsg/core/Data.h | 8 ++++---- include/vsg/core/Object.h | 2 +- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/include/vsg/core/Array.h b/include/vsg/core/Array.h index 7ced4d5f73..ec70eb4280 100644 --- a/include/vsg/core/Array.h +++ b/include/vsg/core/Array.h @@ -57,12 +57,12 @@ namespace vsg dirty(); } - explicit Array(uint32_t numElements, Properties in_properties = {}) : + explicit Array(uint32_t numElements, const Properties& in_properties = {}) : Data(in_properties, sizeof(value_type)), _data(_allocate(numElements)), _size(numElements) { dirty(); } - Array(uint32_t numElements, value_type* data, Properties in_properties = {}, MipmapLayout* mipmapLayout = nullptr) : + Array(uint32_t numElements, value_type* data, const Properties& in_properties = {}, MipmapLayout* mipmapLayout = nullptr) : Data(in_properties, sizeof(value_type)), _data(data), _size(numElements) @@ -71,7 +71,7 @@ namespace vsg dirty(); } - Array(uint32_t numElements, const value_type& value, Properties in_properties = {}) : + Array(uint32_t numElements, const value_type& value, const Properties& in_properties = {}) : Data(in_properties, sizeof(value_type)), _data(_allocate(numElements)), _size(numElements) @@ -80,7 +80,7 @@ namespace vsg dirty(); } - Array(ref_ptr data, uint32_t offset, uint32_t stride, uint32_t numElements, Properties in_properties = {}, MipmapLayout* mipmapLayout = nullptr) : + Array(ref_ptr data, uint32_t offset, uint32_t stride, uint32_t numElements, const Properties& in_properties = {}, MipmapLayout* mipmapLayout = nullptr) : Data(), _data(nullptr), _size(0) @@ -247,7 +247,7 @@ namespace vsg return *this; } - void assign(uint32_t numElements, value_type* data, Properties in_properties = {}, MipmapLayout* mipmapLayout = nullptr) + void assign(uint32_t numElements, value_type* data, const Properties& in_properties = {}, MipmapLayout* mipmapLayout = nullptr) { _delete(); @@ -262,7 +262,7 @@ namespace vsg dirty(); } - void assign(ref_ptr storage, uint32_t offset, uint32_t stride, uint32_t numElements, Properties in_properties = {}, MipmapLayout* mipmapLayout = nullptr) + void assign(ref_ptr storage, uint32_t offset, uint32_t stride, uint32_t numElements, const Properties& in_properties = {}, MipmapLayout* mipmapLayout = nullptr) { _delete(); diff --git a/include/vsg/core/Array2D.h b/include/vsg/core/Array2D.h index 6e557b89ad..1460faff43 100644 --- a/include/vsg/core/Array2D.h +++ b/include/vsg/core/Array2D.h @@ -57,7 +57,7 @@ namespace vsg } } - Array2D(uint32_t width, uint32_t height, Properties in_properties = {}) : + Array2D(uint32_t width, uint32_t height, const Properties& in_properties = {}) : Data(in_properties, sizeof(value_type)), _data(nullptr), _width(width), @@ -67,7 +67,7 @@ namespace vsg dirty(); } - Array2D(uint32_t width, uint32_t height, value_type* data, Properties in_properties = {}, MipmapLayout* mipmapLayout = nullptr) : + Array2D(uint32_t width, uint32_t height, value_type* data, const Properties& in_properties = {}, MipmapLayout* mipmapLayout = nullptr) : Data(in_properties, sizeof(value_type)), _data(data), _width(width), @@ -77,7 +77,7 @@ namespace vsg dirty(); } - Array2D(uint32_t width, uint32_t height, const value_type& value, Properties in_properties = {}) : + Array2D(uint32_t width, uint32_t height, const value_type& value, const Properties& in_properties = {}) : Data(in_properties, sizeof(value_type)), _data(nullptr), _width(width), @@ -91,7 +91,7 @@ namespace vsg } } - Array2D(ref_ptr data, uint32_t offset, uint32_t stride, uint32_t width, uint32_t height, Properties in_properties = {}, MipmapLayout* mipmapLayout = nullptr) : + Array2D(ref_ptr data, uint32_t offset, uint32_t stride, uint32_t width, uint32_t height, const Properties& in_properties = {}, MipmapLayout* mipmapLayout = nullptr) : Data(), _data(nullptr), _width(0), @@ -231,7 +231,7 @@ namespace vsg return *this; } - void assign(uint32_t width, uint32_t height, value_type* data, Properties in_properties = {}, MipmapLayout* mipmapLayout = nullptr) + void assign(uint32_t width, uint32_t height, value_type* data, const Properties& in_properties = {}, MipmapLayout* mipmapLayout = nullptr) { _delete(); @@ -247,7 +247,7 @@ namespace vsg dirty(); } - void assign(ref_ptr storage, uint32_t offset, uint32_t stride, uint32_t width, uint32_t height, Properties in_properties = {}, MipmapLayout* mipmapLayout = nullptr) + void assign(ref_ptr storage, uint32_t offset, uint32_t stride, uint32_t width, uint32_t height, const Properties& in_properties = {}, MipmapLayout* mipmapLayout = nullptr) { _delete(); diff --git a/include/vsg/core/Array3D.h b/include/vsg/core/Array3D.h index fdd764f37c..aa3c911c1b 100644 --- a/include/vsg/core/Array3D.h +++ b/include/vsg/core/Array3D.h @@ -59,7 +59,7 @@ namespace vsg } } - Array3D(uint32_t width, uint32_t height, uint32_t depth, Properties in_properties = {}) : + Array3D(uint32_t width, uint32_t height, uint32_t depth, const Properties& in_properties = {}) : Data(in_properties, sizeof(value_type)), _data(nullptr), _width(width), @@ -70,7 +70,7 @@ namespace vsg dirty(); } - Array3D(uint32_t width, uint32_t height, uint32_t depth, value_type* data, Properties in_properties = {}, MipmapLayout* mipmapLayout = nullptr) : + Array3D(uint32_t width, uint32_t height, uint32_t depth, value_type* data, const Properties& in_properties = {}, MipmapLayout* mipmapLayout = nullptr) : Data(in_properties, sizeof(value_type)), _data(data), _width(width), @@ -81,7 +81,7 @@ namespace vsg dirty(); } - Array3D(uint32_t width, uint32_t height, uint32_t depth, const value_type& value, Properties in_properties = {}) : + Array3D(uint32_t width, uint32_t height, uint32_t depth, const value_type& value, const Properties& in_properties = {}) : Data(in_properties, sizeof(value_type)), _data(nullptr), _width(width), @@ -96,7 +96,7 @@ namespace vsg } } - Array3D(ref_ptr data, uint32_t offset, uint32_t stride, uint32_t width, uint32_t height, uint32_t depth, Properties in_properties = {}, MipmapLayout* mipmapLayout = nullptr) : + Array3D(ref_ptr data, uint32_t offset, uint32_t stride, uint32_t width, uint32_t height, uint32_t depth, const Properties& in_properties = {}, MipmapLayout* mipmapLayout = nullptr) : Data(), _data(nullptr), _width(0), @@ -242,7 +242,7 @@ namespace vsg return *this; } - void assign(uint32_t width, uint32_t height, uint32_t depth, value_type* data, Properties in_properties = {}, MipmapLayout* mipmapLayout = nullptr) + void assign(uint32_t width, uint32_t height, uint32_t depth, value_type* data, const Properties& in_properties = {}, MipmapLayout* mipmapLayout = nullptr) { _delete(); @@ -259,7 +259,7 @@ namespace vsg dirty(); } - void assign(ref_ptr storage, uint32_t offset, uint32_t stride, uint32_t width, uint32_t height, uint32_t depth, Properties in_properties = {}, MipmapLayout* mipmapLayout = nullptr) + void assign(ref_ptr storage, uint32_t offset, uint32_t stride, uint32_t width, uint32_t height, uint32_t depth, const Properties& in_properties = {}, MipmapLayout* mipmapLayout = nullptr) { _delete(); diff --git a/include/vsg/core/Data.h b/include/vsg/core/Data.h index 8da44f29b9..338afbc481 100644 --- a/include/vsg/core/Data.h +++ b/include/vsg/core/Data.h @@ -144,10 +144,10 @@ namespace vsg Data(const Data& data, const CopyOp& copyop = {}) : Object(data, copyop), properties(data.properties) {} - explicit Data(Properties layout) : + explicit Data(const Properties& layout) : properties(layout) {} - Data(Properties layout, uint32_t min_stride) : + Data(const Properties& layout, uint32_t min_stride) : properties(layout) { if (properties.stride < min_stride) properties.stride = min_stride; @@ -240,7 +240,7 @@ namespace vsg using Layout = Properties; /// deprecated: use data->properties = properties instead. - void setLayout(Layout layout) + void setLayout(const Layout& layout) { VkFormat previous_format = properties.format; // temporary hack to keep applications that call setFormat(..) before setLayout(..) working uint32_t previous_stride = properties.stride; @@ -251,7 +251,7 @@ namespace vsg /// deprecated: use data->properties Layout& getLayout() { return properties; } /// deprecated: use data->properties - Layout getLayout() const { return properties; } + const Layout& getLayout() const { return properties; } #endif }; VSG_type_name(vsg::Data); diff --git a/include/vsg/core/Object.h b/include/vsg/core/Object.h index 242ff12380..02f678a4e7 100644 --- a/include/vsg/core/Object.h +++ b/include/vsg/core/Object.h @@ -260,7 +260,7 @@ namespace vsg C dest; dest.reserve(src.size()); - for (auto& ptr : src) + for (const auto& ptr : src) { dest.push_back(operator()(ptr)); } From afa8ae3324877ce74713ba6904a4dee8ccfa2df6 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 May 2026 12:58:47 +0100 Subject: [PATCH 53/80] cppcheck fixes --- include/vsg/animation/AnimationGroup.h | 2 +- include/vsg/animation/Joint.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/vsg/animation/AnimationGroup.h b/include/vsg/animation/AnimationGroup.h index 32db782862..6d4ce7d56f 100644 --- a/include/vsg/animation/AnimationGroup.h +++ b/include/vsg/animation/AnimationGroup.h @@ -50,7 +50,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~AnimationGroup(); + ~AnimationGroup() override; }; VSG_type_name(vsg::AnimationGroup); diff --git a/include/vsg/animation/Joint.h b/include/vsg/animation/Joint.h index 2350e248ea..608f4fec9c 100644 --- a/include/vsg/animation/Joint.h +++ b/include/vsg/animation/Joint.h @@ -54,7 +54,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~Joint(); + ~Joint() override; }; VSG_type_name(vsg::Joint); From abc52dc018c811ebb7061a24c5186e7f306a9c3e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 May 2026 13:19:06 +0100 Subject: [PATCH 54/80] cppcheck fixes --- include/vsg/vk/AllocationCallbacks.h | 2 +- include/vsg/vk/CommandBuffer.h | 4 ++-- include/vsg/vk/CommandPool.h | 2 +- include/vsg/vk/Context.h | 2 +- include/vsg/vk/DescriptorPool.h | 2 +- include/vsg/vk/DescriptorPools.h | 2 +- include/vsg/vk/Device.h | 2 +- include/vsg/vk/DeviceMemory.h | 4 ++-- include/vsg/vk/Fence.h | 2 +- include/vsg/vk/Framebuffer.h | 2 +- include/vsg/vk/Instance.h | 2 +- include/vsg/vk/PhysicalDevice.h | 3 +-- include/vsg/vk/Queue.h | 2 +- include/vsg/vk/RenderPass.h | 2 +- include/vsg/vk/Semaphore.h | 2 +- include/vsg/vk/Surface.h | 2 +- include/vsg/vk/Swapchain.h | 2 +- 17 files changed, 19 insertions(+), 20 deletions(-) diff --git a/include/vsg/vk/AllocationCallbacks.h b/include/vsg/vk/AllocationCallbacks.h index 7bc308400e..0730cba5c7 100644 --- a/include/vsg/vk/AllocationCallbacks.h +++ b/include/vsg/vk/AllocationCallbacks.h @@ -27,7 +27,7 @@ namespace vsg VkAllocationCallbacks{} {} protected: - virtual ~AllocationCallbacks() {} + ~AllocationCallbacks() override {} }; /* diff --git a/include/vsg/vk/CommandBuffer.h b/include/vsg/vk/CommandBuffer.h index a9f5cb929b..8c5ca3aa42 100644 --- a/include/vsg/vk/CommandBuffer.h +++ b/include/vsg/vk/CommandBuffer.h @@ -66,7 +66,7 @@ namespace vsg friend CommandPool; CommandBuffer(CommandPool* commandPool, VkCommandBuffer commandBuffer, VkCommandBufferLevel level); - virtual ~CommandBuffer(); + ~CommandBuffer() override; VkCommandBuffer _commandBuffer; VkCommandBufferLevel _level; @@ -94,7 +94,7 @@ namespace vsg CommandBuffers buffers() const; protected: - virtual ~RecordedCommandBuffers(); + ~RecordedCommandBuffers(); mutable std::mutex _mutex; std::map> _orderedCommandBuffers; CommandBuffers _commandBuffers; diff --git a/include/vsg/vk/CommandPool.h b/include/vsg/vk/CommandPool.h index c287499827..b6cd69f789 100644 --- a/include/vsg/vk/CommandPool.h +++ b/include/vsg/vk/CommandPool.h @@ -41,7 +41,7 @@ namespace vsg const Device* getDevice() const { return _device; } protected: - virtual ~CommandPool(); + ~CommandPool() override; friend CommandBuffer; diff --git a/include/vsg/vk/Context.h b/include/vsg/vk/Context.h index daa5bb1ede..02d0e51446 100644 --- a/include/vsg/vk/Context.h +++ b/include/vsg/vk/Context.h @@ -70,7 +70,7 @@ namespace vsg Context(const Context& context); - virtual ~Context(); + ~Context() override; const uint32_t deviceID = 0; ref_ptr device; diff --git a/include/vsg/vk/DescriptorPool.h b/include/vsg/vk/DescriptorPool.h index 8bbaca55ee..e4324a06ba 100644 --- a/include/vsg/vk/DescriptorPool.h +++ b/include/vsg/vk/DescriptorPool.h @@ -54,7 +54,7 @@ namespace vsg mutable std::mutex mutex; protected: - virtual ~DescriptorPool(); + ~DescriptorPool() override; VkDescriptorPool _descriptorPool; ref_ptr _device; diff --git a/include/vsg/vk/DescriptorPools.h b/include/vsg/vk/DescriptorPools.h index 1ded89cae6..443f3f94c4 100644 --- a/include/vsg/vk/DescriptorPools.h +++ b/include/vsg/vk/DescriptorPools.h @@ -56,7 +56,7 @@ namespace vsg bool allocated(uint32_t& numSets, DescriptorPoolSizes& descriptorPoolSizes) const; protected: - virtual ~DescriptorPools(); + ~DescriptorPools() override; /// get the maxSets and descriptorPoolSizes to use void getDescriptorPoolSizesToUse(uint32_t& maxSets, DescriptorPoolSizes& descriptorPoolSizes); diff --git a/include/vsg/vk/Device.h b/include/vsg/vk/Device.h index 0c48c01e53..92b97bfcef 100644 --- a/include/vsg/vk/Device.h +++ b/include/vsg/vk/Device.h @@ -95,7 +95,7 @@ namespace vsg observer_ptr transferTask; protected: - virtual ~Device(); + ~Device() override; VkDevice _device; diff --git a/include/vsg/vk/DeviceMemory.h b/include/vsg/vk/DeviceMemory.h index a2db80a092..f349ac7bf6 100644 --- a/include/vsg/vk/DeviceMemory.h +++ b/include/vsg/vk/DeviceMemory.h @@ -59,7 +59,7 @@ namespace vsg void report(LogOutput& out) const; protected: - virtual ~DeviceMemory(); + ~DeviceMemory() override; VkDeviceMemory _deviceMemory; VkMemoryRequirements _memoryRequirements; @@ -105,7 +105,7 @@ namespace vsg return data; } - virtual ~MappedData() + ~MappedData() override { T::dataRelease(); // make sure that the Array doesn't delete this memory _deviceMemory->unmap(); diff --git a/include/vsg/vk/Fence.h b/include/vsg/vk/Fence.h index ebf90e80b5..b5ce2900dd 100644 --- a/include/vsg/vk/Fence.h +++ b/include/vsg/vk/Fence.h @@ -44,7 +44,7 @@ namespace vsg const Device* getDevice() const { return _device; } protected: - virtual ~Fence(); + ~Fence() override; VkFence _vkFence; Semaphores _dependentSemaphores; diff --git a/include/vsg/vk/Framebuffer.h b/include/vsg/vk/Framebuffer.h index f9daca0283..e09db28f48 100644 --- a/include/vsg/vk/Framebuffer.h +++ b/include/vsg/vk/Framebuffer.h @@ -43,7 +43,7 @@ namespace vsg VkExtent2D extent2D() const { return VkExtent2D{_width, _height}; } protected: - virtual ~Framebuffer(); + ~Framebuffer() override; VkFramebuffer _framebuffer; ref_ptr _device; diff --git a/include/vsg/vk/Instance.h b/include/vsg/vk/Instance.h index c863a99923..965df75c8d 100644 --- a/include/vsg/vk/Instance.h +++ b/include/vsg/vk/Instance.h @@ -90,7 +90,7 @@ namespace vsg } protected: - virtual ~Instance(); + ~Instance() override; VkInstance _instance; ref_ptr _allocator; diff --git a/include/vsg/vk/PhysicalDevice.h b/include/vsg/vk/PhysicalDevice.h index b5f27f805e..6ecf2566e6 100644 --- a/include/vsg/vk/PhysicalDevice.h +++ b/include/vsg/vk/PhysicalDevice.h @@ -81,8 +81,7 @@ namespace vsg protected: // use Instance::getDevice(..) to create PhysicalDevice PhysicalDevice(Instance* instance, VkPhysicalDevice device); - - virtual ~PhysicalDevice(); + ~PhysicalDevice() override; friend class Instance; diff --git a/include/vsg/vk/Queue.h b/include/vsg/vk/Queue.h index 8f53140ae2..be4d04cf8b 100644 --- a/include/vsg/vk/Queue.h +++ b/include/vsg/vk/Queue.h @@ -44,7 +44,7 @@ namespace vsg protected: Queue(VkQueue queue, VkQueueFlags queueFlags, uint32_t queueFamilyIndex, uint32_t queueIndex); - virtual ~Queue(); + ~Queue() override; Queue() = delete; Queue(const Queue&) = delete; diff --git a/include/vsg/vk/RenderPass.h b/include/vsg/vk/RenderPass.h index dd9af0cbb0..02d988048b 100644 --- a/include/vsg/vk/RenderPass.h +++ b/include/vsg/vk/RenderPass.h @@ -107,7 +107,7 @@ namespace vsg const VkSampleCountFlagBits maxSamples; protected: - virtual ~RenderPass(); + ~RenderPass() override; /// Vulkan renderPass handle, created in RenderPass constructor. VkRenderPass _renderPass; diff --git a/include/vsg/vk/Semaphore.h b/include/vsg/vk/Semaphore.h index 14ce5438cc..6be180dcd0 100644 --- a/include/vsg/vk/Semaphore.h +++ b/include/vsg/vk/Semaphore.h @@ -36,7 +36,7 @@ namespace vsg const Device* getDevice() const { return _device; } protected: - virtual ~Semaphore(); + ~Semaphore() override; VkSemaphore _semaphore; VkPipelineStageFlags _pipelineStageFlags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; diff --git a/include/vsg/vk/Surface.h b/include/vsg/vk/Surface.h index 61455b58b9..7e2000e035 100644 --- a/include/vsg/vk/Surface.h +++ b/include/vsg/vk/Surface.h @@ -39,7 +39,7 @@ namespace vsg } protected: - virtual ~Surface(); + ~Surface() override; VkSurfaceKHR _surface; ref_ptr _instance; diff --git a/include/vsg/vk/Swapchain.h b/include/vsg/vk/Swapchain.h index 97d3f4c821..6f5114f879 100644 --- a/include/vsg/vk/Swapchain.h +++ b/include/vsg/vk/Swapchain.h @@ -60,7 +60,7 @@ namespace vsg VkResult acquireNextImage(uint64_t timeout, ref_ptr semaphore, ref_ptr fence, uint32_t& imageIndex); protected: - virtual ~Swapchain(); + ~Swapchain() override; vsg::ref_ptr _device; vsg::ref_ptr _surface; From 9d91ad41cb4b793e3c9d3b0db034dc758cd1a6e8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 May 2026 13:47:24 +0100 Subject: [PATCH 55/80] cppcheck fixes --- include/vsg/core/ScratchMemory.h | 2 +- include/vsg/vk/DeviceFeatures.h | 2 +- include/vsg/vk/vk_buffer.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/vsg/core/ScratchMemory.h b/include/vsg/core/ScratchMemory.h index 17a06bd5bb..2eb0865ff6 100644 --- a/include/vsg/core/ScratchMemory.h +++ b/include/vsg/core/ScratchMemory.h @@ -42,7 +42,7 @@ namespace vsg delete[] buffer; } - uint8_t* align(uint8_t* p) const + static uint8_t* align(uint8_t* p) { auto alignment = sizeof(p); uint8_t* new_p = reinterpret_cast(((reinterpret_cast(p) + alignment - 1) / alignment) * alignment); diff --git a/include/vsg/vk/DeviceFeatures.h b/include/vsg/vk/DeviceFeatures.h index 54b61b9637..c9aa381fc0 100644 --- a/include/vsg/vk/DeviceFeatures.h +++ b/include/vsg/vk/DeviceFeatures.h @@ -64,7 +64,7 @@ namespace vsg void* data() const; protected: - ~DeviceFeatures(); + ~DeviceFeatures() override; struct FeatureHeader { diff --git a/include/vsg/vk/vk_buffer.h b/include/vsg/vk/vk_buffer.h index eb4833022c..4a2b9418b0 100644 --- a/include/vsg/vk/vk_buffer.h +++ b/include/vsg/vk/vk_buffer.h @@ -32,7 +32,7 @@ namespace vsg T& operator[](uint32_t) { return value; } const T& operator[](uint32_t) const { return value; } - uint32_t size() const { return 1; } + constexpr static uint32_t size() { return 1; } void clear() { value = {}; } From 5ef2fe24d24d124c944ec96c40c483e4478d12ff Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 May 2026 13:57:16 +0100 Subject: [PATCH 56/80] cppcheck fixes --- include/vsg/state/ArrayState.h | 2 +- include/vsg/state/BindDescriptorSet.h | 2 +- include/vsg/state/Buffer.h | 2 +- include/vsg/state/BufferInfo.h | 2 +- include/vsg/state/BufferView.h | 2 +- include/vsg/state/ColorBlendState.h | 2 +- include/vsg/state/ComputePipeline.h | 4 ++-- include/vsg/state/DepthStencilState.h | 2 +- include/vsg/state/DescriptorBuffer.h | 2 +- include/vsg/state/DescriptorSet.h | 2 +- include/vsg/state/DescriptorSetLayout.h | 2 +- include/vsg/state/DynamicState.h | 2 +- include/vsg/state/GraphicsPipeline.h | 4 ++-- include/vsg/state/Image.h | 2 +- include/vsg/state/ImageInfo.h | 2 +- include/vsg/state/ImageView.h | 2 +- include/vsg/state/InputAssemblyState.h | 2 +- include/vsg/state/MultisampleState.h | 2 +- include/vsg/state/PipelineLayout.h | 2 +- include/vsg/state/PushConstants.h | 2 +- include/vsg/state/RasterizationState.h | 2 +- include/vsg/state/ResourceHints.h | 2 +- include/vsg/state/Sampler.h | 2 +- include/vsg/state/ShaderModule.h | 2 +- include/vsg/state/ShaderStage.h | 2 +- include/vsg/state/StateCommand.h | 2 +- include/vsg/state/TessellationState.h | 2 +- include/vsg/state/VertexInputState.h | 2 +- include/vsg/state/ViewDependentState.h | 2 +- include/vsg/state/ViewportState.h | 2 +- 30 files changed, 32 insertions(+), 32 deletions(-) diff --git a/include/vsg/state/ArrayState.h b/include/vsg/state/ArrayState.h index 4c4897495c..d2ff248632 100644 --- a/include/vsg/state/ArrayState.h +++ b/include/vsg/state/ArrayState.h @@ -92,7 +92,7 @@ namespace vsg virtual ref_ptr vertexArray(uint32_t instanceIndex); protected: - virtual ~ArrayState() {} + ~ArrayState() override {} }; VSG_type_name(vsg::ArrayState); diff --git a/include/vsg/state/BindDescriptorSet.h b/include/vsg/state/BindDescriptorSet.h index b38ea92b4c..a27b7b4408 100644 --- a/include/vsg/state/BindDescriptorSet.h +++ b/include/vsg/state/BindDescriptorSet.h @@ -74,7 +74,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~BindDescriptorSets() {} + ~BindDescriptorSets() override {} struct VulkanData { diff --git a/include/vsg/state/Buffer.h b/include/vsg/state/Buffer.h index f4c6530154..65a800ac21 100644 --- a/include/vsg/state/Buffer.h +++ b/include/vsg/state/Buffer.h @@ -60,7 +60,7 @@ namespace vsg virtual bool compile(Context& context); protected: - virtual ~Buffer(); + ~Buffer() override; struct VulkanData { diff --git a/include/vsg/state/BufferInfo.h b/include/vsg/state/BufferInfo.h index dc132c2e1f..f592ef608a 100644 --- a/include/vsg/state/BufferInfo.h +++ b/include/vsg/state/BufferInfo.h @@ -74,7 +74,7 @@ namespace vsg vk_buffer copiedModifiedCounts; protected: - virtual ~BufferInfo(); + ~BufferInfo() override; }; VSG_type_name(vsg::BufferInfo); diff --git a/include/vsg/state/BufferView.h b/include/vsg/state/BufferView.h index 862efeb653..3e11ff7ba4 100644 --- a/include/vsg/state/BufferView.h +++ b/include/vsg/state/BufferView.h @@ -42,7 +42,7 @@ namespace vsg virtual void compile(Context& context); protected: - virtual ~BufferView(); + ~BufferView() override; struct VulkanData { diff --git a/include/vsg/state/ColorBlendState.h b/include/vsg/state/ColorBlendState.h index 8f4d6558e0..0c9ac2a0a2 100644 --- a/include/vsg/state/ColorBlendState.h +++ b/include/vsg/state/ColorBlendState.h @@ -44,7 +44,7 @@ namespace vsg void apply(Context& context, VkGraphicsPipelineCreateInfo& pipelineInfo) const override; protected: - virtual ~ColorBlendState(); + ~ColorBlendState() override; }; VSG_type_name(vsg::ColorBlendState); diff --git a/include/vsg/state/ComputePipeline.h b/include/vsg/state/ComputePipeline.h index a832fa0f63..923f027a99 100644 --- a/include/vsg/state/ComputePipeline.h +++ b/include/vsg/state/ComputePipeline.h @@ -45,7 +45,7 @@ namespace vsg VkPipeline vk(uint32_t deviceID) const { return _implementation[deviceID]->_pipeline; } protected: - virtual ~ComputePipeline(); + ~ComputePipeline() override; struct Implementation : public Inherit { @@ -80,7 +80,7 @@ namespace vsg void compile(Context& context) override; public: - virtual ~BindComputePipeline(); + ~BindComputePipeline() override; }; VSG_type_name(vsg::BindComputePipeline); diff --git a/include/vsg/state/DepthStencilState.h b/include/vsg/state/DepthStencilState.h index aa0f25299b..5085f19462 100644 --- a/include/vsg/state/DepthStencilState.h +++ b/include/vsg/state/DepthStencilState.h @@ -43,7 +43,7 @@ namespace vsg void apply(Context& context, VkGraphicsPipelineCreateInfo& pipelineInfo) const override; protected: - virtual ~DepthStencilState(); + ~DepthStencilState() override; }; VSG_type_name(vsg::DepthStencilState); diff --git a/include/vsg/state/DescriptorBuffer.h b/include/vsg/state/DescriptorBuffer.h index 013c824498..d259aae85d 100644 --- a/include/vsg/state/DescriptorBuffer.h +++ b/include/vsg/state/DescriptorBuffer.h @@ -46,7 +46,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~DescriptorBuffer(); + ~DescriptorBuffer() override; }; VSG_type_name(vsg::DescriptorBuffer) diff --git a/include/vsg/state/DescriptorSet.h b/include/vsg/state/DescriptorSet.h index b6e6ee424b..32b1238a73 100644 --- a/include/vsg/state/DescriptorSet.h +++ b/include/vsg/state/DescriptorSet.h @@ -85,7 +85,7 @@ namespace vsg }; protected: - virtual ~DescriptorSet(); + ~DescriptorSet() override; vk_buffer> _implementation; }; diff --git a/include/vsg/state/DescriptorSetLayout.h b/include/vsg/state/DescriptorSetLayout.h index 9479114083..98d6e57c04 100644 --- a/include/vsg/state/DescriptorSetLayout.h +++ b/include/vsg/state/DescriptorSetLayout.h @@ -64,7 +64,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~DescriptorSetLayout(); + ~DescriptorSetLayout() override; struct Implementation : public Inherit { diff --git a/include/vsg/state/DynamicState.h b/include/vsg/state/DynamicState.h index 420025129b..b316449f88 100644 --- a/include/vsg/state/DynamicState.h +++ b/include/vsg/state/DynamicState.h @@ -46,7 +46,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~DynamicState(); + ~DynamicState() override; }; VSG_type_name(vsg::DynamicState); diff --git a/include/vsg/state/GraphicsPipeline.h b/include/vsg/state/GraphicsPipeline.h index 81fd7f79be..6ace23c6c1 100644 --- a/include/vsg/state/GraphicsPipeline.h +++ b/include/vsg/state/GraphicsPipeline.h @@ -44,7 +44,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~GraphicsPipelineState() {} + ~GraphicsPipelineState() override {} }; VSG_type_name(vsg::GraphicsPipelineState); @@ -88,7 +88,7 @@ namespace vsg void release() { _implementation.clear(); } protected: - virtual ~GraphicsPipeline(); + ~GraphicsPipeline() override; struct Implementation : public Inherit { diff --git a/include/vsg/state/Image.h b/include/vsg/state/Image.h index 9a802e1a7d..55f4b7da69 100644 --- a/include/vsg/state/Image.h +++ b/include/vsg/state/Image.h @@ -72,7 +72,7 @@ namespace vsg virtual VkResult compile(MemoryBufferPools& memoryBufferPools); protected: - virtual ~Image(); + ~Image() override; struct VulkanData { diff --git a/include/vsg/state/ImageInfo.h b/include/vsg/state/ImageInfo.h index 7d26450186..e8c5d9ebd7 100644 --- a/include/vsg/state/ImageInfo.h +++ b/include/vsg/state/ImageInfo.h @@ -69,7 +69,7 @@ namespace vsg vk_buffer copiedModifiedCounts; protected: - virtual ~ImageInfo(); + ~ImageInfo() override; }; VSG_type_name(vsg::ImageInfo); diff --git a/include/vsg/state/ImageView.h b/include/vsg/state/ImageView.h index 9de4bcbc0c..828e239a3e 100644 --- a/include/vsg/state/ImageView.h +++ b/include/vsg/state/ImageView.h @@ -44,7 +44,7 @@ namespace vsg virtual void compile(Context& context); protected: - virtual ~ImageView(); + ~ImageView() override; struct VulkanData { diff --git a/include/vsg/state/InputAssemblyState.h b/include/vsg/state/InputAssemblyState.h index 428d50ed67..a82031066e 100644 --- a/include/vsg/state/InputAssemblyState.h +++ b/include/vsg/state/InputAssemblyState.h @@ -35,7 +35,7 @@ namespace vsg void apply(Context& context, VkGraphicsPipelineCreateInfo& pipelineInfo) const override; protected: - virtual ~InputAssemblyState(); + ~InputAssemblyState() override; }; VSG_type_name(vsg::InputAssemblyState); diff --git a/include/vsg/state/MultisampleState.h b/include/vsg/state/MultisampleState.h index 5da05e09fd..826e10c789 100644 --- a/include/vsg/state/MultisampleState.h +++ b/include/vsg/state/MultisampleState.h @@ -38,7 +38,7 @@ namespace vsg void apply(Context& context, VkGraphicsPipelineCreateInfo& pipelineInfo) const override; protected: - virtual ~MultisampleState(); + ~MultisampleState() override; }; VSG_type_name(vsg::MultisampleState); diff --git a/include/vsg/state/PipelineLayout.h b/include/vsg/state/PipelineLayout.h index 2d5554f993..747d46fbfe 100644 --- a/include/vsg/state/PipelineLayout.h +++ b/include/vsg/state/PipelineLayout.h @@ -54,7 +54,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~PipelineLayout(); + ~PipelineLayout() override; struct Implementation : public Inherit { diff --git a/include/vsg/state/PushConstants.h b/include/vsg/state/PushConstants.h index bab577ff2b..e12735aea7 100644 --- a/include/vsg/state/PushConstants.h +++ b/include/vsg/state/PushConstants.h @@ -37,7 +37,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~PushConstants(); + ~PushConstants() override; }; VSG_type_name(vsg::PushConstants); diff --git a/include/vsg/state/RasterizationState.h b/include/vsg/state/RasterizationState.h index 6487b3f019..33e1c0802a 100644 --- a/include/vsg/state/RasterizationState.h +++ b/include/vsg/state/RasterizationState.h @@ -45,7 +45,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~RasterizationState(); + ~RasterizationState() override; }; VSG_type_name(vsg::RasterizationState); diff --git a/include/vsg/state/ResourceHints.h b/include/vsg/state/ResourceHints.h index 91fc704372..dc23b1c4ae 100644 --- a/include/vsg/state/ResourceHints.h +++ b/include/vsg/state/ResourceHints.h @@ -92,7 +92,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~ResourceHints(); + ~ResourceHints() override; }; VSG_type_name(vsg::ResourceHints); diff --git a/include/vsg/state/Sampler.h b/include/vsg/state/Sampler.h index 239e8366ff..d85d288e21 100644 --- a/include/vsg/state/Sampler.h +++ b/include/vsg/state/Sampler.h @@ -59,7 +59,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~Sampler(); + ~Sampler() override; struct Implementation : public Inherit { diff --git a/include/vsg/state/ShaderModule.h b/include/vsg/state/ShaderModule.h index c55e2407ae..7ce0923cf3 100644 --- a/include/vsg/state/ShaderModule.h +++ b/include/vsg/state/ShaderModule.h @@ -105,7 +105,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~ShaderModule(); + ~ShaderModule() override; struct Implementation : public Inherit { diff --git a/include/vsg/state/ShaderStage.h b/include/vsg/state/ShaderStage.h index 404e34f146..1b6ec3fe25 100644 --- a/include/vsg/state/ShaderStage.h +++ b/include/vsg/state/ShaderStage.h @@ -58,7 +58,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~ShaderStage(); + ~ShaderStage() override; }; VSG_type_name(vsg::ShaderStage); diff --git a/include/vsg/state/StateCommand.h b/include/vsg/state/StateCommand.h index 01e393b489..7e3f65ff99 100644 --- a/include/vsg/state/StateCommand.h +++ b/include/vsg/state/StateCommand.h @@ -36,7 +36,7 @@ namespace vsg uint32_t slot = 0; protected: - virtual ~StateCommand() {} + ~StateCommand() override {} }; VSG_type_name(vsg::StateCommand); diff --git a/include/vsg/state/TessellationState.h b/include/vsg/state/TessellationState.h index 430a3dbfd2..27998b1298 100644 --- a/include/vsg/state/TessellationState.h +++ b/include/vsg/state/TessellationState.h @@ -36,7 +36,7 @@ namespace vsg void apply(Context& context, VkGraphicsPipelineCreateInfo& pipelineInfo) const override; protected: - virtual ~TessellationState(); + ~TessellationState() override; }; VSG_type_name(vsg::TessellationState); diff --git a/include/vsg/state/VertexInputState.h b/include/vsg/state/VertexInputState.h index ff74e2f253..50221af206 100644 --- a/include/vsg/state/VertexInputState.h +++ b/include/vsg/state/VertexInputState.h @@ -40,7 +40,7 @@ namespace vsg void apply(Context& context, VkGraphicsPipelineCreateInfo& pipelineInfo) const override; protected: - virtual ~VertexInputState(); + ~VertexInputState() override; }; VSG_type_name(vsg::VertexInputState); diff --git a/include/vsg/state/ViewDependentState.h b/include/vsg/state/ViewDependentState.h index a502fdcb4e..76b75922f1 100644 --- a/include/vsg/state/ViewDependentState.h +++ b/include/vsg/state/ViewDependentState.h @@ -88,7 +88,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~BindViewDescriptorSets() {} + ~BindViewDescriptorSets() override {} }; VSG_type_name(vsg::BindViewDescriptorSets); diff --git a/include/vsg/state/ViewportState.h b/include/vsg/state/ViewportState.h index 89ac086340..0cf3ddb3b8 100644 --- a/include/vsg/state/ViewportState.h +++ b/include/vsg/state/ViewportState.h @@ -55,7 +55,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~ViewportState(); + ~ViewportState() override; }; VSG_type_name(vsg::ViewportState); From 668084c50da5041c6af6958a7f9068a87f87ccd7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 May 2026 14:08:55 +0100 Subject: [PATCH 57/80] cppcheck fixes --- include/vsg/app/CommandGraph.h | 2 +- include/vsg/app/SecondaryCommandGraph.h | 2 +- include/vsg/app/UpdateOperations.h | 2 +- include/vsg/app/View.h | 2 +- include/vsg/app/Viewer.h | 2 +- include/vsg/app/Window.h | 2 +- include/vsg/app/WindowAdapter.h | 2 +- include/vsg/app/WindowTraits.h | 2 +- include/vsg/state/GraphicsPipeline.h | 2 +- include/vsg/threading/ActivityStatus.h | 2 +- include/vsg/threading/Barrier.h | 2 +- include/vsg/threading/DeleteQueue.h | 2 +- include/vsg/threading/FrameBlock.h | 2 +- include/vsg/threading/Latch.h | 2 +- include/vsg/threading/OperationThreads.h | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/vsg/app/CommandGraph.h b/include/vsg/app/CommandGraph.h index d7cccddc38..f16e400bc2 100644 --- a/include/vsg/app/CommandGraph.h +++ b/include/vsg/app/CommandGraph.h @@ -54,7 +54,7 @@ namespace vsg ref_ptr instrumentation; protected: - virtual ~CommandGraph(); + ~CommandGraph() override; CommandBuffers _commandBuffers; // assign one per index? Or just use round robin, each has a CommandPool }; diff --git a/include/vsg/app/SecondaryCommandGraph.h b/include/vsg/app/SecondaryCommandGraph.h index 7e03f35f1e..ace2168cfc 100644 --- a/include/vsg/app/SecondaryCommandGraph.h +++ b/include/vsg/app/SecondaryCommandGraph.h @@ -43,7 +43,7 @@ namespace vsg void record(ref_ptr recordedCommandBuffers, ref_ptr frameStamp = {}, ref_ptr databasePager = {}) override; protected: - virtual ~SecondaryCommandGraph(); + ~SecondaryCommandGraph() override; friend ExecuteCommands; diff --git a/include/vsg/app/UpdateOperations.h b/include/vsg/app/UpdateOperations.h index e2530ee44f..0ad12f7fa2 100644 --- a/include/vsg/app/UpdateOperations.h +++ b/include/vsg/app/UpdateOperations.h @@ -55,7 +55,7 @@ namespace vsg virtual void run(); protected: - virtual ~UpdateOperations(); + ~UpdateOperations() override; mutable std::mutex _updateOperationMutex; std::list> _updateOperationsOneTime; diff --git a/include/vsg/app/View.h b/include/vsg/app/View.h index 94ea32d1be..b20ad41db3 100644 --- a/include/vsg/app/View.h +++ b/include/vsg/app/View.h @@ -90,7 +90,7 @@ namespace vsg GraphicsPipelineStates overridePipelineStates; protected: - virtual ~View(); + ~View() override; }; VSG_type_name(vsg::View); diff --git a/include/vsg/app/Viewer.h b/include/vsg/app/Viewer.h index a2603e0daa..8d0127a97f 100644 --- a/include/vsg/app/Viewer.h +++ b/include/vsg/app/Viewer.h @@ -149,7 +149,7 @@ namespace vsg void assignInstrumentation(ref_ptr in_instrumentation); protected: - virtual ~Viewer(); + ~Viewer() override; bool _close = false; diff --git a/include/vsg/app/Window.h b/include/vsg/app/Window.h index 8d84920c1a..736f5ec708 100644 --- a/include/vsg/app/Window.h +++ b/include/vsg/app/Window.h @@ -134,7 +134,7 @@ namespace vsg protected: Window(ref_ptr traits); - virtual ~Window(); + ~Window() override; virtual void _initSurface() = 0; void _initFormats(); diff --git a/include/vsg/app/WindowAdapter.h b/include/vsg/app/WindowAdapter.h index bb30230377..1c047f7927 100644 --- a/include/vsg/app/WindowAdapter.h +++ b/include/vsg/app/WindowAdapter.h @@ -41,7 +41,7 @@ namespace vsg bool windowValid = false; protected: - virtual ~WindowAdapter() {} + ~WindowAdapter() override {} void _initSurface() override {}; }; diff --git a/include/vsg/app/WindowTraits.h b/include/vsg/app/WindowTraits.h index 155a3a41be..4efbe8e8c0 100644 --- a/include/vsg/app/WindowTraits.h +++ b/include/vsg/app/WindowTraits.h @@ -99,7 +99,7 @@ namespace vsg std::any systemConnection; protected: - virtual ~WindowTraits() {} + ~WindowTraits() override {} }; VSG_type_name(vsg::WindowTraits); diff --git a/include/vsg/state/GraphicsPipeline.h b/include/vsg/state/GraphicsPipeline.h index 6ace23c6c1..10d72f5430 100644 --- a/include/vsg/state/GraphicsPipeline.h +++ b/include/vsg/state/GraphicsPipeline.h @@ -128,7 +128,7 @@ namespace vsg virtual void release(); public: - virtual ~BindGraphicsPipeline(); + ~BindGraphicsPipeline() override; }; VSG_type_name(vsg::BindGraphicsPipeline); diff --git a/include/vsg/threading/ActivityStatus.h b/include/vsg/threading/ActivityStatus.h index bbcc18214f..c063b33c86 100644 --- a/include/vsg/threading/ActivityStatus.h +++ b/include/vsg/threading/ActivityStatus.h @@ -33,7 +33,7 @@ namespace vsg bool cancel() const noexcept { return !_active; } protected: - virtual ~ActivityStatus() {} + ~ActivityStatus() override {} std::atomic_bool _active; }; diff --git a/include/vsg/threading/Barrier.h b/include/vsg/threading/Barrier.h index 10f655e798..bdc1c03500 100644 --- a/include/vsg/threading/Barrier.h +++ b/include/vsg/threading/Barrier.h @@ -57,7 +57,7 @@ namespace vsg } protected: - virtual ~Barrier() {} + ~Barrier() override {} void _release() { diff --git a/include/vsg/threading/DeleteQueue.h b/include/vsg/threading/DeleteQueue.h index e77027cc24..511ddb72c1 100644 --- a/include/vsg/threading/DeleteQueue.h +++ b/include/vsg/threading/DeleteQueue.h @@ -122,7 +122,7 @@ namespace vsg size_t clear(); protected: - virtual ~DeleteQueue(); + ~DeleteQueue() override; std::mutex _mutex; std::condition_variable _cv; diff --git a/include/vsg/threading/FrameBlock.h b/include/vsg/threading/FrameBlock.h index 6d7d8f10be..ad38da2620 100644 --- a/include/vsg/threading/FrameBlock.h +++ b/include/vsg/threading/FrameBlock.h @@ -67,7 +67,7 @@ namespace vsg } protected: - virtual ~FrameBlock() {} + ~FrameBlock() override {} std::mutex _mutex; std::condition_variable _cv; diff --git a/include/vsg/threading/Latch.h b/include/vsg/threading/Latch.h index 328d36d48c..0fdc6eb082 100644 --- a/include/vsg/threading/Latch.h +++ b/include/vsg/threading/Latch.h @@ -84,7 +84,7 @@ namespace vsg int count() const { return _count.load(); } protected: - virtual ~Latch() {} + ~Latch() override {} std::atomic_int _count; std::mutex _mutex; diff --git a/include/vsg/threading/OperationThreads.h b/include/vsg/threading/OperationThreads.h index 7a6ecd9528..265ef515a5 100644 --- a/include/vsg/threading/OperationThreads.h +++ b/include/vsg/threading/OperationThreads.h @@ -53,7 +53,7 @@ namespace vsg ref_ptr status; protected: - virtual ~OperationThreads(); + ~OperationThreads() override; }; VSG_type_name(vsg::OperationThreads) From 685507ee9b0fa1550df5c0ab78685e8f34d563d1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 May 2026 14:14:37 +0100 Subject: [PATCH 58/80] cppcheck fixes, bumped SO version as ABI changed a little --- CMakeLists.txt | 2 +- include/vsg/core/ScratchMemory.h | 2 +- include/vsg/vk/CommandBuffer.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 213141bc84..02a3e047f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(vsg DESCRIPTION "VulkanSceneGraph library" LANGUAGES CXX ) -set(VSG_SOVERSION 16) +set(VSG_SOVERSION 17) SET(VSG_RELEASE_CANDIDATE 0) set(Vulkan_MIN_VERSION 1.1.70.0) diff --git a/include/vsg/core/ScratchMemory.h b/include/vsg/core/ScratchMemory.h index 2eb0865ff6..25729da00d 100644 --- a/include/vsg/core/ScratchMemory.h +++ b/include/vsg/core/ScratchMemory.h @@ -37,7 +37,7 @@ namespace vsg ScratchMemory(const ScratchMemory&) = delete; ScratchMemory& operator=(const ScratchMemory&) = delete; - ~ScratchMemory() + ~ScratchMemory() override { delete[] buffer; } diff --git a/include/vsg/vk/CommandBuffer.h b/include/vsg/vk/CommandBuffer.h index 8c5ca3aa42..a4091d81d0 100644 --- a/include/vsg/vk/CommandBuffer.h +++ b/include/vsg/vk/CommandBuffer.h @@ -94,7 +94,7 @@ namespace vsg CommandBuffers buffers() const; protected: - ~RecordedCommandBuffers(); + ~RecordedCommandBuffers() override; mutable std::mutex _mutex; std::map> _orderedCommandBuffers; CommandBuffers _commandBuffers; From 08c0eba947c75f5d5220c021ae39dcc46bd709c1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 May 2026 14:20:25 +0100 Subject: [PATCH 59/80] Clean up --- include/vsg/core/Data.h | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/include/vsg/core/Data.h b/include/vsg/core/Data.h index 338afbc481..4fc60b05c2 100644 --- a/include/vsg/core/Data.h +++ b/include/vsg/core/Data.h @@ -233,26 +233,6 @@ namespace vsg void _clear(); ModifiedCount _modifiedCount; - -#if 1 - public: - /// deprecated: provided for backwards compatibility, use Properties instead. - using Layout = Properties; - - /// deprecated: use data->properties = properties instead. - void setLayout(const Layout& layout) - { - VkFormat previous_format = properties.format; // temporary hack to keep applications that call setFormat(..) before setLayout(..) working - uint32_t previous_stride = properties.stride; - properties = layout; - if (properties.format == 0 && previous_format != 0) properties.format = previous_format; // temporary hack to keep existing applications working - if (properties.stride == 0 && previous_stride != 0) properties.stride = previous_stride; // make sure the layout has a valid stride. - } - /// deprecated: use data->properties - Layout& getLayout() { return properties; } - /// deprecated: use data->properties - const Layout& getLayout() const { return properties; } -#endif }; VSG_type_name(vsg::Data); From 28ad64d0b6e2522bb8e58be162e58bbbf2fa28d7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 May 2026 15:35:35 +0100 Subject: [PATCH 60/80] cppcheck fixes --- include/vsg/commands/BindIndexBuffer.h | 2 +- include/vsg/commands/BindVertexBuffers.h | 2 +- include/vsg/commands/Commands.h | 2 +- include/vsg/commands/CopyAndReleaseBuffer.h | 2 +- include/vsg/commands/CopyAndReleaseImage.h | 2 +- include/vsg/commands/Event.h | 2 +- include/vsg/commands/ExecuteCommands.h | 2 +- include/vsg/commands/NextSubPass.h | 2 +- include/vsg/commands/PipelineBarrier.h | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/vsg/commands/BindIndexBuffer.h b/include/vsg/commands/BindIndexBuffer.h index 42e94a44cd..400b238f2c 100644 --- a/include/vsg/commands/BindIndexBuffer.h +++ b/include/vsg/commands/BindIndexBuffer.h @@ -47,7 +47,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~BindIndexBuffer(); + ~BindIndexBuffer() override; }; VSG_type_name(vsg::BindIndexBuffer); diff --git a/include/vsg/commands/BindVertexBuffers.h b/include/vsg/commands/BindVertexBuffers.h index 69908920fb..a9cfd38967 100644 --- a/include/vsg/commands/BindVertexBuffers.h +++ b/include/vsg/commands/BindVertexBuffers.h @@ -42,7 +42,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~BindVertexBuffers(); + ~BindVertexBuffers() override; vk_buffer _vulkanData; }; diff --git a/include/vsg/commands/Commands.h b/include/vsg/commands/Commands.h index 9ecf037f41..d87eed3a0d 100644 --- a/include/vsg/commands/Commands.h +++ b/include/vsg/commands/Commands.h @@ -57,7 +57,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~Commands(); + ~Commands() override; }; VSG_type_name(vsg::Commands); diff --git a/include/vsg/commands/CopyAndReleaseBuffer.h b/include/vsg/commands/CopyAndReleaseBuffer.h index ddd020575f..5354eb0b7b 100644 --- a/include/vsg/commands/CopyAndReleaseBuffer.h +++ b/include/vsg/commands/CopyAndReleaseBuffer.h @@ -36,7 +36,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~CopyAndReleaseBuffer(); + ~CopyAndReleaseBuffer() override; struct CopyData { diff --git a/include/vsg/commands/CopyAndReleaseImage.h b/include/vsg/commands/CopyAndReleaseImage.h index a400aa7d99..c1b9a6e5f9 100644 --- a/include/vsg/commands/CopyAndReleaseImage.h +++ b/include/vsg/commands/CopyAndReleaseImage.h @@ -58,7 +58,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~CopyAndReleaseImage(); + ~CopyAndReleaseImage() override; void _copyDirectly(ref_ptr data, ref_ptr dest, uint32_t numMipMapLevels); diff --git a/include/vsg/commands/Event.h b/include/vsg/commands/Event.h index 92fe0ce9d6..9ce757192c 100644 --- a/include/vsg/commands/Event.h +++ b/include/vsg/commands/Event.h @@ -36,7 +36,7 @@ namespace vsg VkResult status(); protected: - virtual ~Event(); + ~Event() override; VkEvent _event; ref_ptr _device; diff --git a/include/vsg/commands/ExecuteCommands.h b/include/vsg/commands/ExecuteCommands.h index 76ce6f34b7..81d1668e8f 100644 --- a/include/vsg/commands/ExecuteCommands.h +++ b/include/vsg/commands/ExecuteCommands.h @@ -37,7 +37,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~ExecuteCommands(); + ~ExecuteCommands() override; struct CommandGraphAndBuffer { diff --git a/include/vsg/commands/NextSubPass.h b/include/vsg/commands/NextSubPass.h index 5db9581a5b..5c032eadee 100644 --- a/include/vsg/commands/NextSubPass.h +++ b/include/vsg/commands/NextSubPass.h @@ -32,7 +32,7 @@ namespace vsg VkSubpassContents contents = VK_SUBPASS_CONTENTS_INLINE; protected: - virtual ~NextSubPass(); + ~NextSubPass() override; }; VSG_type_name(vsg::NextSubPass); diff --git a/include/vsg/commands/PipelineBarrier.h b/include/vsg/commands/PipelineBarrier.h index 4631d3be71..d5a563203a 100644 --- a/include/vsg/commands/PipelineBarrier.h +++ b/include/vsg/commands/PipelineBarrier.h @@ -152,7 +152,7 @@ namespace vsg ImageMemoryBarriers imageMemoryBarriers; protected: - virtual ~PipelineBarrier(); + ~PipelineBarrier() override; }; VSG_type_name(vsg::PipelineBarrier); From dbdbf5b0d47a1887ae5363b08320ec8e42e91888 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 May 2026 16:21:34 +0100 Subject: [PATCH 61/80] cppcheck fixes --- include/vsg/io/DatabasePager.h | 4 ++-- include/vsg/io/Options.h | 2 +- include/vsg/state/BindDescriptorSet.h | 2 +- include/vsg/state/ComputePipeline.h | 2 +- include/vsg/state/DescriptorSet.h | 2 +- include/vsg/state/DescriptorSetLayout.h | 2 +- include/vsg/state/GraphicsPipeline.h | 2 +- include/vsg/state/PipelineLayout.h | 2 +- include/vsg/state/Sampler.h | 2 +- include/vsg/state/ShaderModule.h | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/vsg/io/DatabasePager.h b/include/vsg/io/DatabasePager.h index 667a896753..a0fa424117 100644 --- a/include/vsg/io/DatabasePager.h +++ b/include/vsg/io/DatabasePager.h @@ -112,7 +112,7 @@ namespace vsg Nodes take_all(CompileResult& result); protected: - virtual ~DatabaseQueue(); + ~DatabaseQueue() override; std::mutex _mutex; std::condition_variable _cv; @@ -168,7 +168,7 @@ namespace vsg ref_ptr deleteQueue; protected: - virtual ~DatabasePager(); + ~DatabasePager() override; void requestDiscarded(PagedLOD* plod); diff --git a/include/vsg/io/Options.h b/include/vsg/io/Options.h index 90bd9e3974..981304123a 100644 --- a/include/vsg/io/Options.h +++ b/include/vsg/io/Options.h @@ -122,7 +122,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~Options(); + ~Options() override; }; VSG_type_name(vsg::Options); diff --git a/include/vsg/state/BindDescriptorSet.h b/include/vsg/state/BindDescriptorSet.h index a27b7b4408..9f975c1148 100644 --- a/include/vsg/state/BindDescriptorSet.h +++ b/include/vsg/state/BindDescriptorSet.h @@ -151,7 +151,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~BindDescriptorSet() {} + ~BindDescriptorSet() override {} struct VulkanData { diff --git a/include/vsg/state/ComputePipeline.h b/include/vsg/state/ComputePipeline.h index 923f027a99..049977cce2 100644 --- a/include/vsg/state/ComputePipeline.h +++ b/include/vsg/state/ComputePipeline.h @@ -50,7 +50,7 @@ namespace vsg struct Implementation : public Inherit { Implementation(Context& context, Device* device, const PipelineLayout* pipelineLayout, const ShaderStage* shaderStage); - virtual ~Implementation(); + ~Implementation() override; VkPipeline _pipeline; ref_ptr _device; diff --git a/include/vsg/state/DescriptorSet.h b/include/vsg/state/DescriptorSet.h index 32b1238a73..7ea4c69c2a 100644 --- a/include/vsg/state/DescriptorSet.h +++ b/include/vsg/state/DescriptorSet.h @@ -76,7 +76,7 @@ namespace vsg static void recycle(ref_ptr& dsi); protected: - virtual ~Implementation(); + ~Implementation() override; friend DescriptorPool; diff --git a/include/vsg/state/DescriptorSetLayout.h b/include/vsg/state/DescriptorSetLayout.h index 98d6e57c04..068c257f0f 100644 --- a/include/vsg/state/DescriptorSetLayout.h +++ b/include/vsg/state/DescriptorSetLayout.h @@ -70,7 +70,7 @@ namespace vsg { Implementation(Device* device, VkDescriptorSetLayoutCreateFlags createFlags, const DescriptorSetLayoutBindings& descriptorSetLayoutBindings, const DescriptorSetLayoutBindingFlags& descriptorSetLayoutBindingFlags); - virtual ~Implementation(); + ~Implementation() override; ref_ptr _device; VkDescriptorSetLayout _descriptorSetLayout; diff --git a/include/vsg/state/GraphicsPipeline.h b/include/vsg/state/GraphicsPipeline.h index 10d72f5430..0d276b4897 100644 --- a/include/vsg/state/GraphicsPipeline.h +++ b/include/vsg/state/GraphicsPipeline.h @@ -94,7 +94,7 @@ namespace vsg { Implementation(Context& context, Device* device, const RenderPass* renderPass, const PipelineLayout* pipelineLayout, const ShaderStages& shaderStages, const GraphicsPipelineStates& pipelineStates, uint32_t subpass); - virtual ~Implementation(); + ~Implementation() override; GraphicsPipelineStates _pipelineStates; VkPipeline _pipeline; diff --git a/include/vsg/state/PipelineLayout.h b/include/vsg/state/PipelineLayout.h index 747d46fbfe..d6567489d7 100644 --- a/include/vsg/state/PipelineLayout.h +++ b/include/vsg/state/PipelineLayout.h @@ -60,7 +60,7 @@ namespace vsg { Implementation(Device* device, const DescriptorSetLayouts& descriptorSetLayouts, const PushConstantRanges& pushConstantRanges, VkPipelineLayoutCreateFlags flags = 0); - virtual ~Implementation(); + ~Implementation() override; VkPipelineLayout _pipelineLayout; diff --git a/include/vsg/state/Sampler.h b/include/vsg/state/Sampler.h index d85d288e21..0706afb4ca 100644 --- a/include/vsg/state/Sampler.h +++ b/include/vsg/state/Sampler.h @@ -65,7 +65,7 @@ namespace vsg { Implementation(Device* device, const VkSamplerCreateInfo& createSamplerInfo); - virtual ~Implementation(); + ~Implementation() override; VkSampler _sampler; ref_ptr _device; diff --git a/include/vsg/state/ShaderModule.h b/include/vsg/state/ShaderModule.h index 7ce0923cf3..4cc75d7ee6 100644 --- a/include/vsg/state/ShaderModule.h +++ b/include/vsg/state/ShaderModule.h @@ -111,7 +111,7 @@ namespace vsg { Implementation(Device* device, ShaderModule* shader); - virtual ~Implementation(); + ~Implementation() override; VkShaderModule _shaderModule; ref_ptr _device; From 3cb19dfdbe15f1e83f7f6e7b35d66853805de83b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 9 May 2026 09:52:53 +0100 Subject: [PATCH 62/80] cppcheck fixes --- include/vsg/app/CompileManager.h | 2 +- include/vsg/app/CompileTraversal.h | 2 +- include/vsg/utils/GpuAnnotation.h | 2 +- include/vsg/utils/ShaderCompiler.h | 2 +- include/vsg/utils/ShaderSet.h | 2 +- include/vsg/utils/SharedObjects.h | 2 +- include/vsg/vk/DeviceMemory.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/vsg/app/CompileManager.h b/include/vsg/app/CompileManager.h index fb9a6d6827..fefdd3e25e 100644 --- a/include/vsg/app/CompileManager.h +++ b/include/vsg/app/CompileManager.h @@ -91,7 +91,7 @@ namespace vsg std::atomic_uint failedCompileCount{0}; protected: - ~CompileManager(); + ~CompileManager() override; using CompileTraversals = ThreadSafeQueue>; size_t numCompileTraversals = 0; diff --git a/include/vsg/app/CompileTraversal.h b/include/vsg/app/CompileTraversal.h index fa9fdf1809..04db232b90 100644 --- a/include/vsg/app/CompileTraversal.h +++ b/include/vsg/app/CompileTraversal.h @@ -103,7 +103,7 @@ namespace vsg void apply(View& view) override; protected: - ~CompileTraversal(); + ~CompileTraversal() override; void add(ref_ptr context, Framebuffer& framebuffer, ref_ptr transferTask, ref_ptr view, const ResourceRequirements& resourceRequirements); void addViewDependentState(ViewDependentState& viewDependentState, ref_ptr device, ref_ptr transferTask, const ResourceRequirements& resourceRequirements); diff --git a/include/vsg/utils/GpuAnnotation.h b/include/vsg/utils/GpuAnnotation.h index 8c4d08c486..6d85e3c7ba 100644 --- a/include/vsg/utils/GpuAnnotation.h +++ b/include/vsg/utils/GpuAnnotation.h @@ -40,7 +40,7 @@ namespace vsg void leave(const vsg::SourceLocation* sl, uint64_t& reference, CommandBuffer& commandBuffer, const Object* object) const override; protected: - virtual ~GpuAnnotation(); + ~GpuAnnotation() override; }; VSG_type_name(vsg::GpuAnnotation); diff --git a/include/vsg/utils/ShaderCompiler.h b/include/vsg/utils/ShaderCompiler.h index d418011c8f..62ac2ca362 100644 --- a/include/vsg/utils/ShaderCompiler.h +++ b/include/vsg/utils/ShaderCompiler.h @@ -16,7 +16,7 @@ namespace vsg { public: ShaderCompiler(); - virtual ~ShaderCompiler(); + ~ShaderCompiler() override; /// return true if shader compilation is supported by this build of VulkanSceneGraph /// you can also use the VSG_SUPPORTS_ShaderCompiler define provided by include/vsg/core/Version.h diff --git a/include/vsg/utils/ShaderSet.h b/include/vsg/utils/ShaderSet.h index e3bf15ac4d..fe4c74f0ed 100644 --- a/include/vsg/utils/ShaderSet.h +++ b/include/vsg/utils/ShaderSet.h @@ -196,7 +196,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~ShaderSet(); + ~ShaderSet() override; AttributeBinding _nullAttributeBinding; DescriptorBinding _nullDescriptorBinding; diff --git a/include/vsg/utils/SharedObjects.h b/include/vsg/utils/SharedObjects.h index dbf4a1c52b..23f3dd76d6 100644 --- a/include/vsg/utils/SharedObjects.h +++ b/include/vsg/utils/SharedObjects.h @@ -73,7 +73,7 @@ namespace vsg void report(vsg::LogOutput& output); protected: - virtual ~SharedObjects(); + ~SharedObjects() override; mutable std::recursive_mutex _mutex; std::map> _defaults; diff --git a/include/vsg/vk/DeviceMemory.h b/include/vsg/vk/DeviceMemory.h index f349ac7bf6..b7912d3562 100644 --- a/include/vsg/vk/DeviceMemory.h +++ b/include/vsg/vk/DeviceMemory.h @@ -98,7 +98,7 @@ namespace vsg } template - static ref_ptr create(DeviceMemory* deviceMemory, VkDeviceSize offset, VkMemoryMapFlags flags, Data::Properties properties, Args... args) + static ref_ptr create(DeviceMemory* deviceMemory, VkDeviceSize offset, VkMemoryMapFlags flags, const Data::Properties& properties, Args... args) { auto data = ref_ptr(new MappedData(deviceMemory, offset, flags, args...)); data->properties = properties; From 9438840c65169ee8a8615fa0b36d17a9e833330e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 9 May 2026 10:13:13 +0100 Subject: [PATCH 63/80] cppcheck fixes --- include/vsg/commands/Event.h | 6 +++--- include/vsg/core/External.h | 2 +- include/vsg/core/IntrusiveAllocator.h | 2 +- include/vsg/core/MipmapLayout.h | 2 +- include/vsg/core/Objects.h | 2 +- include/vsg/state/QueryPool.h | 2 +- src/vsg/utils/PolytopeIntersector.cpp | 6 +++--- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/vsg/commands/Event.h b/include/vsg/commands/Event.h index 9ce757192c..d580a46cff 100644 --- a/include/vsg/commands/Event.h +++ b/include/vsg/commands/Event.h @@ -57,7 +57,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~SetEvent(); + ~SetEvent() override; }; VSG_type_name(vsg::SetEvent); @@ -73,7 +73,7 @@ namespace vsg void record(CommandBuffer& commandBuffer) const override; protected: - virtual ~ResetEvent(); + ~ResetEvent() override; }; VSG_type_name(vsg::ResetEvent); @@ -107,7 +107,7 @@ namespace vsg ImageMemoryBarriers imageMemoryBarriers; protected: - virtual ~WaitEvents(); + ~WaitEvents() override; }; VSG_type_name(vsg::WaitEvents); diff --git a/include/vsg/core/External.h b/include/vsg/core/External.h index 47a8aa6235..d015261eaa 100644 --- a/include/vsg/core/External.h +++ b/include/vsg/core/External.h @@ -59,7 +59,7 @@ namespace vsg void add(const Path& filename, ref_ptr object = {}) { entries[filename] = object; } protected: - virtual ~External(); + ~External() override; }; VSG_type_name(vsg::External); diff --git a/include/vsg/core/IntrusiveAllocator.h b/include/vsg/core/IntrusiveAllocator.h index 1603bd9fda..39dd291142 100644 --- a/include/vsg/core/IntrusiveAllocator.h +++ b/include/vsg/core/IntrusiveAllocator.h @@ -48,7 +48,7 @@ namespace vsg explicit IntrusiveAllocator(size_t in_defaultAlignment = 8); explicit IntrusiveAllocator(std::unique_ptr in_nestedAllocator, size_t in_defaultAlignment = 8); - ~IntrusiveAllocator(); + ~IntrusiveAllocator() override; void report(std::ostream& out) const override; diff --git a/include/vsg/core/MipmapLayout.h b/include/vsg/core/MipmapLayout.h index 968114255f..51d91bae76 100644 --- a/include/vsg/core/MipmapLayout.h +++ b/include/vsg/core/MipmapLayout.h @@ -47,7 +47,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~MipmapLayout(); + ~MipmapLayout() override; }; VSG_type_name(vsg::MipmapLayout); diff --git a/include/vsg/core/Objects.h b/include/vsg/core/Objects.h index 292a6c60ae..5618bd94fd 100644 --- a/include/vsg/core/Objects.h +++ b/include/vsg/core/Objects.h @@ -48,7 +48,7 @@ namespace vsg } protected: - virtual ~Objects(); + ~Objects() override; }; VSG_type_name(vsg::Objects); diff --git a/include/vsg/state/QueryPool.h b/include/vsg/state/QueryPool.h index 7527fd3aa5..54ba71a71c 100644 --- a/include/vsg/state/QueryPool.h +++ b/include/vsg/state/QueryPool.h @@ -51,7 +51,7 @@ namespace vsg void compile(Context& context); protected: - ~QueryPool(); + ~QueryPool() override; VkQueryPool _queryPool{}; ref_ptr _device{}; diff --git a/src/vsg/utils/PolytopeIntersector.cpp b/src/vsg/utils/PolytopeIntersector.cpp index 14f4525b33..e5d3a04245 100644 --- a/src/vsg/utils/PolytopeIntersector.cpp +++ b/src/vsg/utils/PolytopeIntersector.cpp @@ -220,7 +220,7 @@ PolytopeIntersector::PolytopeIntersector(const Camera& camera, double xMin, doub clipspace.push_back(dplane(0.0, 0.0, 1.0, ndc_far)); // far vsg::Polytope eyespace; - for (auto& pl : clipspace) + for (const auto& pl : clipspace) { eyespace.push_back(pl * projectionMatrix); } @@ -228,7 +228,7 @@ PolytopeIntersector::PolytopeIntersector(const Camera& camera, double xMin, doub _polytopeStack.push_back(eyespace); vsg::Polytope worldspace; - for (auto& pl : eyespace) + for (const auto& pl : eyespace) { worldspace.push_back(pl * viewMatrix); } @@ -276,7 +276,7 @@ void PolytopeIntersector::pushTransform(const Transform& transform) const auto& worldspace = _polytopeStack.front(); Polytope localspace; - for (auto& pl : worldspace) + for (const auto& pl : worldspace) { localspace.push_back(pl * localToWorld); } From 5dcb224f1e1a27d20d00a0e921c08ff9cbdd6195 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 9 May 2026 12:38:20 +0100 Subject: [PATCH 64/80] cppcheck fixes --- cmake/cppcheck-suppression-list.txt | 1 + include/vsg/core/IntrusiveAllocator.h | 10 +++++++--- include/vsg/lighting/AmbientLight.h | 2 +- include/vsg/lighting/DirectionalLight.h | 2 +- include/vsg/lighting/Light.h | 2 +- include/vsg/lighting/PointLight.h | 2 +- include/vsg/lighting/ShadowSettings.h | 2 +- include/vsg/lighting/SpotLight.h | 2 +- include/vsg/raytracing/AccelerationStructure.h | 2 +- include/vsg/raytracing/RayTracingPipeline.h | 6 +++--- include/vsg/raytracing/RayTracingShaderGroup.h | 2 +- include/vsg/utils/CommandLine.h | 2 +- 12 files changed, 20 insertions(+), 15 deletions(-) diff --git a/cmake/cppcheck-suppression-list.txt b/cmake/cppcheck-suppression-list.txt index e08ee2adca..c699b6b3b9 100644 --- a/cmake/cppcheck-suppression-list.txt +++ b/cmake/cppcheck-suppression-list.txt @@ -152,6 +152,7 @@ arrayIndexOutOfBounds:*/include/vsg/vk/State.h // suppress warnings about intentional code usage or where cppcheck just hasn't got a clue about how templates are used... knownConditionTrueFalse:*/src/vsg/utils/Builder.cpp knownConditionTrueFalse:*/include/vsg/utils/CommandLine.h +knownConditionTrueFalse:*/include/vsg/utils/Inherit.h // suppress warning about initializtion. useInitializationList:*/include/vsg/core/ScratchMemory.h diff --git a/include/vsg/core/IntrusiveAllocator.h b/include/vsg/core/IntrusiveAllocator.h index 39dd291142..51c68cedf8 100644 --- a/include/vsg/core/IntrusiveAllocator.h +++ b/include/vsg/core/IntrusiveAllocator.h @@ -104,9 +104,13 @@ namespace vsg next(static_cast(in_next)), status(in_status) {} - Element() = default; - Element(const Element&) = default; - Element& operator=(const Element&) = default; + Element() : index(0) {} + Element(const Element& rhs) : index(rhs.index) {} + Element& operator=(const Element& rhs) + { + index = rhs.index; + return *this; + } }; struct FreeList diff --git a/include/vsg/lighting/AmbientLight.h b/include/vsg/lighting/AmbientLight.h index 9417bda87e..bcb22f8a6f 100644 --- a/include/vsg/lighting/AmbientLight.h +++ b/include/vsg/lighting/AmbientLight.h @@ -33,7 +33,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~AmbientLight() {} + ~AmbientLight() override {} }; VSG_type_name(vsg::AmbientLight); diff --git a/include/vsg/lighting/DirectionalLight.h b/include/vsg/lighting/DirectionalLight.h index 890c69721a..4ff000e7e9 100644 --- a/include/vsg/lighting/DirectionalLight.h +++ b/include/vsg/lighting/DirectionalLight.h @@ -37,7 +37,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~DirectionalLight() {} + ~DirectionalLight() override {} }; VSG_type_name(vsg::DirectionalLight); diff --git a/include/vsg/lighting/Light.h b/include/vsg/lighting/Light.h index bf6887be4a..cd2f44e7bf 100644 --- a/include/vsg/lighting/Light.h +++ b/include/vsg/lighting/Light.h @@ -41,7 +41,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~Light() {} + ~Light() override {} }; VSG_type_name(vsg::Light); diff --git a/include/vsg/lighting/PointLight.h b/include/vsg/lighting/PointLight.h index fd8fca3cef..7462d0f280 100644 --- a/include/vsg/lighting/PointLight.h +++ b/include/vsg/lighting/PointLight.h @@ -37,7 +37,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~PointLight() {} + ~PointLight() override {} }; VSG_type_name(vsg::PointLight); diff --git a/include/vsg/lighting/ShadowSettings.h b/include/vsg/lighting/ShadowSettings.h index 055e619297..2e36cc120e 100644 --- a/include/vsg/lighting/ShadowSettings.h +++ b/include/vsg/lighting/ShadowSettings.h @@ -33,7 +33,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~ShadowSettings() {} + ~ShadowSettings() override {} }; VSG_type_name(vsg::ShadowSettings); diff --git a/include/vsg/lighting/SpotLight.h b/include/vsg/lighting/SpotLight.h index 614d8de386..b8d8db3244 100644 --- a/include/vsg/lighting/SpotLight.h +++ b/include/vsg/lighting/SpotLight.h @@ -40,7 +40,7 @@ namespace vsg void write(Output& output) const override; protected: - virtual ~SpotLight() {} + ~SpotLight() override {} }; VSG_type_name(vsg::SpotLight); diff --git a/include/vsg/raytracing/AccelerationStructure.h b/include/vsg/raytracing/AccelerationStructure.h index 40773a32a7..f3cd750734 100644 --- a/include/vsg/raytracing/AccelerationStructure.h +++ b/include/vsg/raytracing/AccelerationStructure.h @@ -37,7 +37,7 @@ namespace vsg VkDeviceSize requiredScratchSize() const { return _requiredBuildScratchSize; } protected: - virtual ~AccelerationStructure(); + ~AccelerationStructure() override; VkAccelerationStructureKHR _accelerationStructure; VkAccelerationStructureCreateInfoKHR _accelerationStructureInfo; diff --git a/include/vsg/raytracing/RayTracingPipeline.h b/include/vsg/raytracing/RayTracingPipeline.h index 84fa32ef35..ec8910174c 100644 --- a/include/vsg/raytracing/RayTracingPipeline.h +++ b/include/vsg/raytracing/RayTracingPipeline.h @@ -56,12 +56,12 @@ namespace vsg VkPipeline vk(uint32_t deviceID) const { return _implementation[deviceID]->_pipeline; } protected: - virtual ~RayTracingPipeline(); + ~RayTracingPipeline() override; struct Implementation : public Inherit { Implementation(Context& context, RayTracingPipeline* rayTracingPipeline); - virtual ~Implementation(); + ~Implementation() override; VkPipeline _pipeline; @@ -103,7 +103,7 @@ namespace vsg virtual void release(); public: - virtual ~BindRayTracingPipeline(); + ~BindRayTracingPipeline() override; ref_ptr _pipeline; }; diff --git a/include/vsg/raytracing/RayTracingShaderGroup.h b/include/vsg/raytracing/RayTracingShaderGroup.h index 068c851660..0c3f5b50fb 100644 --- a/include/vsg/raytracing/RayTracingShaderGroup.h +++ b/include/vsg/raytracing/RayTracingShaderGroup.h @@ -38,7 +38,7 @@ namespace vsg ref_ptr bufferInfo; protected: - virtual ~RayTracingShaderGroup(); + ~RayTracingShaderGroup() override; }; VSG_type_name(vsg::RayTracingShaderGroup); diff --git a/include/vsg/utils/CommandLine.h b/include/vsg/utils/CommandLine.h index 7f24c00f46..4594e65af7 100644 --- a/include/vsg/utils/CommandLine.h +++ b/include/vsg/utils/CommandLine.h @@ -155,7 +155,7 @@ namespace vsg bool read(std::initializer_list matches, Args&... args) { bool result = false; - for (auto str : matches) result = read(str, args...) | result; + for (auto str : matches) result = read(str, args...) || result; return result; } From dbf1221d3df91d93d6eed29c21ab7216383dcc1f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 9 May 2026 12:46:59 +0100 Subject: [PATCH 65/80] Fix cppcheck warnings, and suppress inappropriate ones. --- cmake/cppcheck-suppression-list.txt | 4 ++++ include/vsg/state/ViewDependentState.h | 2 +- include/vsg/utils/Builder.h | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/cmake/cppcheck-suppression-list.txt b/cmake/cppcheck-suppression-list.txt index c699b6b3b9..0728930784 100644 --- a/cmake/cppcheck-suppression-list.txt +++ b/cmake/cppcheck-suppression-list.txt @@ -243,3 +243,7 @@ constVariablePointer:*/src/vsg/app/SecondaryCommandGraph.cpp // suppress inappropriate warning passedByValue:*/src/vsg/vk/Device.cpp passedByValue:*/src/vsg/vk/Instance.cpp + +// suppress inapproach functionStatic warnings +functionStatic:*/include/vsg/io/Output.h +functionStatic:*/include/vsg/io/Input.h diff --git a/include/vsg/state/ViewDependentState.h b/include/vsg/state/ViewDependentState.h index 76b75922f1..ded1e84ca7 100644 --- a/include/vsg/state/ViewDependentState.h +++ b/include/vsg/state/ViewDependentState.h @@ -175,7 +175,7 @@ namespace vsg mutable std::vector shadowMaps; protected: - ~ViewDependentState(); + ~ViewDependentState() override; }; VSG_type_name(vsg::ViewDependentState); diff --git a/include/vsg/utils/Builder.h b/include/vsg/utils/Builder.h index 99b9eccf18..5004515750 100644 --- a/include/vsg/utils/Builder.h +++ b/include/vsg/utils/Builder.h @@ -113,7 +113,7 @@ namespace vsg Builder(const Builder& rhs) = delete; Builder& operator=(const Builder& rhs) = delete; - ~Builder(); + ~Builder() override; bool verbose = false; ref_ptr options; From 4d57d60d2daad616cb135c86fad6866a4f048f6d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 9 May 2026 13:33:00 +0100 Subject: [PATCH 66/80] cppcheck suggest change --- include/vsg/app/WindowResizeHandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/vsg/app/WindowResizeHandler.h b/include/vsg/app/WindowResizeHandler.h index 87be5b3efa..b579af1a04 100644 --- a/include/vsg/app/WindowResizeHandler.h +++ b/include/vsg/app/WindowResizeHandler.h @@ -53,7 +53,7 @@ namespace vsg WindowResizeHandler(); template - T scale_parameter(T original, R extentOriginal, R extentNew) + static T scale_parameter(T original, R extentOriginal, R extentNew) { if (original == static_cast(extentOriginal)) return static_cast(extentNew); return static_cast(static_cast(original) * static_cast(extentNew) / static_cast(extentOriginal) + 0.5f); From 5b507e84ccd57ea323422fd0f65e744009378b15 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 9 May 2026 14:19:18 +0100 Subject: [PATCH 67/80] cppcheck suggested change --- include/vsg/io/JSONParser.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/vsg/io/JSONParser.h b/include/vsg/io/JSONParser.h index 90c72d7bb3..c713477a8a 100644 --- a/include/vsg/io/JSONParser.h +++ b/include/vsg/io/JSONParser.h @@ -82,7 +82,7 @@ namespace vsg warnings.push_back(vsg::make_string("Parsing error at [", line, ":", column, "], pos = ", pos, " [ ", lineEnclosingPosition(pos), " ]. ", std::forward(args)...)); } - inline bool white_space(char c) const + static inline bool white_space(char c) const { return (c == ' ' || c == '\t' || c == '\r' || c == '\n'); } From a85afb1c2ca79defe645295733d60ddc2ee30196 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 9 May 2026 15:48:32 +0100 Subject: [PATCH 68/80] Build fix --- include/vsg/io/JSONParser.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/vsg/io/JSONParser.h b/include/vsg/io/JSONParser.h index c713477a8a..024c86a55a 100644 --- a/include/vsg/io/JSONParser.h +++ b/include/vsg/io/JSONParser.h @@ -82,7 +82,7 @@ namespace vsg warnings.push_back(vsg::make_string("Parsing error at [", line, ":", column, "], pos = ", pos, " [ ", lineEnclosingPosition(pos), " ]. ", std::forward(args)...)); } - static inline bool white_space(char c) const + static inline bool white_space(char c) { return (c == ' ' || c == '\t' || c == '\r' || c == '\n'); } From 179c85ca6f504bb10730d96155ab71743a3a8009 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 9 May 2026 15:51:20 +0100 Subject: [PATCH 69/80] Quietened erroneous warning --- cmake/cppcheck-suppression-list.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/cppcheck-suppression-list.txt b/cmake/cppcheck-suppression-list.txt index 0728930784..3d4233283e 100644 --- a/cmake/cppcheck-suppression-list.txt +++ b/cmake/cppcheck-suppression-list.txt @@ -152,7 +152,7 @@ arrayIndexOutOfBounds:*/include/vsg/vk/State.h // suppress warnings about intentional code usage or where cppcheck just hasn't got a clue about how templates are used... knownConditionTrueFalse:*/src/vsg/utils/Builder.cpp knownConditionTrueFalse:*/include/vsg/utils/CommandLine.h -knownConditionTrueFalse:*/include/vsg/utils/Inherit.h +knownConditionTrueFalse:*/include/vsg/core/Inherit.h // suppress warning about initializtion. useInitializationList:*/include/vsg/core/ScratchMemory.h From 0f262fe483848514894b799b905ae356fecc56d2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 10 May 2026 10:43:12 +0100 Subject: [PATCH 70/80] cppcheck fixes --- cmake/cppcheck-suppression-list.txt | 19 ++++++++++++++++++- include/vsg/utils/TracyInstrumentation.h | 2 +- src/vsg/app/Viewer.cpp | 4 ++-- src/vsg/commands/ExecuteCommands.cpp | 2 +- src/vsg/state/ViewDependentState.cpp | 2 +- src/vsg/utils/ComputeBounds.cpp | 4 ++-- src/vsg/utils/ShaderCompiler.cpp | 4 +--- 7 files changed, 26 insertions(+), 11 deletions(-) diff --git a/cmake/cppcheck-suppression-list.txt b/cmake/cppcheck-suppression-list.txt index 3d4233283e..d25ad2cce2 100644 --- a/cmake/cppcheck-suppression-list.txt +++ b/cmake/cppcheck-suppression-list.txt @@ -244,6 +244,23 @@ constVariablePointer:*/src/vsg/app/SecondaryCommandGraph.cpp passedByValue:*/src/vsg/vk/Device.cpp passedByValue:*/src/vsg/vk/Instance.cpp -// suppress inapproach functionStatic warnings +// suppress inappropriate warnings functionStatic:*/include/vsg/io/Output.h functionStatic:*/include/vsg/io/Input.h +functionStatic:*/src/vsg/app/CompileManager.h +functionStatic:*/include/vsg/app/RecordTraversal.h +functionStatic:*/include/vsg/io/VSG.h +functionStatic:*/include/vsg/io/json.h +functionStatic:*/include/vsg/io/txt.h +functionStatic:*/include/vsg/io/tile.h +functionStatic:*/include/vsg/state/QueryPool.h +functionStatic:*/include/vsg/state/ArrayState.h +functionStatic:*/include/vsg/text/StandardLayout.h +functionStatic:*/include/vsg/utils/Builder.h +functionStatic:*/include/vsg/utils/ShaderCompiler.h +functionStatic:*/ +functionStatic:*/ + + +// suppress inappropriate warnings +suspiciousFloatingPointCast:*/src/vsg/maths/maths_transform.cpp diff --git a/include/vsg/utils/TracyInstrumentation.h b/include/vsg/utils/TracyInstrumentation.h index 1d6bd86132..f552cdebd8 100644 --- a/include/vsg/utils/TracyInstrumentation.h +++ b/include/vsg/utils/TracyInstrumentation.h @@ -80,7 +80,7 @@ namespace vsg mutable std::map, std::pair> ctxMap; protected: - ~TracyContexts() + ~TracyContexts() override { for (auto itr = ctxMap.begin(); itr != ctxMap.end(); ++itr) { diff --git a/src/vsg/app/Viewer.cpp b/src/vsg/app/Viewer.cpp index f1da140180..3c186b14a3 100644 --- a/src/vsg/app/Viewer.cpp +++ b/src/vsg/app/Viewer.cpp @@ -92,7 +92,7 @@ void Viewer::removeWindow(ref_ptr window) CommandGraphs commandGraphs; for (const auto& task : recordAndSubmitTasks) { - for (auto& cg : task->commandGraphs) + for (const auto& cg : task->commandGraphs) { if (cg->window != window) commandGraphs.push_back(cg); } @@ -582,7 +582,7 @@ void Viewer::addRecordAndSubmitTaskAndPresentation(CommandGraphs commandGraphs) CommandGraphs combinedCommandGraphs; for (const auto& task : recordAndSubmitTasks) { - for (auto& cg : task->commandGraphs) + for (const auto& cg : task->commandGraphs) { combinedCommandGraphs.push_back(cg); } diff --git a/src/vsg/commands/ExecuteCommands.cpp b/src/vsg/commands/ExecuteCommands.cpp index 5aa2821563..cb17b008b0 100644 --- a/src/vsg/commands/ExecuteCommands.cpp +++ b/src/vsg/commands/ExecuteCommands.cpp @@ -71,7 +71,7 @@ void ExecuteCommands::record(CommandBuffer& commandBuffer) const std::scoped_lock lock(_mutex); std::vector vk_commandBuffers; - for (auto& entry : _commandGraphsAndBuffers) + for (const auto& entry : _commandGraphsAndBuffers) { if (entry.cb) vk_commandBuffers.push_back(*entry.cb); } diff --git a/src/vsg/state/ViewDependentState.cpp b/src/vsg/state/ViewDependentState.cpp index 801cd28ff4..0d194f9fbc 100644 --- a/src/vsg/state/ViewDependentState.cpp +++ b/src/vsg/state/ViewDependentState.cpp @@ -658,7 +658,7 @@ void ViewDependentState::traverse(RecordTraversal& rt) const dbox eyeSpaceRegionBounds; for (auto& [mv, regionOfInterest] : rt.regionsOfInterest) { - for (auto& v : regionOfInterest->points) + for (const auto& v : regionOfInterest->points) { eyeSpaceRegionBounds.add(mv * v); } diff --git a/src/vsg/utils/ComputeBounds.cpp b/src/vsg/utils/ComputeBounds.cpp index 11fed2b290..a055996bca 100644 --- a/src/vsg/utils/ComputeBounds.cpp +++ b/src/vsg/utils/ComputeBounds.cpp @@ -302,7 +302,7 @@ void ComputeBounds::add(const dbox& bb) } else { - auto& matrix = matrixStack.back(); + const auto& matrix = matrixStack.back(); bounds.add(matrix * bb.min); bounds.add(matrix * dvec3(bb.max.x, bb.min.y, bb.min.z)); bounds.add(matrix * dvec3(bb.max.x, bb.max.y, bb.min.z)); @@ -323,7 +323,7 @@ void ComputeBounds::add(const dsphere& bs) } else { - auto& matrix = matrixStack.back(); + const auto& matrix = matrixStack.back(); bounds.add(matrix * dvec3(bs.center.x - bs.radius, bs.center.y - bs.radius, bs.center.z - bs.radius)); bounds.add(matrix * dvec3(bs.center.x + bs.radius, bs.center.y - bs.radius, bs.center.z - bs.radius)); bounds.add(matrix * dvec3(bs.center.x - bs.radius, bs.center.y + bs.radius, bs.center.z - bs.radius)); diff --git a/src/vsg/utils/ShaderCompiler.cpp b/src/vsg/utils/ShaderCompiler.cpp index ff1364a1bb..9e79e395a4 100644 --- a/src/vsg/utils/ShaderCompiler.cpp +++ b/src/vsg/utils/ShaderCompiler.cpp @@ -281,7 +281,7 @@ bool ShaderCompiler::compile(ShaderStages& shaders, const std::vectormodule->source, options); std::vector combinedDefines(defines); - for (auto& define : settings->defines) combinedDefines.push_back(define); + for (const auto& define : settings->defines) combinedDefines.push_back(define); if (!combinedDefines.empty()) finalShaderSource = combineSourceAndDefines(finalShaderSource, combinedDefines); vsg::debug("ShaderCompiler::compile() combinedDefines = ", combinedDefines); @@ -472,8 +472,6 @@ std::string ShaderCompiler::combineSourceAndDefines(const std::string& source, c const std::string versionmatch = "#version"; const std::string importdefinesmatch = "#pragma import_defines"; - std::vector finaldefines; - for (std::string line; std::getline(iss, line);) { std::string sanitisedline = line; From 5ef01985584047bd03986f1945b5e1d046b08535 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 10 May 2026 10:52:51 +0100 Subject: [PATCH 71/80] cppcheck bug fix!! --- src/vsg/vk/ResourceRequirements.cpp | 2 +- src/vsg/vk/Swapchain.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vsg/vk/ResourceRequirements.cpp b/src/vsg/vk/ResourceRequirements.cpp index 9b02299488..6ca2196714 100644 --- a/src/vsg/vk/ResourceRequirements.cpp +++ b/src/vsg/vk/ResourceRequirements.cpp @@ -90,7 +90,7 @@ void ResourceRequirements::apply(const ResourceHints& resourceHints) viewportStateHint = resourceHints.viewportStateHint; dynamicData.add(resourceHints.dynamicData); - containsPagedLOD = containsPagedLOD | resourceHints.containsPagedLOD; + containsPagedLOD = containsPagedLOD || resourceHints.containsPagedLOD; } ////////////////////////////////////////////////////////////////////// diff --git a/src/vsg/vk/Swapchain.cpp b/src/vsg/vk/Swapchain.cpp index 24b1963651..612e604661 100644 --- a/src/vsg/vk/Swapchain.cpp +++ b/src/vsg/vk/Swapchain.cpp @@ -141,7 +141,7 @@ namespace vsg } protected: - virtual ~SwapchainImage() + ~SwapchainImage() override { for (auto& vd : _vulkanData) { From e4674d4dae8124d7145e76f0f67454692e5e77cd Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 10 May 2026 11:31:49 +0100 Subject: [PATCH 72/80] cppcheck fixes --- cmake/cppcheck-suppression-list.txt | 7 +++++-- include/vsg/lighting/AmbientLight.h | 3 --- include/vsg/lighting/HardShadows.h | 4 ---- .../vsg/lighting/PercentageCloserSoftShadows.h | 4 ---- src/vsg/lighting/AmbientLight.cpp | 10 ---------- src/vsg/lighting/HardShadows.cpp | 15 --------------- src/vsg/lighting/PercentageCloserSoftShadows.cpp | 15 --------------- src/vsg/meshshaders/DrawMeshTasks.cpp | 2 +- src/vsg/meshshaders/DrawMeshTasksIndirect.cpp | 2 +- .../meshshaders/DrawMeshTasksIndirectCount.cpp | 2 +- src/vsg/nodes/Transform.cpp | 4 ++++ 11 files changed, 12 insertions(+), 56 deletions(-) diff --git a/cmake/cppcheck-suppression-list.txt b/cmake/cppcheck-suppression-list.txt index d25ad2cce2..8d50104252 100644 --- a/cmake/cppcheck-suppression-list.txt +++ b/cmake/cppcheck-suppression-list.txt @@ -224,6 +224,11 @@ cstyleCast:*/src/vsg/io/mem_stream.cpp // suppress unhelpful warnings of override that make inform programmers what is being done uselessOverride:*/include/vsg/utils/TracyInstrumentation.h +uselessOverride:*/include/vsg/ui/WindowEvent.h +uselessOverride:*/include/vsg/utils/ShaderSet.h +uselessOverride:*/include/vsg/nodes/Transform.h +uselessOverride:*/include/vsg/raytracing/DescriptorAccelerationStructure.h +uselessOverride:*/include/vsg/raytracing/RayTracingShaderGroup.h // suppress inappropriate warning constParameterReference:*/include/vsg/vk/Device.h @@ -258,8 +263,6 @@ functionStatic:*/include/vsg/state/ArrayState.h functionStatic:*/include/vsg/text/StandardLayout.h functionStatic:*/include/vsg/utils/Builder.h functionStatic:*/include/vsg/utils/ShaderCompiler.h -functionStatic:*/ -functionStatic:*/ // suppress inappropriate warnings diff --git a/include/vsg/lighting/AmbientLight.h b/include/vsg/lighting/AmbientLight.h index bcb22f8a6f..61d418c2a3 100644 --- a/include/vsg/lighting/AmbientLight.h +++ b/include/vsg/lighting/AmbientLight.h @@ -29,9 +29,6 @@ namespace vsg public: ref_ptr clone(const CopyOp& copyop = {}) const override { return AmbientLight::create(*this, copyop); } - void read(Input& input) override; - void write(Output& output) const override; - protected: ~AmbientLight() override {} }; diff --git a/include/vsg/lighting/HardShadows.h b/include/vsg/lighting/HardShadows.h index 1f868cb4c7..035351aa0c 100644 --- a/include/vsg/lighting/HardShadows.h +++ b/include/vsg/lighting/HardShadows.h @@ -25,10 +25,6 @@ namespace vsg public: ref_ptr clone(const CopyOp& copyop = {}) const override { return HardShadows::create(*this, copyop); } - int compare(const Object& rhs) const override; - - void read(Input& input) override; - void write(Output& output) const override; }; VSG_type_name(vsg::HardShadows); diff --git a/include/vsg/lighting/PercentageCloserSoftShadows.h b/include/vsg/lighting/PercentageCloserSoftShadows.h index 40bd546ebd..8bda61a965 100644 --- a/include/vsg/lighting/PercentageCloserSoftShadows.h +++ b/include/vsg/lighting/PercentageCloserSoftShadows.h @@ -25,10 +25,6 @@ namespace vsg public: ref_ptr clone(const CopyOp& copyop = {}) const override { return PercentageCloserSoftShadows::create(*this, copyop); } - int compare(const Object& rhs) const override; - - void read(Input& input) override; - void write(Output& output) const override; }; VSG_type_name(vsg::PercentageCloserSoftShadows); diff --git a/src/vsg/lighting/AmbientLight.cpp b/src/vsg/lighting/AmbientLight.cpp index 6878dc4490..72f59aaf58 100644 --- a/src/vsg/lighting/AmbientLight.cpp +++ b/src/vsg/lighting/AmbientLight.cpp @@ -22,13 +22,3 @@ AmbientLight::AmbientLight(const AmbientLight& rhs, const CopyOp& copyop) : Inherit(rhs, copyop) { } - -void AmbientLight::read(Input& input) -{ - Light::read(input); -} - -void AmbientLight::write(Output& output) const -{ - Light::write(output); -} diff --git a/src/vsg/lighting/HardShadows.cpp b/src/vsg/lighting/HardShadows.cpp index bdd702c9f6..f9811747dc 100644 --- a/src/vsg/lighting/HardShadows.cpp +++ b/src/vsg/lighting/HardShadows.cpp @@ -23,18 +23,3 @@ HardShadows::HardShadows(const HardShadows& rhs, const CopyOp& copyop) : Inherit(rhs, copyop) { } - -int HardShadows::compare(const Object& rhs_object) const -{ - return ShadowSettings::compare(rhs_object); -} - -void HardShadows::read(Input& input) -{ - ShadowSettings::read(input); -} - -void HardShadows::write(Output& output) const -{ - ShadowSettings::write(output); -} diff --git a/src/vsg/lighting/PercentageCloserSoftShadows.cpp b/src/vsg/lighting/PercentageCloserSoftShadows.cpp index 85de950484..ede15efdcd 100644 --- a/src/vsg/lighting/PercentageCloserSoftShadows.cpp +++ b/src/vsg/lighting/PercentageCloserSoftShadows.cpp @@ -23,18 +23,3 @@ PercentageCloserSoftShadows::PercentageCloserSoftShadows(const PercentageCloserS Inherit(rhs, copyop) { } - -int PercentageCloserSoftShadows::compare(const Object& rhs_object) const -{ - return ShadowSettings::compare(rhs_object); -} - -void PercentageCloserSoftShadows::read(Input& input) -{ - ShadowSettings::read(input); -} - -void PercentageCloserSoftShadows::write(Output& output) const -{ - ShadowSettings::write(output); -} diff --git a/src/vsg/meshshaders/DrawMeshTasks.cpp b/src/vsg/meshshaders/DrawMeshTasks.cpp index da2bca13cc..df6e13430c 100644 --- a/src/vsg/meshshaders/DrawMeshTasks.cpp +++ b/src/vsg/meshshaders/DrawMeshTasks.cpp @@ -43,7 +43,7 @@ void DrawMeshTasks::write(Output& output) const void DrawMeshTasks::record(vsg::CommandBuffer& commandBuffer) const { - Device* device = commandBuffer.getDevice(); + auto device = commandBuffer.getDevice(); auto extensions = device->getExtensions(); extensions->vkCmdDrawMeshTasksEXT(commandBuffer, groupCountX, groupCountY, groupCountZ); } diff --git a/src/vsg/meshshaders/DrawMeshTasksIndirect.cpp b/src/vsg/meshshaders/DrawMeshTasksIndirect.cpp index 3e0a6a60e4..cd0a49a186 100644 --- a/src/vsg/meshshaders/DrawMeshTasksIndirect.cpp +++ b/src/vsg/meshshaders/DrawMeshTasksIndirect.cpp @@ -72,7 +72,7 @@ void DrawMeshTasksIndirect::compile(Context& context) void DrawMeshTasksIndirect::record(vsg::CommandBuffer& commandBuffer) const { - Device* device = commandBuffer.getDevice(); + auto device = commandBuffer.getDevice(); auto extensions = device->getExtensions(); extensions->vkCmdDrawMeshTasksIndirectEXT(commandBuffer, drawParameters->buffer->vk(commandBuffer.deviceID), drawParameters->offset, drawCount, stride); } diff --git a/src/vsg/meshshaders/DrawMeshTasksIndirectCount.cpp b/src/vsg/meshshaders/DrawMeshTasksIndirectCount.cpp index c8e7e53c17..ab7c18462f 100644 --- a/src/vsg/meshshaders/DrawMeshTasksIndirectCount.cpp +++ b/src/vsg/meshshaders/DrawMeshTasksIndirectCount.cpp @@ -83,7 +83,7 @@ void DrawMeshTasksIndirectCount::compile(Context& context) void DrawMeshTasksIndirectCount::record(vsg::CommandBuffer& commandBuffer) const { - Device* device = commandBuffer.getDevice(); + auto device = commandBuffer.getDevice(); auto extensions = device->getExtensions(); extensions->vkCmdDrawMeshTasksIndirectCountEXT(commandBuffer, drawParameters->buffer->vk(commandBuffer.deviceID), drawParameters->offset, drawCount->buffer->vk(commandBuffer.deviceID), drawCount->offset, maxDrawCount, stride); } diff --git a/src/vsg/nodes/Transform.cpp b/src/vsg/nodes/Transform.cpp index 52cc4cb362..ae70dd756d 100644 --- a/src/vsg/nodes/Transform.cpp +++ b/src/vsg/nodes/Transform.cpp @@ -38,9 +38,13 @@ int Transform::compare(const Object& rhs_object) const void Transform::read(Input& input) { Group::read(input); + + // subclasses currently serialize subgraphRequiresLocalFrustum } void Transform::write(Output& output) const { Group::write(output); + + // subclasses currently serialize subgraphRequiresLocalFrustum } From 0a1e52db1dee6f8a1f76ab7f92d89874b2af83dc Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 10 May 2026 15:58:35 +0100 Subject: [PATCH 73/80] Added extra files to suppression list --- cmake/cppcheck-suppression-list.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmake/cppcheck-suppression-list.txt b/cmake/cppcheck-suppression-list.txt index 8d50104252..1e866116d2 100644 --- a/cmake/cppcheck-suppression-list.txt +++ b/cmake/cppcheck-suppression-list.txt @@ -252,9 +252,12 @@ passedByValue:*/src/vsg/vk/Instance.cpp // suppress inappropriate warnings functionStatic:*/include/vsg/io/Output.h functionStatic:*/include/vsg/io/Input.h -functionStatic:*/src/vsg/app/CompileManager.h +functionStatic:*/include/vsg/app/CompileManager.h +functionStatic:*/include/vsg/app/CompileManager.cpp functionStatic:*/include/vsg/app/RecordTraversal.h +functionStatic:*/src/vsg/app/RecordTraversal.cpp functionStatic:*/include/vsg/io/VSG.h +functionStatic:*/src/vsg/io/VSG.cpp functionStatic:*/include/vsg/io/json.h functionStatic:*/include/vsg/io/txt.h functionStatic:*/include/vsg/io/tile.h From 6185c738b5576065e51231d5740814219e4d74d5 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 10 May 2026 16:24:14 +0100 Subject: [PATCH 74/80] Four bug fixes to issues found by an AI code audit! --- include/vsg/maths/mat4.h | 7 +++--- src/vsg/animation/CameraSampler.cpp | 35 +++++++++++++++++++++-------- src/vsg/state/ColorBlendState.cpp | 2 +- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/include/vsg/maths/mat4.h b/include/vsg/maths/mat4.h index 83257afc54..ad5ab16031 100644 --- a/include/vsg/maths/mat4.h +++ b/include/vsg/maths/mat4.h @@ -236,9 +236,8 @@ namespace vsg t_vec3 operator*(const t_vec3& lhs, const t_mat4& rhs) { T inv = numbers::one() / (lhs[0] * rhs[3][0] + lhs[1] * rhs[3][1] + lhs[2] * rhs[3][2] + rhs[3][3]); - return t_vec3(lhs[0] * rhs[0][0] + lhs[1] * rhs[0][1] + lhs[2] * rhs[0][2] + rhs[0][3] * inv, - lhs[0] * rhs[1][0] + lhs[1] * rhs[1][1] + lhs[2] * rhs[1][2] + rhs[1][3] * inv, - lhs[0] * rhs[2][0] + lhs[1] * rhs[2][1] + lhs[2] * rhs[2][2] + rhs[2][3] * inv); + return t_vec3((lhs[0] * rhs[0][0] + lhs[1] * rhs[0][1] + lhs[2] * rhs[0][2] + rhs[0][3]) * inv, + (lhs[0] * rhs[1][0] + lhs[1] * rhs[1][1] + lhs[2] * rhs[1][2] + rhs[1][3]) * inv, + (lhs[0] * rhs[2][0] + lhs[1] * rhs[2][1] + lhs[2] * rhs[2][2] + rhs[2][3]) * inv); } - } // namespace vsg diff --git a/src/vsg/animation/CameraSampler.cpp b/src/vsg/animation/CameraSampler.cpp index 1aaa146e58..1a222a8b55 100644 --- a/src/vsg/animation/CameraSampler.cpp +++ b/src/vsg/animation/CameraSampler.cpp @@ -45,6 +45,19 @@ void CameraKeyframes::read(Input& input) input.readObjects("path", track.value); } + if (input.version_greater_equal(1, 1, 15)) + { + // read origin key frames + uint32_t num_origins = input.readValue("origins"); + origins.resize(num_origins); + for (auto& origin : origins) + { + input.matchPropertyName("origin"); + input.read(1, &origin.time); + input.read(1, &origin.value); + } + } + // read position key frames uint32_t num_positions = input.readValue("positions"); positions.resize(num_positions); @@ -103,6 +116,19 @@ void CameraKeyframes::write(Output& output) const output.writeObjects("path", track.value); } + if (output.version_greater_equal(1, 1, 15)) + { + // write origin key frames + output.writeValue("origins", origins.size()); + for (const auto& origin : origins) + { + output.writePropertyName("origin"); + output.write(1, &origin.time); + output.write(1, &origin.value); + output.writeEndOfLine(); + } + } + // write position key frames output.writeValue("positions", positions.size()); for (const auto& position : positions) @@ -123,15 +149,6 @@ void CameraKeyframes::write(Output& output) const output.writeEndOfLine(); } - // write scale key frames - for (const auto& scale : fieldOfViews) - { - output.writePropertyName("fov"); - output.write(1, &scale.time); - output.write(1, &scale.value); - output.writeEndOfLine(); - } - // write field of view key frames output.writeValue("fieldOfViews", fieldOfViews.size()); for (const auto& fov : fieldOfViews) diff --git a/src/vsg/state/ColorBlendState.cpp b/src/vsg/state/ColorBlendState.cpp index 105f50ea37..eb9993dca5 100644 --- a/src/vsg/state/ColorBlendState.cpp +++ b/src/vsg/state/ColorBlendState.cpp @@ -85,7 +85,7 @@ int ColorBlendState::compare(const Object& rhs_object) const if ((result = compare_value(logicOpEnable, rhs.logicOpEnable))) return result; if ((result = compare_value(logicOp, rhs.logicOp))) return result; if ((result = compare_value_container(attachments, rhs.attachments))) return result; - return compare_values(blendConstants, rhs.blendConstants, 3); + return compare_values(blendConstants, rhs.blendConstants, 4); } void ColorBlendState::read(Input& input) From 599a8c5c61cbb993079261b2ada99bd843badf5b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 10 May 2026 18:27:47 +0100 Subject: [PATCH 75/80] Quietened down debug message --- src/vsg/app/CompileManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vsg/app/CompileManager.cpp b/src/vsg/app/CompileManager.cpp index 9c6b0d23a6..0db9a10a58 100644 --- a/src/vsg/app/CompileManager.cpp +++ b/src/vsg/app/CompileManager.cpp @@ -147,7 +147,7 @@ CompileManager::CompileManager(Viewer& viewer, ref_ptr hints) CompileManager::~CompileManager() { - vsg::info("CompileManager::~CompileManager() successfulCompileCount= ", successfulCompileCount, ", failedCompileCount = ", failedCompileCount); + vsg::debug("CompileManager::~CompileManager() successfulCompileCount= ", successfulCompileCount, ", failedCompileCount = ", failedCompileCount); } CompileManager::CompileTraversals::container_type CompileManager::takeCompileTraversals(size_t count) From b01d466c992614b0985661a4ca44f64b1ffac2f0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 May 2026 18:50:00 +0100 Subject: [PATCH 76/80] Added enabling of and checks for VK_EXT_memory_budget --- include/vsg/vk/Device.h | 3 ++ src/vsg/vk/Device.cpp | 71 ++++++++++++++++++++++++++++++----------- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/include/vsg/vk/Device.h b/include/vsg/vk/Device.h index 92b97bfcef..212d55e484 100644 --- a/include/vsg/vk/Device.h +++ b/include/vsg/vk/Device.h @@ -85,6 +85,9 @@ namespace vsg /// return true if Device was created with specified extension bool supportsDeviceExtension(const char* extensionName) const; + /// commonly checked extensions + const bool memory_budget = false; // VK_EXT_memory_budget + /// return the amount of remaining memory, compatible with specified flags, available that can be allocated. VkDeviceSize availableMemory(VkMemoryPropertyFlags memoryPropertiesFlags, double allocatedMemoryLimit = 1.0) const; diff --git a/src/vsg/vk/Device.cpp b/src/vsg/vk/Device.cpp index 9fe8625979..1873031d20 100644 --- a/src/vsg/vk/Device.cpp +++ b/src/vsg/vk/Device.cpp @@ -53,7 +53,6 @@ static void releaseDeviceID(uint32_t deviceID) Device::Device(PhysicalDevice* physicalDevice, const QueueSettings& queueSettings, Names layers, Names deviceExtensions, const DeviceFeatures* deviceFeatures, AllocationCallbacks* allocator) : deviceID(getUniqueDeviceID()), - enabledExtensions(deviceExtensions), _instance(physicalDevice->getInstance()), _physicalDevice(physicalDevice), _allocator(allocator) @@ -115,6 +114,12 @@ Device::Device(PhysicalDevice* physicalDevice, const QueueSettings& queueSetting deviceExtensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); #endif + if (_physicalDevice->supportsDeviceExtension(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME)) + { + deviceExtensions.push_back(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME); + const_cast(memory_budget) = true; + } + VkDeviceCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; @@ -162,6 +167,7 @@ Device::Device(PhysicalDevice* physicalDevice, const QueueSettings& queueSetting } } + const_cast(enabledExtensions) = deviceExtensions; _extensions = DeviceExtensions::create(this); } @@ -208,32 +214,59 @@ bool Device::supportsDeviceExtension(const char* extensionName) const VkDeviceSize Device::availableMemory(VkMemoryPropertyFlags memoryPropertiesFlags, double allocatedMemoryLimit) const { - VkPhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget; - memoryBudget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; - memoryBudget.pNext = nullptr; + if (memory_budget) + { + VkPhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget; + memoryBudget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; + memoryBudget.pNext = nullptr; - VkPhysicalDeviceMemoryProperties2 dmp; - dmp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2; - dmp.pNext = &memoryBudget; + VkPhysicalDeviceMemoryProperties2 dmp; + dmp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2; + dmp.pNext = &memoryBudget; - vkGetPhysicalDeviceMemoryProperties2(*(getPhysicalDevice()), &dmp); + vkGetPhysicalDeviceMemoryProperties2(*(getPhysicalDevice()), &dmp); - auto& memoryProperties = dmp.memoryProperties; + auto& memoryProperties = dmp.memoryProperties; - VkDeviceSize availableSpace = 0; - for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i) + VkDeviceSize availableSpace = 0; + for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i) + { + if ((memoryProperties.memoryTypes[i].propertyFlags & memoryPropertiesFlags) == memoryPropertiesFlags) // supported + { + uint32_t heapIndex = memoryProperties.memoryTypes[i].heapIndex; + + VkDeviceSize heapBudget = static_cast(static_cast(memoryBudget.heapBudget[heapIndex]) * allocatedMemoryLimit); + VkDeviceSize heapUsage = memoryBudget.heapUsage[heapIndex]; + VkDeviceSize heapAvailable = (heapUsage < heapBudget) ? heapBudget - heapUsage : 0; + availableSpace += heapAvailable; + + break; + } + } + + return availableSpace; + } + else { - if ((memoryProperties.memoryTypes[i].propertyFlags & memoryPropertiesFlags) == memoryPropertiesFlags) // supported + VkPhysicalDeviceMemoryProperties memoryProperties; + vkGetPhysicalDeviceMemoryProperties(*(getPhysicalDevice()), &memoryProperties); + + VkDeviceSize availableSpace = 0; + for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i) { - uint32_t heapIndex = memoryProperties.memoryTypes[i].heapIndex; + if ((memoryProperties.memoryTypes[i].propertyFlags & memoryPropertiesFlags) == memoryPropertiesFlags) // supported + { + uint32_t heapIndex = memoryProperties.memoryTypes[i].heapIndex; + + VkDeviceSize heapBudget = static_cast(static_cast(memoryProperties.memoryHeaps[heapIndex].size) * allocatedMemoryLimit);; - VkDeviceSize heapBudget = static_cast(static_cast(memoryBudget.heapBudget[heapIndex]) * allocatedMemoryLimit); - VkDeviceSize heapUsage = memoryBudget.heapUsage[heapIndex]; - VkDeviceSize heapAvailable = (heapUsage < heapBudget) ? heapBudget - heapUsage : 0; - availableSpace += heapAvailable; + // unable to estimate usage, so assume whole budget is available and let calling code gracefully handle any memory allocation failures. + availableSpace += heapBudget; - break; + break; + } } + + return availableSpace; } - return availableSpace; } From 61c94f5daa330a5602fee468dcf07d36ad61ee6c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 May 2026 10:35:36 +0100 Subject: [PATCH 77/80] Moved extension check to DeviceExtensions. --- include/vsg/vk/Device.h | 3 --- include/vsg/vk/DeviceExtensions.h | 3 +++ src/vsg/vk/Device.cpp | 5 ++--- src/vsg/vk/DeviceExtensions.cpp | 2 ++ 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/include/vsg/vk/Device.h b/include/vsg/vk/Device.h index 212d55e484..92b97bfcef 100644 --- a/include/vsg/vk/Device.h +++ b/include/vsg/vk/Device.h @@ -85,9 +85,6 @@ namespace vsg /// return true if Device was created with specified extension bool supportsDeviceExtension(const char* extensionName) const; - /// commonly checked extensions - const bool memory_budget = false; // VK_EXT_memory_budget - /// return the amount of remaining memory, compatible with specified flags, available that can be allocated. VkDeviceSize availableMemory(VkMemoryPropertyFlags memoryPropertiesFlags, double allocatedMemoryLimit = 1.0) const; diff --git a/include/vsg/vk/DeviceExtensions.h b/include/vsg/vk/DeviceExtensions.h index 08641831fd..e65157208e 100644 --- a/include/vsg/vk/DeviceExtensions.h +++ b/include/vsg/vk/DeviceExtensions.h @@ -61,6 +61,9 @@ namespace vsg PFN_vkCmdSetDepthBoundsTestEnableEXT vkCmdSetDepthBoundsTestEnable = nullptr; PFN_vkCmdSetStencilTestEnableEXT vkCmdSetStencilTestEnable = nullptr; PFN_vkCmdSetStencilOpEXT vkCmdSetStencilOp = nullptr; + + // cache whether extension is supported + bool memory_budget = false; // VK_EXT_memory_budget }; VSG_type_name(vsg::DeviceExtensions); diff --git a/src/vsg/vk/Device.cpp b/src/vsg/vk/Device.cpp index 1873031d20..a13a24c857 100644 --- a/src/vsg/vk/Device.cpp +++ b/src/vsg/vk/Device.cpp @@ -114,10 +114,9 @@ Device::Device(PhysicalDevice* physicalDevice, const QueueSettings& queueSetting deviceExtensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); #endif - if (_physicalDevice->supportsDeviceExtension(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME)) + if (supportsApiVersion(VK_API_VERSION_1_1) && _physicalDevice->supportsDeviceExtension(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME)) { deviceExtensions.push_back(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME); - const_cast(memory_budget) = true; } VkDeviceCreateInfo createInfo = {}; @@ -214,7 +213,7 @@ bool Device::supportsDeviceExtension(const char* extensionName) const VkDeviceSize Device::availableMemory(VkMemoryPropertyFlags memoryPropertiesFlags, double allocatedMemoryLimit) const { - if (memory_budget) + if (_extensions->memory_budget) { VkPhysicalDeviceMemoryBudgetPropertiesEXT memoryBudget; memoryBudget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; diff --git a/src/vsg/vk/DeviceExtensions.cpp b/src/vsg/vk/DeviceExtensions.cpp index 4390229c38..d2f668c5f8 100644 --- a/src/vsg/vk/DeviceExtensions.cpp +++ b/src/vsg/vk/DeviceExtensions.cpp @@ -77,4 +77,6 @@ DeviceExtensions::DeviceExtensions(Device* device) device->getProcAddr(vkCmdSetStencilTestEnable, "vkCmdSetStencilTestEnableEXT"); device->getProcAddr(vkCmdSetStencilOp, "vkCmdSetStencilOpEXT"); } + + memory_budget = device->supportsApiVersion(VK_API_VERSION_1_1) && device->supportsDeviceExtension(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME); } From bd74da3585ada3242642e72a5f1b12ddf238370f Mon Sep 17 00:00:00 2001 From: maisvendoo Date: Mon, 25 May 2026 19:28:59 +0300 Subject: [PATCH 78/80] Fixed incorrect mapping of some key, such as Pause etc. --- .gitignore | 3 +- include/vsg/platform/win32/Win32_Window.h | 128 +++++++++++++--------- 2 files changed, 78 insertions(+), 53 deletions(-) diff --git a/.gitignore b/.gitignore index 5b075e1993..d6cec6ae34 100644 --- a/.gitignore +++ b/.gitignore @@ -84,4 +84,5 @@ DerivedData/ include/glslang src/vsg/CHANGES.md src/vsg/vsgTargets.cmake - +*.txt.user +*.txt.user.* diff --git a/include/vsg/platform/win32/Win32_Window.h b/include/vsg/platform/win32/Win32_Window.h index 54755cf159..cbb1ea3016 100644 --- a/include/vsg/platform/win32/Win32_Window.h +++ b/include/vsg/platform/win32/Win32_Window.h @@ -40,86 +40,86 @@ namespace vsgWin32 { uint16_t modifierMask = 0; - // see https://learn.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input#keystroke-message-flags - WORD keyFlags = HIWORD(lParam); - WORD scanCode = LOBYTE(keyFlags); // scan code - BOOL isExtendedKey = (keyFlags & KF_EXTENDED) == KF_EXTENDED; // extended-key flag, 1 if scancode has 0xE0 prefix + // Get scancode + uint16_t keyFlags = HIWORD(lParam); + uint16_t scanCode = LOBYTE(lParam); + bool isExtendedKey = (keyFlags & KF_EXTENDED) == KF_EXTENDED; if (isExtendedKey) + { scanCode = MAKEWORD(scanCode, 0xE0); + } + + // Get virtual key code + uint32_t virtualKey = static_cast(wParam); + + // Left and right modofier detection + if (virtualKey == VK_SHIFT) + { + virtualKey = (scanCode == 0x2A) ? VK_RSHIFT : VK_LSHIFT; + } + else if (virtualKey == VK_CONTROL) + { + virtualKey = isExtendedKey ? VK_RCONTROL : VK_LCONTROL; + } + else if (virtualKey == VK_MENU) + { + virtualKey = isExtendedKey ? VK_RMENU : VK_LMENU; + } - uint32_t virtualKey = ::MapVirtualKeyEx(scanCode, MAPVK_VSC_TO_VK_EX, ::GetKeyboardLayout(0)); auto itr = _vk2vsg.find(virtualKey); if (itr == _vk2vsg.end()) { - // What ever the code was in lParam should translate to a Virtual Key that we know of in _vk2vsg - // If we cannot find it, we simply return. return false; } - // This is the base-key that was pressed. (i.e., the VSG enum of the physical key pressed). keySymbol = itr->second; - // Look for any modifiers that may be active. + // Get keys state BYTE keyState[256]; - if (virtualKey == 0 || !::GetKeyboardState(keyState)) - { - // if virtualKey was undefined or we could not get the keyboard state, simply return. - return false; - } - // If any of the specific left/right modifier keys are active - // add the side-independent vsg modifier to the modifier Mask - switch (virtualKey) + if (!::GetKeyboardState(keyState)) { - case VK_LSHIFT: - case VK_RSHIFT: - modifierMask |= vsg::KeyModifier::MODKEY_Shift; - break; - - case VK_LCONTROL: - case VK_RCONTROL: - modifierMask |= vsg::KeyModifier::MODKEY_Control; - break; - - case VK_LMENU: - case VK_RMENU: - modifierMask |= vsg::KeyModifier::MODKEY_Alt; - break; - - default: - virtualKey = static_cast(wParam); - break; + return false; } - // Check if caps lock or numlock is toggled. + // Modifier's flags setting + if (keyState[VK_SHIFT] & 0x80) modifierMask |= vsg::KeyModifier::MODKEY_Shift; + if (keyState[VK_CONTROL] & 0x80) modifierMask |= vsg::KeyModifier::MODKEY_Control; + if (keyState[VK_MENU] & 0x80) modifierMask |= vsg::KeyModifier::MODKEY_Alt; if (keyState[VK_CAPITAL] & 0x01) modifierMask |= vsg::KeyModifier::MODKEY_CapsLock; if (keyState[VK_NUMLOCK] & 0x01) modifierMask |= vsg::KeyModifier::MODKEY_NumLock; - // Check if the modifier keys are down (these are non-toggle keys, so the high-order bit is relevant!) - // again, vsg only has a side-independent modifier - if (keyState[VK_LSHIFT] & 0x80) modifierMask |= vsg::KeyModifier::MODKEY_Shift; - if (keyState[VK_RSHIFT] & 0x80) modifierMask |= vsg::KeyModifier::MODKEY_Shift; - if (keyState[VK_LCONTROL] & 0x80) modifierMask |= vsg::KeyModifier::MODKEY_Control; - if (keyState[VK_RCONTROL] & 0x80) modifierMask |= vsg::KeyModifier::MODKEY_Control; - if (keyState[VK_LMENU] & 0x80) modifierMask |= vsg::KeyModifier::MODKEY_Alt; - if (keyState[VK_RMENU] & 0x80) modifierMask |= vsg::KeyModifier::MODKEY_Alt; - - // This is the final keyModifier keyModifier = static_cast(modifierMask); - // The actual keystroke is what we get after the ::ToAscii call - char asciiKey[2]; - int32_t numChars = ::ToAsciiEx(static_cast(wParam), scanCode, keyState, reinterpret_cast(asciiKey), 0, ::GetKeyboardLayout(0)); + // Get Unicode symbol + wchar_t unicodeChar[2] = {0}; + int numChars = ::ToUnicodeEx(virtualKey, scanCode, keyState, unicodeChar, 2, 0, ::GetKeyboardLayout(0)); + if (numChars == 1) { - // it is indeed an ascii character. 0-127 - modifiedKeySymbol = static_cast(asciiKey[0]); + wchar_t ch = unicodeChar[0]; + + if (ch >= L'A' && ch <= L'Z') + { + modifiedKeySymbol = static_cast(L'a' + (ch - L'A')); + } + else if (ch >= L'a' && ch <= L'z') + { + modifiedKeySymbol = static_cast(ch); + } + else if (ch >= L'0' && ch <= L'9') + { + modifiedKeySymbol = static_cast(ch); + } + else + { + modifiedKeySymbol = mapUnicodeToKeySymbol(ch); + } } else { - // otherwise treat the modifiedKeySymbol as the same as the keySymbol. modifiedKeySymbol = keySymbol; } @@ -127,6 +127,30 @@ namespace vsgWin32 } protected: + + // Helper function for Unicode cahracters + vsg::KeySymbol mapUnicodeToKeySymbol(wchar_t ch) + { + switch (ch) + { + case L' ': return vsg::KEY_Space; + case L'\t': return vsg::KEY_Tab; + case L'\r': return vsg::KEY_Return; + case L',': return vsg::KEY_Comma; + case L'.': return vsg::KEY_Period; + case L'/': return vsg::KEY_Slash; + case L';': return vsg::KEY_Semicolon; + case L'=': return vsg::KEY_Equals; + case L'-': return vsg::KEY_Minus; + case L'[': return vsg::KEY_Leftbracket; + case L']': return vsg::KEY_Rightbracket; + case L'\\': return vsg::KEY_Backslash; + case L'`': return vsg::KEY_Tilde; + case L'\'': return vsg::KEY_Quote; + default: return static_cast(ch); + } + } + VirtualKeyToKeySymbolMap _vk2vsg; }; From 94efbc8f19d07585c8135412e945108ebb8bb57b Mon Sep 17 00:00:00 2001 From: maisvendoo Date: Mon, 25 May 2026 22:13:40 +0300 Subject: [PATCH 79/80] Correct test in vstinput witch Capslock pressed and Shift for capital symbols --- include/vsg/platform/win32/Win32_Window.h | 83 ++++++++++++++++++----- 1 file changed, 66 insertions(+), 17 deletions(-) diff --git a/include/vsg/platform/win32/Win32_Window.h b/include/vsg/platform/win32/Win32_Window.h index cbb1ea3016..4a4725c671 100644 --- a/include/vsg/platform/win32/Win32_Window.h +++ b/include/vsg/platform/win32/Win32_Window.h @@ -53,7 +53,7 @@ namespace vsgWin32 // Get virtual key code uint32_t virtualKey = static_cast(wParam); - // Left and right modofier detection + // Left and right modifier detection if (virtualKey == VK_SHIFT) { virtualKey = (scanCode == 0x2A) ? VK_RSHIFT : VK_LSHIFT; @@ -101,22 +101,7 @@ namespace vsgWin32 { wchar_t ch = unicodeChar[0]; - if (ch >= L'A' && ch <= L'Z') - { - modifiedKeySymbol = static_cast(L'a' + (ch - L'A')); - } - else if (ch >= L'a' && ch <= L'z') - { - modifiedKeySymbol = static_cast(ch); - } - else if (ch >= L'0' && ch <= L'9') - { - modifiedKeySymbol = static_cast(ch); - } - else - { - modifiedKeySymbol = mapUnicodeToKeySymbol(ch); - } + modifiedKeySymbol = mapCharToKeySymbol(ch); } else { @@ -128,6 +113,70 @@ namespace vsgWin32 protected: + vsg::KeySymbol mapCharToKeySymbol(wchar_t ch) + { + // Letters + if (ch >= L'A' && ch <= L'Z') + { + return static_cast(ch); // Capital + } + if (ch >= L'a' && ch <= L'z') + { + return static_cast(ch); + } + + // Digits + if (ch >= L'0' && ch <= L'9') + { + return static_cast(ch); + } + + // Special characters (with and without Shift) + switch (ch) + { + case L'!': return vsg::KEY_Exclaim; + case L'\"': return vsg::KEY_Quotedbl; + case L'#': return vsg::KEY_Hash; + case L'$': return vsg::KEY_Dollar; + case L'%': return vsg::KEY_Percent; + case L'&': return vsg::KEY_Ampersand; + case L'\'': return vsg::KEY_Quote; + case L'(': return vsg::KEY_Leftparen; + case L')': return vsg::KEY_Rightparen; + case L'*': return vsg::KEY_Asterisk; + case L'+': return vsg::KEY_Plus; + case L',': return vsg::KEY_Comma; + case L'-': return vsg::KEY_Minus; + case L'.': return vsg::KEY_Period; + case L'/': return vsg::KEY_Slash; + case L':': return vsg::KEY_Colon; + case L';': return vsg::KEY_Semicolon; + case L'<': return vsg::KEY_Less; + case L'=': return vsg::KEY_Equals; + case L'>': return vsg::KEY_Greater; + case L'?': return vsg::KEY_Question; + case L'@': return vsg::KEY_At; + case L'[': return vsg::KEY_Leftbracket; + case L'\\': return vsg::KEY_Backslash; + case L']': return vsg::KEY_Rightbracket; + case L'^': return vsg::KEY_Caret; + case L'_': return vsg::KEY_Underscore; + case L'`': return vsg::KEY_Backquote; + case L'{': return vsg::KEY_Leftcurlybracket; + case L'|': return vsg::KEY_Verticalslash; + case L'}': return vsg::KEY_Rightcurlybracket; + case L'~': return vsg::KEY_Tilde; + + // Whitespace and control characters + case L' ': return vsg::KEY_Space; + case L'\t': return vsg::KEY_Tab; + case L'\r': return vsg::KEY_Return; + } + + // Return for other non-ASCII + return mapUnicodeToKeySymbol(ch); + } + // Helper function for Unicode cahracters vsg::KeySymbol mapUnicodeToKeySymbol(wchar_t ch) { From 07ad76332faed19d4b5fae31d06ff90262d31f0d Mon Sep 17 00:00:00 2001 From: maisvendoo Date: Mon, 25 May 2026 23:32:10 +0300 Subject: [PATCH 80/80] Simple conversion to vsg::KeySymbol for ascii --- include/vsg/platform/win32/Win32_Window.h | 77 +---------------------- 1 file changed, 1 insertion(+), 76 deletions(-) diff --git a/include/vsg/platform/win32/Win32_Window.h b/include/vsg/platform/win32/Win32_Window.h index 4a4725c671..62f8aa5ca4 100644 --- a/include/vsg/platform/win32/Win32_Window.h +++ b/include/vsg/platform/win32/Win32_Window.h @@ -115,89 +115,14 @@ namespace vsgWin32 vsg::KeySymbol mapCharToKeySymbol(wchar_t ch) { - // Letters - if (ch >= L'A' && ch <= L'Z') - { - return static_cast(ch); // Capital - } - if (ch >= L'a' && ch <= L'z') - { - return static_cast(ch); - } - - // Digits - if (ch >= L'0' && ch <= L'9') - { - return static_cast(ch); - } - // Special characters (with and without Shift) switch (ch) { - case L'!': return vsg::KEY_Exclaim; - case L'\"': return vsg::KEY_Quotedbl; - case L'#': return vsg::KEY_Hash; - case L'$': return vsg::KEY_Dollar; - case L'%': return vsg::KEY_Percent; - case L'&': return vsg::KEY_Ampersand; - case L'\'': return vsg::KEY_Quote; - case L'(': return vsg::KEY_Leftparen; - case L')': return vsg::KEY_Rightparen; - case L'*': return vsg::KEY_Asterisk; - case L'+': return vsg::KEY_Plus; - case L',': return vsg::KEY_Comma; - case L'-': return vsg::KEY_Minus; - case L'.': return vsg::KEY_Period; - case L'/': return vsg::KEY_Slash; - case L':': return vsg::KEY_Colon; - case L';': return vsg::KEY_Semicolon; - case L'<': return vsg::KEY_Less; - case L'=': return vsg::KEY_Equals; - case L'>': return vsg::KEY_Greater; - case L'?': return vsg::KEY_Question; - case L'@': return vsg::KEY_At; - case L'[': return vsg::KEY_Leftbracket; - case L'\\': return vsg::KEY_Backslash; - case L']': return vsg::KEY_Rightbracket; - case L'^': return vsg::KEY_Caret; - case L'_': return vsg::KEY_Underscore; - case L'`': return vsg::KEY_Backquote; - case L'{': return vsg::KEY_Leftcurlybracket; - case L'|': return vsg::KEY_Verticalslash; - case L'}': return vsg::KEY_Rightcurlybracket; - case L'~': return vsg::KEY_Tilde; - - // Whitespace and control characters - case L' ': return vsg::KEY_Space; case L'\t': return vsg::KEY_Tab; case L'\r': return vsg::KEY_Return; } - // Return for other non-ASCII - return mapUnicodeToKeySymbol(ch); - } - - // Helper function for Unicode cahracters - vsg::KeySymbol mapUnicodeToKeySymbol(wchar_t ch) - { - switch (ch) - { - case L' ': return vsg::KEY_Space; - case L'\t': return vsg::KEY_Tab; - case L'\r': return vsg::KEY_Return; - case L',': return vsg::KEY_Comma; - case L'.': return vsg::KEY_Period; - case L'/': return vsg::KEY_Slash; - case L';': return vsg::KEY_Semicolon; - case L'=': return vsg::KEY_Equals; - case L'-': return vsg::KEY_Minus; - case L'[': return vsg::KEY_Leftbracket; - case L']': return vsg::KEY_Rightbracket; - case L'\\': return vsg::KEY_Backslash; - case L'`': return vsg::KEY_Tilde; - case L'\'': return vsg::KEY_Quote; - default: return static_cast(ch); - } + return static_cast(ch); } VirtualKeyToKeySymbolMap _vk2vsg;