From a2d2e9d7b589026ebdadb30fe21913ee869fd8ae Mon Sep 17 00:00:00 2001 From: Fletterio Date: Wed, 23 Jul 2025 23:05:49 -0300 Subject: [PATCH 01/20] Fix so that code can run in examples branch --- include/nbl/builtin/hlsl/cpp_compat/matrix.hlsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/nbl/builtin/hlsl/cpp_compat/matrix.hlsl b/include/nbl/builtin/hlsl/cpp_compat/matrix.hlsl index b1d33f097b..8f23e790e8 100644 --- a/include/nbl/builtin/hlsl/cpp_compat/matrix.hlsl +++ b/include/nbl/builtin/hlsl/cpp_compat/matrix.hlsl @@ -34,7 +34,7 @@ struct matrix final : private glm::mat template inline friend matrix mul(matrix const& lhs, matrix const& rhs) { - return matrix(glm::operator*(reinterpret_cast(rhs), reinterpret_cast::Base const&>(lhs))); + return matrix(glm::operator*(reinterpret_cast::Base const&>(rhs), reinterpret_cast(lhs))); } inline friend vector mul(matrix const& lhs, vector const& rhs) { From b12d95949a97856edecef3bd4a9be01655024346 Mon Sep 17 00:00:00 2001 From: Erfan Ahmadi Date: Fri, 8 Aug 2025 08:58:35 +0400 Subject: [PATCH 02/20] update examples --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index 06d839d6c3..e61e389ed7 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 06d839d6c3185fd66ad95602ab50d61f67fa4c7c +Subproject commit e61e389ed763f9d9b6b44b075de00baa220763a5 From 1197852b4266ac5ef90eabe645841c7bf7a32086 Mon Sep 17 00:00:00 2001 From: Erfan Ahmadi Date: Wed, 3 Sep 2025 09:23:56 +0400 Subject: [PATCH 03/20] update examples --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index 0ed564e5c8..888bcb1f76 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 0ed564e5c88ba90ca5859036f33ea5cb241c3443 +Subproject commit 888bcb1f7635950e2dcf0c796726cb472e704bca From f334f90c1fc3b23d99f35e4cdf5227560a296954 Mon Sep 17 00:00:00 2001 From: Arkadiusz Lachowicz Date: Mon, 15 Sep 2025 16:54:19 +0200 Subject: [PATCH 04/20] ieee754::flipSign update, flipSign_helper::FloatingPoint fix --- include/nbl/builtin/hlsl/ieee754.hlsl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/nbl/builtin/hlsl/ieee754.hlsl b/include/nbl/builtin/hlsl/ieee754.hlsl index 6bdfcf2514..0fa027a82e 100644 --- a/include/nbl/builtin/hlsl/ieee754.hlsl +++ b/include/nbl/builtin/hlsl/ieee754.hlsl @@ -159,7 +159,7 @@ struct flipSign_helper(asUint ^ spirv::select(AsUint(0ull), ieee754::traits::signMask, flip)); + return bit_cast(asUint ^ spirv::select(flip, ieee754::traits::signMask, AsUint(0ull))); #else return bit_cast(asUint ^ (flip ? ieee754::traits::signMask : AsUint(0ull))); #endif @@ -205,8 +205,8 @@ struct flipSign_helper -NBL_CONSTEXPR_INLINE_FUNC T flipSign(T val, U flip) +template +NBL_CONSTEXPR_INLINE_FUNC T flipSign(T val, U flip = true) { return impl::flipSign_helper::__call(val, flip); } From 0e84d335d8b338d77a5a5cd3c7955065bc874e01 Mon Sep 17 00:00:00 2001 From: Fletterio Date: Mon, 15 Sep 2025 13:32:17 -0300 Subject: [PATCH 05/20] Change examples submodule --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index 888bcb1f76..8a02379810 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 888bcb1f7635950e2dcf0c796726cb472e704bca +Subproject commit 8a023798107556c5441b6695a91a12ef8d4b90da From 0adfa1e01c3d8190cf4cf168fd0a2f9c33abc56c Mon Sep 17 00:00:00 2001 From: Fletterio Date: Mon, 15 Sep 2025 21:10:30 -0300 Subject: [PATCH 06/20] Update submodule pointer --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index 8a02379810..73303836b8 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 8a023798107556c5441b6695a91a12ef8d4b90da +Subproject commit 73303836b839dbd1667ada6f930cadc792569537 From 9bd7f3b56b4d510e2bdd63e7ab022f9ba4659c48 Mon Sep 17 00:00:00 2001 From: Arkadiusz Lachowicz <34793522+AnastaZIuk@users.noreply.github.com> Date: Sat, 20 Sep 2025 20:04:06 +0200 Subject: [PATCH 07/20] Update CMakePresets.json, forgot to commit and push new n4ce preset --- CMakePresets.json | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/CMakePresets.json b/CMakePresets.json index e91c46d8e9..b755976bfa 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -295,7 +295,31 @@ "CMAKE_BUILD_TYPE": "Debug", "CMAKE_EXPORT_COMPILE_COMMANDS": "ON" } - } + }, + { + "name": "n4ce-configure-windows-msvc", + "hidden": false, + "binaryDir": "build/production/n4ce", + "cacheVariables": { + "NBL_STATIC_BUILD": "OFF", + "CMAKE_SUPPRESS_REGENERATION": "OFF", + "NBL_COMPILER_DYNAMIC_RUNTIME": "ON", + "NBL_EMBED_BUILTIN_RESOURCES": "ON", + "NBL_UPDATE_GIT_SUBMODULE": "OFF", + "NBL_COMPILE_WITH_CUDA": "OFF", + "NBL_BUILD_OPTIX": "OFF", + "NBL_BUILD_MITSUBA_LOADER": "OFF", + "NBL_BUILD_RADEON_RAYS": "OFF", + "_NBL_COMPILE_WITH_OPEN_EXR_": "ON", + "NBL_EXPLICIT_MODULE_LOAD_LOG": "ON", + "NBL_CPACK_NO_BUILD_DIRECTORY_MODULES": "ON", + "GIT_FAIL_IF_NONZERO_EXIT": "OFF" + }, + "displayName": "[N4CE]: Dynamic library target, Visual Studio 17 2022 generator, MSVC v143 toolset", + "description": "Configure as dynamic library with Visual Studio 17 2022 generator and MSVC v143 toolset", + "generator": "Visual Studio 17 2022", + "toolset": "v143" + } ], "buildPresets": [ { From 824a55e3609083290de76ccc79e4c2c3a3ffdfe0 Mon Sep 17 00:00:00 2001 From: Erfan Ahmadi Date: Fri, 3 Oct 2025 11:11:15 +0400 Subject: [PATCH 08/20] update examples --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index 73303836b8..b232c218aa 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 73303836b839dbd1667ada6f930cadc792569537 +Subproject commit b232c218aaba0e6bf614cc59aaa65bd50312dc60 From f9cfa1e394ad22fee960d25f19b31559af7d1a5e Mon Sep 17 00:00:00 2001 From: Arkadiusz Lachowicz Date: Sat, 11 Oct 2025 10:29:51 +0200 Subject: [PATCH 09/20] asset::IShaderCompiler::E_DEBUG_INFO_FLAGS::EDIF_NONE for NSC --- tools/nsc/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/nsc/main.cpp b/tools/nsc/main.cpp index c4ce43b326..0a532916b4 100644 --- a/tools/nsc/main.cpp +++ b/tools/nsc/main.cpp @@ -145,6 +145,7 @@ class ShaderCompiler final : public system::IApplicationFramework return strings; }; + // TODO: replace this parse crap with argparse or something auto findOutputFlag = [&](const std::string_view& outputFlag) { return std::find_if(m_arguments.begin(), m_arguments.end(), [&](const std::string& argument) @@ -299,7 +300,7 @@ class ShaderCompiler final : public system::IApplicationFramework options.preprocessorOptions.sourceIdentifier = sourceIdentifier; options.preprocessorOptions.logger = m_logger.get(); - options.debugInfoFlags = core::bitflag(asset::IShaderCompiler::E_DEBUG_INFO_FLAGS::EDIF_TOOL_BIT); + options.debugInfoFlags = core::bitflag(asset::IShaderCompiler::E_DEBUG_INFO_FLAGS::EDIF_NONE); // pass explicitly to CLI if you want them options.dxcOptions = std::span(m_arguments); auto includeFinder = make_smart_refctd_ptr(smart_refctd_ptr(m_system)); From 029083dab7a3e43d3f397d4e9c233fd9232ed9cc Mon Sep 17 00:00:00 2001 From: Erfan Ahmadi Date: Mon, 13 Oct 2025 12:09:57 +0400 Subject: [PATCH 10/20] add debug info flags to ILogicalDevice::compileShader --- include/nbl/video/ILogicalDevice.h | 1 + src/nbl/video/ILogicalDevice.cpp | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/nbl/video/ILogicalDevice.h b/include/nbl/video/ILogicalDevice.h index 180342e2d4..a269be082e 100644 --- a/include/nbl/video/ILogicalDevice.h +++ b/include/nbl/video/ILogicalDevice.h @@ -831,6 +831,7 @@ class NBL_API2 ILogicalDevice : public core::IReferenceCounted, public IDeviceMe asset::IShaderCompiler::CCache* writeCache = nullptr; std::span extraDefines = {}; hlsl::ShaderStage stage = hlsl::ShaderStage::ESS_ALL_OR_LIBRARY; + core::bitflag debugInfoFlags = asset::IShaderCompiler::E_DEBUG_INFO_FLAGS::EDIF_NONE; }; core::smart_refctd_ptr compileShader(const SShaderCreationParameters& creationParams); diff --git a/src/nbl/video/ILogicalDevice.cpp b/src/nbl/video/ILogicalDevice.cpp index 7c3f5dbb81..81f880cfeb 100644 --- a/src/nbl/video/ILogicalDevice.cpp +++ b/src/nbl/video/ILogicalDevice.cpp @@ -360,9 +360,7 @@ core::smart_refctd_ptr ILogicalDevice::compileShader(const SShad commonCompileOptions.preprocessorOptions.extraDefines = creationParams.extraDefines; commonCompileOptions.stage = creationParams.stage; - commonCompileOptions.debugInfoFlags = - asset::IShaderCompiler::E_DEBUG_INFO_FLAGS::EDIF_SOURCE_BIT | - asset::IShaderCompiler::E_DEBUG_INFO_FLAGS::EDIF_TOOL_BIT; + commonCompileOptions.debugInfoFlags = creationParams.debugInfoFlags; commonCompileOptions.spirvOptimizer = creationParams.optimizer; commonCompileOptions.preprocessorOptions.targetSpirvVersion = m_physicalDevice->getLimits().spirvVersion; From db5156a247eb8992c575d2b6643b77033fde64d2 Mon Sep 17 00:00:00 2001 From: Fletterio Date: Tue, 14 Oct 2025 12:07:15 -0300 Subject: [PATCH 11/20] Point submodule to geotex branch --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index 73303836b8..1c128978a1 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 73303836b839dbd1667ada6f930cadc792569537 +Subproject commit 1c128978a114e1f4edd125d63e7c50d0558a8f7f From 86c8426e5a1d9ba7587eea87079c258506a89fb9 Mon Sep 17 00:00:00 2001 From: Erfan Ahmadi Date: Wed, 15 Oct 2025 09:26:55 +0400 Subject: [PATCH 12/20] IUtilities Allow for null (0 sized) staging buffers for download/upload --- include/nbl/video/utilities/IUtilities.h | 18 ++++++++++++++++-- src/nbl/video/utilities/IUtilities.cpp | 10 ++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/nbl/video/utilities/IUtilities.h b/include/nbl/video/utilities/IUtilities.h index 7817df8d23..f52d5d36ef 100644 --- a/include/nbl/video/utilities/IUtilities.h +++ b/include/nbl/video/utilities/IUtilities.h @@ -37,8 +37,10 @@ class NBL_API2 IUtilities : public core::IReferenceCounted , m_allocationAlignment(allocationAlignment) , m_allocationAlignmentForBufferImageCopy(allocationAlignmentForBufferImageCopy) { - m_defaultDownloadBuffer->getBuffer()->setObjectDebugName(("Default Download Buffer of Utilities "+std::to_string(ptrdiff_t(this))).c_str()); - m_defaultUploadBuffer->getBuffer()->setObjectDebugName(("Default Upload Buffer of Utilities "+std::to_string(ptrdiff_t(this))).c_str()); + if (m_defaultDownloadBuffer) + m_defaultDownloadBuffer->getBuffer()->setObjectDebugName(("Default Download Buffer of Utilities "+std::to_string(ptrdiff_t(this))).c_str()); + if (m_defaultUploadBuffer) + m_defaultUploadBuffer->getBuffer()->setObjectDebugName(("Default Upload Buffer of Utilities "+std::to_string(ptrdiff_t(this))).c_str()); } IUtilities() = delete; @@ -94,6 +96,7 @@ class NBL_API2 IUtilities : public core::IReferenceCounted core::smart_refctd_ptr > defaultDownloadBuffer = nullptr; // Try Create Download Buffer + if (downstreamSize > 0u) { IGPUBuffer::SCreationParams streamingBufferCreationParams = {}; streamingBufferCreationParams.size = downstreamSize; @@ -127,6 +130,7 @@ class NBL_API2 IUtilities : public core::IReferenceCounted defaultDownloadBuffer = core::make_smart_refctd_ptr>(asset::SBufferRange{0ull,downstreamSize,std::move(buffer)},maxStreamingBufferAllocationAlignment,minStreamingBufferAllocationSize); } // Try Create Upload Buffer + if (upstreamSize > 0u) { IGPUBuffer::SCreationParams streamingBufferCreationParams = {}; streamingBufferCreationParams.size = upstreamSize; @@ -374,6 +378,11 @@ class NBL_API2 IUtilities : public core::IReferenceCounted //! * data must not be nullptr inline bool updateBufferRangeViaStagingBuffer(SIntendedSubmitInfo& nextSubmit, const asset::SBufferRange& bufferRange, IUpstreamingDataProducer& callback) { + if (!m_defaultUploadBuffer) + { + m_logger.log("no staging buffer available for upload. check `upstreamSize` passed to `IUtilities::create`",system::ILogger::ELL_ERROR); + return false; + } if (!bufferRange.isValid() || !bufferRange.buffer->getCreationParams().usage.hasFlags(asset::IBuffer::EUF_TRANSFER_DST_BIT)) { m_logger.log("Invalid `bufferRange` or buffer has no `EUF_TRANSFER_DST_BIT` usage flag, cannot `updateBufferRangeViaStagingBuffer`!", system::ILogger::ELL_ERROR); @@ -623,6 +632,11 @@ class NBL_API2 IUtilities : public core::IReferenceCounted template requires std::is_same_v, SIntendedSubmitInfo> inline bool downloadBufferRangeViaStagingBuffer(const std::function& consumeCallback, IntendedSubmitInfo&& nextSubmit, const asset::SBufferRange& srcBufferRange) { + if (!m_defaultDownloadBuffer) + { + m_logger.log("no staging buffer available for download. check `downstreamSize` passed to `IUtilities::create`",system::ILogger::ELL_ERROR); + return false; + } if (!srcBufferRange.isValid() || !srcBufferRange.buffer->getCreationParams().usage.hasFlags(asset::IBuffer::EUF_TRANSFER_SRC_BIT)) { m_logger.log("Invalid `srcBufferRange` or buffer has no `EUF_TRANSFER_SRC_BIT` usage flag, cannot `downloadBufferRangeViaStagingBuffer`!",system::ILogger::ELL_ERROR); diff --git a/src/nbl/video/utilities/IUtilities.cpp b/src/nbl/video/utilities/IUtilities.cpp index 46bda8a227..f6db104aa2 100644 --- a/src/nbl/video/utilities/IUtilities.cpp +++ b/src/nbl/video/utilities/IUtilities.cpp @@ -11,6 +11,11 @@ bool IUtilities::updateImageViaStagingBuffer( const std::span regions ) { + if (!m_defaultUploadBuffer) + { + m_logger.log("no staging buffer available for upload. check `upstreamSize` passed to `IUtilities::create`",system::ILogger::ELL_ERROR); + return false; + } auto* scratch = commonTransferValidation(intendedNextSubmit); if (!scratch) return false; @@ -164,6 +169,11 @@ bool IUtilities::downloadImageViaStagingBuffer( void* dest, const std::span regions ) { + if (!m_defaultDownloadBuffer) + { + m_logger.log("no staging buffer available for download. check `downstreamSize` passed to `IUtilities::create`",system::ILogger::ELL_ERROR); + return false; + } if (regions.empty()) return false; From 6e13596ed9b136b236e202ec4273b55a99efc9b8 Mon Sep 17 00:00:00 2001 From: Erfan Ahmadi Date: Thu, 6 Nov 2025 22:37:31 +0400 Subject: [PATCH 13/20] Cmake "NBL_SKIP_BUILD_OPTIONS_VALIDATION": "ON" --- CMakePresets.json | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakePresets.json b/CMakePresets.json index b755976bfa..269ecb6dcc 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -302,6 +302,7 @@ "binaryDir": "build/production/n4ce", "cacheVariables": { "NBL_STATIC_BUILD": "OFF", + "NBL_SKIP_BUILD_OPTIONS_VALIDATION": "ON", "CMAKE_SUPPRESS_REGENERATION": "OFF", "NBL_COMPILER_DYNAMIC_RUNTIME": "ON", "NBL_EMBED_BUILTIN_RESOURCES": "ON", From fb6214543fcdc56096fe45174d4d647f05d7e2de Mon Sep 17 00:00:00 2001 From: Erfan Ahmadi Date: Tue, 11 Nov 2025 10:33:50 +0400 Subject: [PATCH 14/20] Small MonoDeviceApp fix and update examples --- examples_tests | 2 +- include/nbl/application_templates/MonoDeviceApplication.hpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples_tests b/examples_tests index 1c128978a1..57912507f4 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 1c128978a114e1f4edd125d63e7c50d0558a8f7f +Subproject commit 57912507f4d9fac493c4127ebf9ba9969449eabe diff --git a/include/nbl/application_templates/MonoDeviceApplication.hpp b/include/nbl/application_templates/MonoDeviceApplication.hpp index a3a169d7b7..c7a94fe332 100644 --- a/include/nbl/application_templates/MonoDeviceApplication.hpp +++ b/include/nbl/application_templates/MonoDeviceApplication.hpp @@ -24,7 +24,8 @@ class MonoDeviceApplication : public virtual MonoSystemMonoLoggerApplication virtual bool onAppTerminated() override { // break the circular references from queues tracking submit resources - m_device->waitIdle(); + if (m_device) + m_device->waitIdle(); m_device = nullptr; m_api = nullptr; return base_t::onAppTerminated(); From f444ea3062b127449223508357932ad6e060c544 Mon Sep 17 00:00:00 2001 From: Erfan Ahmadi Date: Tue, 11 Nov 2025 10:34:13 +0400 Subject: [PATCH 15/20] update examples --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index 57912507f4..3820eb17c3 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 57912507f4d9fac493c4127ebf9ba9969449eabe +Subproject commit 3820eb17c371626f189b242f1b0bdb36abb7ee85 From 92e7d1474cd1c1e781431eb088d0df7c7e46a3ba Mon Sep 17 00:00:00 2001 From: Arkadiusz Lachowicz Date: Wed, 12 Nov 2025 13:47:31 +0100 Subject: [PATCH 16/20] Update Vulkan-Headers to 1.4.332 --- 3rdparty/Vulkan-Headers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/Vulkan-Headers b/3rdparty/Vulkan-Headers index 33d7f51258..3dda5a1a87 160000 --- a/3rdparty/Vulkan-Headers +++ b/3rdparty/Vulkan-Headers @@ -1 +1 @@ -Subproject commit 33d7f512583b8de44d1b6384aa1cf482f92e53e9 +Subproject commit 3dda5a1a87b62fdf3baf4680edc41c00e85a7a22 From 542e0bf10bbe747f7dec942634e74df24e66581d Mon Sep 17 00:00:00 2001 From: Arkadiusz Lachowicz Date: Wed, 12 Nov 2025 13:50:56 +0100 Subject: [PATCH 17/20] update 3rdparty/Vulkan-Tools] --- 3rdparty/Vulkan-Tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/Vulkan-Tools b/3rdparty/Vulkan-Tools index 761e7bf273..013d17f10e 160000 --- a/3rdparty/Vulkan-Tools +++ b/3rdparty/Vulkan-Tools @@ -1 +1 @@ -Subproject commit 761e7bf2736f3ad326fdfc1b3c1543f4e669fd5c +Subproject commit 013d17f10ec730db20a70f2ead677b80bb01e35e From de16092279fbb52238437182880d12a861227187 Mon Sep 17 00:00:00 2001 From: Arkadiusz Lachowicz Date: Wed, 12 Nov 2025 20:37:28 +0100 Subject: [PATCH 18/20] update smoke test to cover n4ce case, update 3rdparty/SPIRV-Tools submodule --- 3rdparty/Vulkan-Tools | 2 +- smoke/CMakeLists.txt | 1 + smoke/main.cpp | 67 +++++++++++++++++++++++++++++++++++-------- 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/3rdparty/Vulkan-Tools b/3rdparty/Vulkan-Tools index 013d17f10e..4b6f7101c1 160000 --- a/3rdparty/Vulkan-Tools +++ b/3rdparty/Vulkan-Tools @@ -1 +1 @@ -Subproject commit 013d17f10ec730db20a70f2ead677b80bb01e35e +Subproject commit 4b6f7101c15e09a8931f2f81c97146d0dfe68bc5 diff --git a/smoke/CMakeLists.txt b/smoke/CMakeLists.txt index a44374714d..c560e56a0f 100644 --- a/smoke/CMakeLists.txt +++ b/smoke/CMakeLists.txt @@ -28,6 +28,7 @@ find_package(Nabla REQUIRED CONFIG add_executable(smoke main.cpp pch.hpp cdb.ps1) target_link_libraries(smoke PRIVATE Nabla::Nabla) +target_compile_definitions(smoke PRIVATE _AFXDLL) target_precompile_headers(smoke PRIVATE pch.hpp) set(CMAKE_CTEST_ARGUMENTS --verbose) diff --git a/smoke/main.cpp b/smoke/main.cpp index 2b1863d404..530b29adae 100644 --- a/smoke/main.cpp +++ b/smoke/main.cpp @@ -1,3 +1,5 @@ +#include + #define ENABLE_SMOKE using namespace nbl; @@ -36,7 +38,25 @@ class Smoke final : public system::IApplicationFramework return false; } - exportGpuProfiles(); + if (!AfxWinInit(GetModuleHandle(nullptr), nullptr, GetCommandLineA(), 0)) + { + std::cerr << "[ERROR]: Could not init AFX, terminating!\n"; + return false; + } + + try { + createAfxDummyWindow(320, 240, nullptr, _T("Dummy 1")); + exportGpuProfiles(); + createAfxDummyWindow(320, 240, nullptr, _T("Dummy 2")); + } + catch (const std::exception& e) { + std::cerr << "[ERROR]: " << e.what() << '\n'; + return false; + } + catch (...) { + std::cerr << "[ERROR]: Unknown exception!\n"; + return false; + } return true; } @@ -44,37 +64,60 @@ class Smoke final : public system::IApplicationFramework void workLoopBody() override {} bool keepRunning() override { return false; } + bool onAppTerminated() override + { + AfxWinTerm(); + return true; + } + private: static void exportGpuProfiles() { - std::string arg2 = "-o"; - std::string buf; - std::string arg1; - std::string arg3; + std::string buf, arg1, arg2 = "-o", arg3; for (size_t i = 0;; i++) { - auto stringifiedIndex = std::to_string(i); - arg1 = "--json=" + stringifiedIndex; - arg3 = "device_" + stringifiedIndex + ".json"; - std::array args = { arg1.data(), arg2.data(), arg3.data() }; + auto six = std::to_string(i); + arg1 = "--json=" + six; + arg3 = "device_" + six + ".json"; + auto args = std::to_array({ arg1.data(), arg2.data(), arg3.data()}); int code = nbl::video::vulkaninfo(args); if (code != 0) break; - // print out file content std::ifstream input(arg3); while (std::getline(input, buf)) - { std::cout << buf << "\n"; - } std::cout << "\n\n"; } } + + static bool createAfxDummyWindow(int w, int h, HWND parent, LPCTSTR windowName) + { + CWnd wnd; + LPCTSTR cls = AfxRegisterWndClass(0, ::LoadCursor(nullptr, IDC_ARROW)); + if (!cls) return false; + + if (!wnd.CreateEx(0, cls, windowName, WS_POPUP | WS_VISIBLE, 0, 0, w, h, parent, nullptr)) + return false; + + MSG msg {}; + const ULONGLONG end = GetTickCount64() + 1000; + while (GetTickCount64() < end) { + while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + Sleep(1); + } + + wnd.DestroyWindow(); + return true; + } }; NBL_MAIN_FUNC(Smoke) From f08a43cba435fada5c2278c8420da9ec30000324 Mon Sep 17 00:00:00 2001 From: Arkadiusz Lachowicz Date: Thu, 13 Nov 2025 12:21:22 +0100 Subject: [PATCH 19/20] add include/nbl/system/json.h and wipe nlohmann/json_fwd.hpp from public header interface --- 3rdparty/CMakeLists.txt | 3 - include/nbl/asset/utils/IShaderCompiler.h | 18 +- include/nbl/system/json.h | 15 ++ src/nbl/asset/utils/IShaderCompiler.cpp | 249 +++++++++++++++++- .../utils/shaderCompiler_serialization.h | 196 -------------- 5 files changed, 269 insertions(+), 212 deletions(-) create mode 100644 include/nbl/system/json.h delete mode 100644 src/nbl/asset/utils/shaderCompiler_serialization.h diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index 4ee86dcfcd..167419bb22 100755 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -543,9 +543,6 @@ nbl_install_dir(imath/src/Imath) nbl_install_file(blake/c/blake3.h) -nbl_install_file_spec(nlohmann_json/include/nlohmann/json_fwd.hpp nlohmann) -nbl_install_file_spec(nlohmann_json/include/nlohmann/detail/abi_macros.hpp nlohmann/detail) - nbl_install_dir(boost/superproject/libs/preprocessor/include/boost) nbl_install_file_spec(renderdoc/renderdoc_app.h renderdoc) diff --git a/include/nbl/asset/utils/IShaderCompiler.h b/include/nbl/asset/utils/IShaderCompiler.h index 30d37f36c7..2052174d92 100644 --- a/include/nbl/asset/utils/IShaderCompiler.h +++ b/include/nbl/asset/utils/IShaderCompiler.h @@ -12,9 +12,7 @@ #include "nbl/asset/IShader.h" #include "nbl/asset/utils/ISPIRVOptimizer.h" - -// Less leakage than "nlohmann/json.hpp" only forward declarations -#include "nlohmann/json_fwd.hpp" +#include "nbl/system/json.h" #include "nbl/builtin/hlsl/enums.hlsl" @@ -111,11 +109,10 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted // struct SMacroDefinition { - friend void to_json(nlohmann::json&, const SMacroDefinition&); - friend void from_json(const nlohmann::json&, SMacroDefinition&); - std::string_view identifier; std::string_view definition; + + friend struct system::json::adl_serializer; }; // @@ -216,9 +213,8 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted inline SPreprocessingDependency() {} private: - friend void to_json(nlohmann::json& j, const SEntry::SPreprocessingDependency& dependency); - friend void from_json(const nlohmann::json& j, SEntry::SPreprocessingDependency& dependency); friend class CCache; + friend struct system::json::adl_serializer; // path or identifier system::path requestingSourceDir = ""; @@ -252,8 +248,7 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted friend class SCompilerArgs; friend class SEntry; friend class CCache; - friend void to_json(nlohmann::json&, const SPreprocessorArgs&); - friend void from_json(const nlohmann::json&, SPreprocessorArgs&); + friend struct system::json::adl_serializer; // Default constructor needed for json serialization of SCompilerArgs SPreprocessorArgs() {}; @@ -295,8 +290,7 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted private: friend class SEntry; friend class CCache; - friend void to_json(nlohmann::json&, const SCompilerArgs&); - friend void from_json(const nlohmann::json&, SCompilerArgs&); + friend struct system::json::adl_serializer; // Default constructor needed for json serialization of SEntry SCompilerArgs() {} diff --git a/include/nbl/system/json.h b/include/nbl/system/json.h new file mode 100644 index 0000000000..1fdd0abf47 --- /dev/null +++ b/include/nbl/system/json.h @@ -0,0 +1,15 @@ +#ifndef _NBL_SYSTEM_JSON_H_INCLUDED_ +#define _NBL_SYSTEM_JSON_H_INCLUDED_ + +namespace nbl::system::json { + template struct adl_serializer; +} + +#define NBL_JSON_IMPL_BIND_ADL_SERIALIZER(T) \ +namespace nlohmann { \ + template<> \ + struct adl_serializer \ + : T {}; \ +} + +#endif // _NBL_SYSTEM_JSON_H_INCLUDED_ \ No newline at end of file diff --git a/src/nbl/asset/utils/IShaderCompiler.cpp b/src/nbl/asset/utils/IShaderCompiler.cpp index e60bf31b5c..982f78ef6d 100644 --- a/src/nbl/asset/utils/IShaderCompiler.cpp +++ b/src/nbl/asset/utils/IShaderCompiler.cpp @@ -3,7 +3,6 @@ // For conditions of distribution and use, see copyright notice in nabla.h #include "nbl/asset/utils/IShaderCompiler.h" #include "nbl/asset/utils/shadercUtils.h" -#include "nbl/asset/utils/shaderCompiler_serialization.h" #include #include @@ -11,10 +10,258 @@ #include #include +#include "nlohmann/json.hpp" + +using json = nlohmann::json; +using SEntry = nbl::asset::IShaderCompiler::CCache::SEntry; using namespace nbl; using namespace nbl::asset; +// -> serialization +// SMacroData, simple container used in SPreprocessorArgs +namespace nbl::system::json { + template<> + struct adl_serializer + { + using value_t = IShaderCompiler::SMacroDefinition; + + static inline void to_json(::json& j, const value_t& p) + { + j = ::json{ + { "identifier", p.identifier }, + { "definition", p.definition }, + }; + } + + static inline void from_json(const ::json& j, value_t& p) + { + j.at("identifier").get_to(p.identifier); + j.at("definition").get_to(p.definition); + } + }; +} +NBL_JSON_IMPL_BIND_ADL_SERIALIZER(::nbl::system::json::adl_serializer) + +// SPreprocessorData, holds serialized info for Preprocessor options used during compilation +namespace nbl::system::json { + template<> + struct adl_serializer + { + using value_t = SEntry::SPreprocessorArgs; + + static inline void to_json(::json& j, const value_t& p) + { + j = ::json{ + { "sourceIdentifier", p.sourceIdentifier }, + { "extraDefines", p.extraDefines}, + }; + } + + static inline void from_json(const ::json& j, value_t& p) + { + j.at("sourceIdentifier").get_to(p.sourceIdentifier); + j.at("extraDefines").get_to(p.extraDefines); + } + }; +} +NBL_JSON_IMPL_BIND_ADL_SERIALIZER(::nbl::system::json::adl_serializer) + +// Optimizer pass has its own method for easier vector serialization +namespace nbl::system::json { + template<> + struct adl_serializer + { + using value_t = ISPIRVOptimizer::E_OPTIMIZER_PASS; + + static inline void to_json(::json& j, const value_t& p) + { + uint32_t value = static_cast(p); + j = ::json{ + { "optPass", value }, + }; + } + + static inline void from_json(const ::json& j, value_t& p) + { + uint32_t aux; + j.at("optPass").get_to(aux); + p = static_cast(aux); + } + }; +} +NBL_JSON_IMPL_BIND_ADL_SERIALIZER(::nbl::system::json::adl_serializer) + +// SCompilerArgs, holds serialized info for all Compilation options +namespace nbl::system::json { + template<> + struct adl_serializer + { + using value_t = SEntry::SCompilerArgs; + + static inline void to_json(::json& j, const value_t& p) + { + uint32_t shaderStage = static_cast(p.stage); + uint32_t spirvVersion = static_cast(p.targetSpirvVersion); + uint32_t debugFlags = static_cast(p.debugInfoFlags.value); + + j = ::json{ + { "shaderStage", shaderStage }, + { "spirvVersion", spirvVersion }, + { "optimizerPasses", p.optimizerPasses }, + { "debugFlags", debugFlags }, + { "preprocessorArgs", p.preprocessorArgs }, + }; + } + + static inline void from_json(const ::json& j, value_t& p) + { + uint32_t shaderStage, spirvVersion, debugFlags; + j.at("shaderStage").get_to(shaderStage); + j.at("spirvVersion").get_to(spirvVersion); + j.at("optimizerPasses").get_to(p.optimizerPasses); + j.at("debugFlags").get_to(debugFlags); + j.at("preprocessorArgs").get_to(p.preprocessorArgs); + p.stage = static_cast(shaderStage); + p.targetSpirvVersion = static_cast(spirvVersion); + p.debugInfoFlags = core::bitflag(debugFlags); + } + }; +} +NBL_JSON_IMPL_BIND_ADL_SERIALIZER(::nbl::system::json::adl_serializer) + +// Serialize clock's time point +using time_point_t = nbl::system::IFileBase::time_point_t; +namespace nbl::system::json { + template<> + struct adl_serializer + { + using value_t = time_point_t; + + static inline void to_json(::json& j, const value_t& p) + { + auto ticks = p.time_since_epoch().count(); + j = ::json{ + { "ticks", ticks }, + }; + } + + static inline void from_json(const ::json& j, value_t& p) + { + uint64_t ticks; + j.at("ticks").get_to(ticks); + p = time_point_t(time_point_t::clock::duration(ticks)); + } + }; +} +NBL_JSON_IMPL_BIND_ADL_SERIALIZER(::nbl::system::json::adl_serializer) + +// SDependency serialization. Dependencies will be saved in a vector for easier vectorization +namespace nbl::system::json { + template<> + struct adl_serializer + { + using value_t = SEntry::SPreprocessingDependency; + + static inline void to_json(::json& j, const value_t& p) + { + j = ::json{ + { "requestingSourceDir", p.requestingSourceDir }, + { "identifier", p.identifier }, + { "hash", p.hash.data }, + { "standardInclude", p.standardInclude }, + }; + } + + static inline void from_json(const ::json& j, value_t& p) + { + j.at("requestingSourceDir").get_to(p.requestingSourceDir); + j.at("identifier").get_to(p.identifier); + j.at("hash").get_to(p.hash.data); + j.at("standardInclude").get_to(p.standardInclude); + } + }; +} +NBL_JSON_IMPL_BIND_ADL_SERIALIZER(::nbl::system::json::adl_serializer) + +// We serialize shader creation parameters into a json, along with indexing info into the .bin buffer where the cache is serialized +struct CPUShaderCreationParams { + IShader::E_SHADER_STAGE stage; + std::string filepathHint; + uint64_t codeByteSize = 0; + uint64_t offset = 0; // Offset into the serialized .bin for the Cache where code starts + + CPUShaderCreationParams(IShader::E_SHADER_STAGE _stage, std::string_view _filepathHint, uint64_t _codeByteSize, uint64_t _offset) + : stage(_stage), filepathHint(_filepathHint), codeByteSize(_codeByteSize), offset(_offset) {} + CPUShaderCreationParams() {}; +}; + +namespace nbl::system::json { + template<> + struct adl_serializer + { + using value_t = CPUShaderCreationParams; + + static inline void to_json(::json& j, const value_t& p) + { + uint32_t stage = static_cast(p.stage); + j = ::json{ + { "stage", stage }, + { "filepathHint", p.filepathHint }, + { "codeByteSize", p.codeByteSize }, + { "offset", p.offset }, + }; + } + + static inline void from_json(const ::json& j, value_t& p) + { + uint32_t stage; + j.at("stage").get_to(stage); + j.at("filepathHint").get_to(p.filepathHint); + j.at("codeByteSize").get_to(p.codeByteSize); + j.at("offset").get_to(p.offset); + p.stage = static_cast(stage); + } + }; +} +NBL_JSON_IMPL_BIND_ADL_SERIALIZER(::nbl::system::json::adl_serializer) + +// Serialize SEntry, keeping some fields as extra serialization to keep them separate on disk +namespace nbl::system::json { + template<> + struct adl_serializer + { + using value_t = SEntry; + + static inline void to_json(::json& j, const value_t& p) + { + j = ::json{ + { "mainFileContents", p.mainFileContents }, + { "compilerArgs", p.compilerArgs }, + { "hash", p.hash.data }, + { "lookupHash", p.lookupHash }, + { "dependencies", p.dependencies }, + { "uncompressedContentHash", p.uncompressedContentHash.data }, + { "uncompressedSize", p.uncompressedSize }, + }; + } + + static inline void from_json(const ::json& j, value_t& p) + { + j.at("mainFileContents").get_to(p.mainFileContents); + j.at("compilerArgs").get_to(p.compilerArgs); + j.at("hash").get_to(p.hash.data); + j.at("lookupHash").get_to(p.lookupHash); + j.at("dependencies").get_to(p.dependencies); + j.at("uncompressedContentHash").get_to(p.uncompressedContentHash.data); + j.at("uncompressedSize").get_to(p.uncompressedSize); + p.spirv = nullptr; + } + }; +} +NBL_JSON_IMPL_BIND_ADL_SERIALIZER(::nbl::system::json::adl_serializer) +// <- serialization + IShaderCompiler::IShaderCompiler(core::smart_refctd_ptr&& system) : m_system(std::move(system)) { diff --git a/src/nbl/asset/utils/shaderCompiler_serialization.h b/src/nbl/asset/utils/shaderCompiler_serialization.h deleted file mode 100644 index 6ad33a2ff5..0000000000 --- a/src/nbl/asset/utils/shaderCompiler_serialization.h +++ /dev/null @@ -1,196 +0,0 @@ -#ifndef _NBL_ASSET_SHADER_COMPILER_SERIALIZATION_H_INCLUDED_ -#define _NBL_ASSET_SHADER_COMPILER_SERIALIZATION_H_INCLUDED_ - -#include "nbl/asset/utils/IShaderCompiler.h" -#include "nlohmann/json.hpp" - -using json = nlohmann::json; -using SEntry = nbl::asset::IShaderCompiler::CCache::SEntry; - - -namespace nbl::asset -{ - -// TODO: use NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE whenever possible - -// SMacroData, simple container used in SPreprocessorArgs - -inline void to_json(json& j, const IShaderCompiler::SMacroDefinition& macroData) -{ - j = json{ - { "identifier", macroData.identifier }, - { "definition", macroData.definition }, - }; -} - -inline void from_json(const json& j, IShaderCompiler::SMacroDefinition& macroData) -{ - j.at("identifier").get_to(macroData.identifier); - j.at("definition").get_to(macroData.definition); -} - -// SPreprocessorData, holds serialized info for Preprocessor options used during compilation -inline void to_json(json& j, const SEntry::SPreprocessorArgs& preprocArgs) -{ - j = json{ - { "sourceIdentifier", preprocArgs.sourceIdentifier }, - { "extraDefines", preprocArgs.extraDefines}, - }; -} - -inline void from_json(const json& j, SEntry::SPreprocessorArgs& preprocArgs) -{ - j.at("sourceIdentifier").get_to(preprocArgs.sourceIdentifier); - j.at("extraDefines").get_to(preprocArgs.extraDefines); -} - -// Optimizer pass has its own method for easier vector serialization - -inline void to_json(json& j, const ISPIRVOptimizer::E_OPTIMIZER_PASS& optPass) -{ - uint32_t value = static_cast(optPass); - j = json{ - { "optPass", value }, - }; -} - -inline void from_json(const json& j, ISPIRVOptimizer::E_OPTIMIZER_PASS& optPass) -{ - uint32_t aux; - j.at("optPass").get_to(aux); - optPass = static_cast(aux); -} - -// SCompilerArgs, holds serialized info for all Compilation options - -inline void to_json(json& j, const SEntry::SCompilerArgs& compilerData) -{ - uint32_t shaderStage = static_cast(compilerData.stage); - uint32_t spirvVersion = static_cast(compilerData.targetSpirvVersion); - uint32_t debugFlags = static_cast(compilerData.debugInfoFlags.value); - - j = json { - { "shaderStage", shaderStage }, - { "spirvVersion", spirvVersion }, - { "optimizerPasses", compilerData.optimizerPasses }, - { "debugFlags", debugFlags }, - { "preprocessorArgs", compilerData.preprocessorArgs }, - }; -} - -inline void from_json(const json& j, SEntry::SCompilerArgs& compilerData) -{ - uint32_t shaderStage, spirvVersion, debugFlags; - j.at("shaderStage").get_to(shaderStage); - j.at("spirvVersion").get_to(spirvVersion); - j.at("optimizerPasses").get_to(compilerData.optimizerPasses); - j.at("debugFlags").get_to(debugFlags); - j.at("preprocessorArgs").get_to(compilerData.preprocessorArgs); - compilerData.stage = static_cast(shaderStage); - compilerData.targetSpirvVersion = static_cast(spirvVersion); - compilerData.debugInfoFlags = core::bitflag(debugFlags); -} - -// Serialize clock's time point -using time_point_t = nbl::system::IFileBase::time_point_t; - -inline void to_json(json& j, const time_point_t& timePoint) -{ - auto ticks = timePoint.time_since_epoch().count(); - j = json{ - { "ticks", ticks }, - }; -} - -inline void from_json(const json& j, time_point_t& timePoint) -{ - uint64_t ticks; - j.at("ticks").get_to(ticks); - timePoint = time_point_t(time_point_t::clock::duration(ticks)); -} - -// SDependency serialization. Dependencies will be saved in a vector for easier vectorization - -inline void to_json(json& j, const SEntry::SPreprocessingDependency& dependency) -{ - j = json{ - { "requestingSourceDir", dependency.requestingSourceDir }, - { "identifier", dependency.identifier }, - { "hash", dependency.hash.data }, - { "standardInclude", dependency.standardInclude }, - }; -} - -inline void from_json(const json& j, SEntry::SPreprocessingDependency& dependency) -{ - j.at("requestingSourceDir").get_to(dependency.requestingSourceDir); - j.at("identifier").get_to(dependency.identifier); - j.at("hash").get_to(dependency.hash.data); - j.at("standardInclude").get_to(dependency.standardInclude); -} - -// We serialize shader creation parameters into a json, along with indexing info into the .bin buffer where the cache is serialized - -struct CPUShaderCreationParams { - IShader::E_SHADER_STAGE stage; - std::string filepathHint; - uint64_t codeByteSize = 0; - uint64_t offset = 0; // Offset into the serialized .bin for the Cache where code starts - - CPUShaderCreationParams(IShader::E_SHADER_STAGE _stage, std::string_view _filepathHint, uint64_t _codeByteSize, uint64_t _offset) - : stage(_stage), filepathHint(_filepathHint), codeByteSize(_codeByteSize), offset(_offset) - {} - - CPUShaderCreationParams() {}; -}; - -inline void to_json(json& j, const CPUShaderCreationParams& creationParams) -{ - uint32_t stage = static_cast(creationParams.stage); - j = json{ - { "stage", stage }, - { "filepathHint", creationParams.filepathHint }, - { "codeByteSize", creationParams.codeByteSize }, - { "offset", creationParams.offset }, - }; -} - -inline void from_json(const json& j, CPUShaderCreationParams& creationParams) -{ - uint32_t stage; - j.at("stage").get_to(stage); - j.at("filepathHint").get_to(creationParams.filepathHint); - j.at("codeByteSize").get_to(creationParams.codeByteSize); - j.at("offset").get_to(creationParams.offset); - creationParams.stage = static_cast(stage); -} - -// Serialize SEntry, keeping some fields as extra serialization to keep them separate on disk - -inline void to_json(json& j, const SEntry& entry) -{ - j = json{ - { "mainFileContents", entry.mainFileContents }, - { "compilerArgs", entry.compilerArgs }, - { "hash", entry.hash.data }, - { "lookupHash", entry.lookupHash }, - { "dependencies", entry.dependencies }, - { "uncompressedContentHash", entry.uncompressedContentHash.data }, - { "uncompressedSize", entry.uncompressedSize }, - }; -} - -inline void from_json(const json& j, SEntry& entry) -{ - j.at("mainFileContents").get_to(entry.mainFileContents); - j.at("compilerArgs").get_to(entry.compilerArgs); - j.at("hash").get_to(entry.hash.data); - j.at("lookupHash").get_to(entry.lookupHash); - j.at("dependencies").get_to(entry.dependencies); - j.at("uncompressedContentHash").get_to(entry.uncompressedContentHash.data); - j.at("uncompressedSize").get_to(entry.uncompressedSize); - entry.spirv = nullptr; -} - -} -#endif \ No newline at end of file From 0168ad7bec492bb84fc6892eace28bb3e6090c76 Mon Sep 17 00:00:00 2001 From: Arkadiusz Lachowicz Date: Thu, 13 Nov 2025 12:47:45 +0100 Subject: [PATCH 20/20] fix json ambiguity, update examples_tests submodule --- examples_tests | 2 +- tools/nsc/main.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples_tests b/examples_tests index 3820eb17c3..8a29f18026 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 3820eb17c371626f189b242f1b0bdb36abb7ee85 +Subproject commit 8a29f18026a277589d7b2b672ab13fc572f70448 diff --git a/tools/nsc/main.cpp b/tools/nsc/main.cpp index 0a532916b4..f1e623bcf8 100644 --- a/tools/nsc/main.cpp +++ b/tools/nsc/main.cpp @@ -8,7 +8,7 @@ #include "nbl/asset/metadata/CHLSLMetadata.h" #include "nlohmann/json.hpp" -using json = nlohmann::json; +using json = ::nlohmann::json; using namespace nbl; using namespace nbl::system; @@ -34,7 +34,7 @@ class ShaderCompiler final : public system::IApplicationFramework if (argv[1] == "--dump-build-info") { - json j; + ::json j; auto& modules = j["modules"];