Browse Source

Make ConfigSet a singleton

Panagiotis Christopoulos Charitos 2 years ago
parent
commit
35ff474d0e
66 changed files with 360 additions and 365 deletions
  1. 39 39
      AnKi/Core/App.cpp
  2. 1 14
      AnKi/Core/App.h
  3. 14 15
      AnKi/Core/ConfigSet.h
  4. 6 6
      AnKi/Core/GpuMemoryPools.cpp
  5. 3 6
      AnKi/Core/GpuMemoryPools.h
  6. 0 13
      AnKi/Gr/GrManager.h
  7. 33 26
      AnKi/Gr/Vulkan/GrManagerImpl.cpp
  8. 0 1
      AnKi/Gr/Vulkan/GrManagerImpl.h
  9. 2 3
      AnKi/Gr/Vulkan/PipelineCache.cpp
  10. 1 4
      AnKi/Gr/Vulkan/PipelineCache.h
  11. 13 13
      AnKi/Renderer/Bloom.cpp
  12. 0 1
      AnKi/Renderer/Common.h
  13. 3 3
      AnKi/Renderer/Dbg.cpp
  14. 2 2
      AnKi/Renderer/DepthDownscale.cpp
  15. 3 3
      AnKi/Renderer/DownscaleBlur.cpp
  16. 5 6
      AnKi/Renderer/FinalComposite.cpp
  17. 3 6
      AnKi/Renderer/GBuffer.cpp
  18. 16 16
      AnKi/Renderer/IndirectDiffuse.cpp
  19. 2 2
      AnKi/Renderer/IndirectDiffuseProbes.cpp
  20. 12 12
      AnKi/Renderer/IndirectSpecular.cpp
  21. 2 2
      AnKi/Renderer/LensFlare.cpp
  22. 5 6
      AnKi/Renderer/LightShading.cpp
  23. 2 2
      AnKi/Renderer/MainRenderer.cpp
  24. 6 6
      AnKi/Renderer/MotionVectors.cpp
  25. 4 4
      AnKi/Renderer/ProbeReflections.cpp
  26. 7 7
      AnKi/Renderer/Renderer.cpp
  27. 0 1
      AnKi/Renderer/RendererObject.h
  28. 3 3
      AnKi/Renderer/RtShadows.cpp
  29. 9 9
      AnKi/Renderer/Scale.cpp
  30. 6 6
      AnKi/Renderer/ShadowMapping.cpp
  31. 6 6
      AnKi/Renderer/ShadowmapsResolve.cpp
  32. 7 7
      AnKi/Renderer/TemporalAA.cpp
  33. 4 4
      AnKi/Renderer/VolumetricFog.cpp
  34. 4 4
      AnKi/Renderer/VolumetricLightingAccumulation.cpp
  35. 7 7
      AnKi/Renderer/VrsSriGeneration.cpp
  36. 0 2
      AnKi/Resource/Common.h
  37. 1 1
      AnKi/Resource/ImageResource.cpp
  38. 3 3
      AnKi/Resource/ResourceFilesystem.cpp
  39. 1 4
      AnKi/Resource/ResourceFilesystem.h
  40. 1 1
      AnKi/Resource/ResourceManager.cpp
  41. 0 1
      AnKi/Resource/ResourceManager.h
  42. 0 2
      AnKi/Scene/Common.h
  43. 1 1
      AnKi/Scene/Components/CameraComponent.cpp
  44. 3 4
      AnKi/Scene/Components/GlobalIlluminationProbeComponent.cpp
  45. 2 2
      AnKi/Scene/Components/ParticleEmitterComponent.cpp
  46. 4 5
      AnKi/Scene/Components/ReflectionProbeComponent.cpp
  47. 1 1
      AnKi/Scene/ContiguousArrayAllocator.cpp
  48. 1 1
      AnKi/Scene/SceneGraph.cpp
  49. 1 1
      AnKi/Scene/SceneGraph.h
  50. 2 1
      AnKi/Util/CMakeLists.txt
  51. 3 3
      AnKi/Util/MemoryPool.h
  52. 30 0
      AnKi/Util/Singleton.cpp
  53. 25 9
      AnKi/Util/Singleton.h
  54. 9 9
      Samples/Common/SampleApp.cpp
  55. 0 2
      Samples/Common/SampleApp.h
  56. 4 4
      Samples/PhysicsPlayground/Main.cpp
  57. 1 1
      Samples/SkeletalAnimation/Main.cpp
  58. 10 12
      Sandbox/Main.cpp
  59. 3 5
      Tests/Framework/Framework.cpp
  60. 2 2
      Tests/Framework/Framework.h
  61. 5 4
      Tests/Gr/Gr.cpp
  62. 2 2
      Tests/Gr/GrTextureBuffer.cpp
  63. 2 2
      Tests/Resource/ResourceFilesystem.cpp
  64. 1 2
      Tests/Resource/ResourceManager.cpp
  65. 4 4
      Tests/Ui/Ui.cpp
  66. 8 9
      Tools/Image/ImageViewerMain.cpp

+ 39 - 39
AnKi/Core/App.cpp

@@ -103,6 +103,8 @@ void* App::MemStats::allocCallback(void* userData, void* ptr, PtrSize size, [[ma
 
 App::App()
 {
+	// Config is special
+	ConfigSet::allocateSingleton(allocAligned, nullptr);
 }
 
 App::~App()
@@ -153,14 +155,14 @@ void App::cleanup()
 	m_coreTracer = nullptr;
 #endif
 
+	ConfigSet::freeSingleton();
+
 	m_settingsDir.destroy(m_mainPool);
 	m_cacheDir.destroy(m_mainPool);
 }
 
-Error App::init(ConfigSet* config, AllocAlignedCallback allocCb, void* allocCbUserData)
+Error App::init(AllocAlignedCallback allocCb, void* allocCbUserData)
 {
-	ANKI_ASSERT(config);
-	m_config = config;
 	const Error err = initInternal(allocCb, allocCbUserData);
 	if(err)
 	{
@@ -173,7 +175,7 @@ Error App::init(ConfigSet* config, AllocAlignedCallback allocCb, void* allocCbUs
 
 Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 {
-	Logger::getSingleton().enableVerbosity(m_config->getCoreVerboseLog());
+	Logger::getSingleton().enableVerbosity(ConfigSet::getSingleton().getCoreVerboseLog());
 
 	setSignalHandlers();
 
@@ -222,12 +224,12 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	}
 #endif
 
-	ANKI_CORE_LOGI("Number of job threads: %u", m_config->getCoreJobThreadCount());
+	ANKI_CORE_LOGI("Number of job threads: %u", ConfigSet::getSingleton().getCoreJobThreadCount());
 
-	if(m_config->getCoreBenchmarkMode() && m_config->getGrVsync())
+	if(ConfigSet::getSingleton().getCoreBenchmarkMode() && ConfigSet::getSingleton().getGrVsync())
 	{
 		ANKI_CORE_LOGW("Vsync is enabled and benchmark mode as well. Will turn vsync off");
-		m_config->setGrVsync(false);
+		ConfigSet::getSingleton().setGrVsync(false);
 	}
 
 	//
@@ -244,13 +246,13 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	NativeWindowInitInfo nwinit;
 	nwinit.m_allocCallback = m_mainPool.getAllocationCallback();
 	nwinit.m_allocCallbackUserData = m_mainPool.getAllocationCallbackUserData();
-	nwinit.m_width = m_config->getWidth();
-	nwinit.m_height = m_config->getHeight();
+	nwinit.m_width = ConfigSet::getSingleton().getWidth();
+	nwinit.m_height = ConfigSet::getSingleton().getHeight();
 	nwinit.m_depthBits = 0;
 	nwinit.m_stencilBits = 0;
-	nwinit.m_fullscreenDesktopRez = m_config->getWindowFullscreen() > 0;
-	nwinit.m_exclusiveFullscreen = m_config->getWindowFullscreen() == 2;
-	nwinit.m_targetFps = m_config->getCoreTargetFps();
+	nwinit.m_fullscreenDesktopRez = ConfigSet::getSingleton().getWindowFullscreen() > 0;
+	nwinit.m_exclusiveFullscreen = ConfigSet::getSingleton().getWindowFullscreen() == 2;
+	nwinit.m_targetFps = ConfigSet::getSingleton().getCoreTargetFps();
 	ANKI_CHECK(NativeWindow::newInstance(nwinit, m_window));
 
 	//
@@ -263,7 +265,8 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	// ThreadPool
 	//
 	const Bool pinThreads = !ANKI_OS_ANDROID;
-	m_threadHive = newInstance<ThreadHive>(m_mainPool, m_config->getCoreJobThreadCount(), &m_mainPool, pinThreads);
+	m_threadHive =
+		newInstance<ThreadHive>(m_mainPool, ConfigSet::getSingleton().getCoreJobThreadCount(), &m_mainPool, pinThreads);
 
 	//
 	// Graphics API
@@ -272,7 +275,6 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	grInit.m_allocCallback = m_mainPool.getAllocationCallback();
 	grInit.m_allocCallbackUserData = m_mainPool.getAllocationCallbackUserData();
 	grInit.m_cacheDirectory = m_cacheDir.toCString();
-	grInit.m_config = m_config;
 	grInit.m_window = m_window;
 
 	ANKI_CHECK(GrManager::newInstance(grInit, m_gr));
@@ -280,7 +282,8 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	//
 	// Mali HW counters
 	//
-	if(m_gr->getDeviceCapabilities().m_gpuVendor == GpuVendor::kArm && m_config->getCoreMaliHwCounters())
+	if(m_gr->getDeviceCapabilities().m_gpuVendor == GpuVendor::kArm
+	   && ConfigSet::getSingleton().getCoreMaliHwCounters())
 	{
 		m_maliHwCounters = newInstance<MaliHwCounters>(m_mainPool, &m_mainPool);
 	}
@@ -289,13 +292,13 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	// GPU mem
 	//
 	m_unifiedGometryMemPool = newInstance<UnifiedGeometryMemoryPool>(m_mainPool);
-	m_unifiedGometryMemPool->init(&m_mainPool, m_gr, *m_config);
+	m_unifiedGometryMemPool->init(&m_mainPool, m_gr);
 
 	m_gpuSceneMemPool = newInstance<GpuSceneMemoryPool>(m_mainPool);
-	m_gpuSceneMemPool->init(&m_mainPool, m_gr, *m_config);
+	m_gpuSceneMemPool->init(&m_mainPool, m_gr);
 
 	m_rebarPool = newInstance<RebarStagingGpuMemoryPool>(m_mainPool);
-	ANKI_CHECK(m_rebarPool->init(m_gr, *m_config));
+	ANKI_CHECK(m_rebarPool->init(m_gr));
 
 	//
 	// Physics
@@ -315,13 +318,12 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	StringRaii shadersPath(&m_mainPool);
 	getParentFilepath(executableFname, shadersPath);
 	shadersPath.append(":");
-	shadersPath.append(m_config->getRsrcDataPaths());
-	m_config->setRsrcDataPaths(shadersPath);
+	shadersPath.append(ConfigSet::getSingleton().getRsrcDataPaths());
+	ConfigSet::getSingleton().setRsrcDataPaths(shadersPath);
 #endif
 
 	m_resourceFs = newInstance<ResourceFilesystem>(m_mainPool);
-	ANKI_CHECK(
-		m_resourceFs->init(*m_config, m_mainPool.getAllocationCallback(), m_mainPool.getAllocationCallbackUserData()));
+	ANKI_CHECK(m_resourceFs->init(m_mainPool.getAllocationCallback(), m_mainPool.getAllocationCallbackUserData()));
 
 	//
 	// Resources
@@ -330,7 +332,6 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	rinit.m_grManager = m_gr;
 	rinit.m_resourceFilesystem = m_resourceFs;
 	rinit.m_unifiedGometryMemoryPool = m_unifiedGometryMemPool;
-	rinit.m_config = m_config;
 	rinit.m_allocCallback = m_mainPool.getAllocationCallback();
 	rinit.m_allocCallbackData = m_mainPool.getAllocationCallbackUserData();
 	m_resources = newInstance<ResourceManager>(m_mainPool);
@@ -369,7 +370,6 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	renderInit.m_grManager = m_gr;
 	renderInit.m_rebarStagingPool = m_rebarPool;
 	renderInit.m_uiManager = m_ui;
-	renderInit.m_config = m_config;
 	renderInit.m_globTimestamp = &m_globalTimestamp;
 	renderInit.m_gpuScenePool = m_gpuSceneMemPool;
 	renderInit.m_gpuSceneMicroPatcher = m_gpuSceneMicroPatcher;
@@ -391,7 +391,6 @@ Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 	SceneGraphInitInfo sceneInit;
 	sceneInit.m_allocCallback = m_mainPool.getAllocationCallback();
 	sceneInit.m_allocCallbackData = m_mainPool.getAllocationCallbackUserData();
-	sceneInit.m_config = m_config;
 	sceneInit.m_globalTimestamp = &m_globalTimestamp;
 	sceneInit.m_gpuSceneMemoryPool = m_gpuSceneMemPool;
 	sceneInit.m_gpuSceneMicroPatcher = m_gpuSceneMicroPatcher;
@@ -445,7 +444,7 @@ Error App::initDirs()
 	m_cacheDir.sprintf(m_mainPool, "%s/cache", &m_settingsDir[0]);
 
 	const Bool cacheDirExists = directoryExists(m_cacheDir.toCString());
-	if(m_config->getCoreClearCaches() && cacheDirExists)
+	if(ConfigSet::getSingleton().getCoreClearCaches() && cacheDirExists)
 	{
 		ANKI_CORE_LOGI("Will delete the cache dir and start fresh: %s", &m_cacheDir[0]);
 		ANKI_CHECK(removeDirectory(m_cacheDir.toCString(), m_mainPool));
@@ -469,7 +468,7 @@ Error App::mainLoop()
 	Second crntTime = prevUpdateTime;
 
 	// Benchmark mode stuff:
-	const Bool benchmarkMode = m_config->getCoreBenchmarkMode();
+	const Bool benchmarkMode = ConfigSet::getSingleton().getCoreBenchmarkMode();
 	Second aggregatedCpuTime = 0.0;
 	Second aggregatedGpuTime = 0.0;
 	constexpr U32 kBenchmarkFramesToGatherBeforeFlush = 60;
@@ -509,7 +508,7 @@ Error App::mainLoop()
 
 			// Render
 			TexturePtr presentableTex = m_gr->acquireNextPresentableTexture();
-			m_renderer->setStatsEnabled(m_config->getCoreDisplayStats() > 0 || benchmarkMode
+			m_renderer->setStatsEnabled(ConfigSet::getSingleton().getCoreDisplayStats() > 0 || benchmarkMode
 #if ANKI_ENABLE_TRACE
 										|| Tracer::getSingleton().getEnabled()
 #endif
@@ -522,14 +521,14 @@ Error App::mainLoop()
 			// If we get stats exclude the time of GR because it forces some GPU-CPU serialization. We don't want to
 			// count that
 			Second grTime = 0.0;
-			if(benchmarkMode || m_config->getCoreDisplayStats() > 0) [[unlikely]]
+			if(benchmarkMode || ConfigSet::getSingleton().getCoreDisplayStats() > 0) [[unlikely]]
 			{
 				grTime = HighRezTimer::getCurrentTime();
 			}
 
 			m_gr->swapBuffers();
 
-			if(benchmarkMode || m_config->getCoreDisplayStats() > 0) [[unlikely]]
+			if(benchmarkMode || ConfigSet::getSingleton().getCoreDisplayStats() > 0) [[unlikely]]
 			{
 				grTime = HighRezTimer::getCurrentTime() - grTime;
 			}
@@ -551,7 +550,7 @@ Error App::mainLoop()
 			const Second frameTime = endTime - startTime;
 			if(!benchmarkMode) [[likely]]
 			{
-				const Second timerTick = 1.0_sec / Second(m_config->getCoreTargetFps());
+				const Second timerTick = 1.0_sec / Second(ConfigSet::getSingleton().getCoreTargetFps());
 				if(frameTime < timerTick)
 				{
 					ANKI_TRACE_SCOPED_EVENT(TimerTickSleep);
@@ -577,7 +576,7 @@ Error App::mainLoop()
 			}
 
 			// Stats
-			if(m_config->getCoreDisplayStats() > 0)
+			if(ConfigSet::getSingleton().getCoreDisplayStats() > 0)
 			{
 				StatsUiInput in;
 				in.m_cpuFrameTime = frameTime - grTime;
@@ -614,8 +613,9 @@ Error App::mainLoop()
 				in.m_vkCommandBufferCount = grStats.m_commandBufferCount;
 
 				StatsUi& statsUi = *static_cast<StatsUi*>(m_statsUi.get());
-				const StatsUiDetail detail =
-					(m_config->getCoreDisplayStats() == 1) ? StatsUiDetail::kFpsOnly : StatsUiDetail::kDetailed;
+				const StatsUiDetail detail = (ConfigSet::getSingleton().getCoreDisplayStats() == 1)
+												 ? StatsUiDetail::kFpsOnly
+												 : StatsUiDetail::kDetailed;
 				statsUi.setStats(in, detail);
 			}
 
@@ -631,7 +631,7 @@ Error App::mainLoop()
 
 			if(benchmarkMode) [[unlikely]]
 			{
-				if(m_globalTimestamp >= m_config->getCoreBenchmarkModeFrameCount())
+				if(m_globalTimestamp >= ConfigSet::getSingleton().getCoreBenchmarkModeFrameCount())
 				{
 					quit = true;
 				}
@@ -655,9 +655,9 @@ Error App::mainLoop()
 void App::injectUiElements(DynamicArrayRaii<UiQueueElement>& newUiElementArr, RenderQueue& rqueue)
 {
 	const U32 originalCount = rqueue.m_uis.getSize();
-	if(m_config->getCoreDisplayStats() > 0 || m_consoleEnabled)
+	if(ConfigSet::getSingleton().getCoreDisplayStats() > 0 || m_consoleEnabled)
 	{
-		const U32 extraElements = (m_config->getCoreDisplayStats() > 0) + (m_consoleEnabled != 0);
+		const U32 extraElements = (ConfigSet::getSingleton().getCoreDisplayStats() > 0) + (m_consoleEnabled != 0);
 		newUiElementArr.create(originalCount + extraElements);
 
 		if(originalCount > 0)
@@ -669,7 +669,7 @@ void App::injectUiElements(DynamicArrayRaii<UiQueueElement>& newUiElementArr, Re
 	}
 
 	U32 count = originalCount;
-	if(m_config->getCoreDisplayStats() > 0)
+	if(ConfigSet::getSingleton().getCoreDisplayStats() > 0)
 	{
 		newUiElementArr[count].m_userData = m_statsUi.get();
 		newUiElementArr[count].m_drawCallback = [](CanvasPtr& canvas, void* userData) -> void {
@@ -690,7 +690,7 @@ void App::injectUiElements(DynamicArrayRaii<UiQueueElement>& newUiElementArr, Re
 
 void App::initMemoryCallbacks(AllocAlignedCallback& allocCb, void*& allocCbUserData)
 {
-	if(m_config->getCoreDisplayStats() > 1)
+	if(ConfigSet::getSingleton().getCoreDisplayStats() > 1)
 	{
 		m_memStats.m_originalAllocCallback = allocCb;
 		m_memStats.m_originalUserData = allocCbUserData;

+ 1 - 14
AnKi/Core/App.h

@@ -14,7 +14,6 @@ namespace anki {
 
 // Forward
 class CoreTracer;
-class ConfigSet;
 class ThreadHive;
 class NativeWindow;
 class Input;
@@ -41,8 +40,7 @@ public:
 	virtual ~App();
 
 	/// Initialize the application.
-	/// @param[in,out] config The config. Needs to be alive as long as the app is alive.
-	Error init(ConfigSet* config, AllocAlignedCallback allocCb, void* allocCbUserData);
+	Error init(AllocAlignedCallback allocCb, void* allocCbUserData);
 
 	const String& getSettingsDirectory() const
 	{
@@ -79,16 +77,6 @@ public:
 		return Error::kNone;
 	}
 
-	const ConfigSet& getConfig() const
-	{
-		return *m_config;
-	}
-
-	ConfigSet& getConfig()
-	{
-		return *m_config;
-	}
-
 	Input& getInput()
 	{
 		return *m_input;
@@ -133,7 +121,6 @@ private:
 	HeapMemoryPool m_mainPool;
 
 	// Sybsystems
-	ConfigSet* m_config = nullptr;
 #if ANKI_ENABLE_TRACE
 	CoreTracer* m_coreTracer = nullptr;
 #endif

+ 14 - 15
AnKi/Core/ConfigSet.h

@@ -8,6 +8,7 @@
 #include <AnKi/Core/Common.h>
 #include <AnKi/Util/List.h>
 #include <AnKi/Util/String.h>
+#include <AnKi/Util/Singleton.h>
 #include <AnKi/Math/Functions.h>
 
 namespace anki {
@@ -16,27 +17,16 @@ namespace anki {
 /// @{
 
 /// A storage of configuration variables.
-class ConfigSet
+class ConfigSet : public MakeSingleton<ConfigSet>
 {
-public:
-	/// @note Need to call init() if using this constructor.
-	ConfigSet()
-	{
-	}
-
-	ConfigSet(AllocAlignedCallback allocCb, void* allocCbUserData)
-	{
-		init(allocCb, allocCbUserData);
-	}
+	template<typename>
+	friend class MakeSingleton;
 
+public:
 	ConfigSet(const ConfigSet& b) = delete; // Non-copyable
 
-	~ConfigSet();
-
 	ConfigSet& operator=(const ConfigSet& b) = delete; // Non-copyable
 
-	void init(AllocAlignedCallback allocCb, void* allocCbUserData);
-
 	Error loadFromFile(CString filename);
 
 	Error saveToFile(CString filename) const;
@@ -144,6 +134,15 @@ private:
 #define ANKI_CONFIG_VAR_STRING(name, defaultValue, description) StringVar m_##name;
 #include <AnKi/Core/AllConfigVars.defs.h>
 
+	ConfigSet(AllocAlignedCallback allocCb, void* allocCbUserData)
+	{
+		init(allocCb, allocCbUserData);
+	}
+
+	~ConfigSet();
+
+	void init(AllocAlignedCallback allocCb, void* allocCbUserData);
+
 	Bool isInitialized() const
 	{
 		return !m_vars.isEmpty();

+ 6 - 6
AnKi/Core/GpuMemoryPools.cpp

@@ -12,11 +12,11 @@
 
 namespace anki {
 
-void UnifiedGeometryMemoryPool::init(HeapMemoryPool* pool, GrManager* gr, const ConfigSet& cfg)
+void UnifiedGeometryMemoryPool::init(HeapMemoryPool* pool, GrManager* gr)
 {
 	ANKI_ASSERT(pool && gr);
 
-	const PtrSize poolSize = cfg.getCoreGlobalVertexMemorySize();
+	const PtrSize poolSize = ConfigSet::getSingleton().getCoreGlobalVertexMemorySize();
 
 	const Array classes = {1_KB, 8_KB, 32_KB, 128_KB, 512_KB, 4_MB, 8_MB, 16_MB, poolSize};
 
@@ -36,11 +36,11 @@ void UnifiedGeometryMemoryPool::init(HeapMemoryPool* pool, GrManager* gr, const
 	deferredFree(token);
 }
 
-void GpuSceneMemoryPool::init(HeapMemoryPool* pool, GrManager* gr, const ConfigSet& cfg)
+void GpuSceneMemoryPool::init(HeapMemoryPool* pool, GrManager* gr)
 {
 	ANKI_ASSERT(pool && gr);
 
-	const PtrSize poolSize = cfg.getCoreGpuSceneInitialSize();
+	const PtrSize poolSize = ConfigSet::getSingleton().getCoreGpuSceneInitialSize();
 
 	const Array classes = {32_B, 64_B, 128_B, 256_B, poolSize};
 
@@ -59,11 +59,11 @@ RebarStagingGpuMemoryPool::~RebarStagingGpuMemoryPool()
 	m_buffer.reset(nullptr);
 }
 
-Error RebarStagingGpuMemoryPool::init(GrManager* gr, const ConfigSet& cfg)
+Error RebarStagingGpuMemoryPool::init(GrManager* gr)
 {
 	BufferInitInfo buffInit("ReBar");
 	buffInit.m_mapAccess = BufferMapAccessBit::kWrite;
-	buffInit.m_size = cfg.getCoreRebarGpuMemorySize();
+	buffInit.m_size = ConfigSet::getSingleton().getCoreRebarGpuMemorySize();
 	buffInit.m_usage = BufferUsageBit::kAllUniform | BufferUsageBit::kAllStorage | BufferUsageBit::kVertex
 					   | BufferUsageBit::kIndex | BufferUsageBit::kShaderBindingTable;
 	m_buffer = gr->newBuffer(buffInit);

+ 3 - 6
AnKi/Core/GpuMemoryPools.h

@@ -13,9 +13,6 @@
 
 namespace anki {
 
-// Forward
-class ConfigSet;
-
 /// @addtogroup core
 /// @{
 
@@ -29,7 +26,7 @@ public:
 
 	UnifiedGeometryMemoryPool& operator=(const UnifiedGeometryMemoryPool&) = delete; // Non-copyable
 
-	void init(HeapMemoryPool* pool, GrManager* gr, const ConfigSet& cfg);
+	void init(HeapMemoryPool* pool, GrManager* gr);
 
 	void allocate(PtrSize size, U32 alignment, SegregatedListsGpuMemoryPoolToken& token)
 	{
@@ -70,7 +67,7 @@ public:
 
 	GpuSceneMemoryPool& operator=(const GpuSceneMemoryPool&) = delete; // Non-copyable
 
-	void init(HeapMemoryPool* pool, GrManager* gr, const ConfigSet& cfg);
+	void init(HeapMemoryPool* pool, GrManager* gr);
 
 	void allocate(PtrSize size, U32 alignment, SegregatedListsGpuMemoryPoolToken& token)
 	{
@@ -145,7 +142,7 @@ public:
 
 	RebarStagingGpuMemoryPool& operator=(const RebarStagingGpuMemoryPool&) = delete; // Non-copyable
 
-	Error init(GrManager* gr, const ConfigSet& cfg);
+	Error init(GrManager* gr);
 
 	PtrSize endFrame();
 

+ 0 - 13
AnKi/Gr/GrManager.h

@@ -12,7 +12,6 @@
 namespace anki {
 
 // Forward
-class ConfigSet;
 class NativeWindow;
 
 /// @addtogroup graphics
@@ -27,7 +26,6 @@ public:
 
 	CString m_cacheDirectory;
 
-	ConfigSet* m_config = nullptr;
 	NativeWindow* m_window = nullptr;
 };
 
@@ -104,22 +102,11 @@ public:
 		return m_uuidIndex.fetchAdd(1);
 	}
 
-	ANKI_INTERNAL const ConfigSet& getConfig() const
-	{
-		return *m_config;
-	}
-
-	ANKI_INTERNAL ConfigSet& getConfig()
-	{
-		return *m_config;
-	}
-
 protected:
 	/// Keep it first to get deleted last. It's mutable because its methods are thread-safe and we want to use it in
 	/// const methods.
 	mutable HeapMemoryPool m_pool;
 
-	ConfigSet* m_config = nullptr;
 	String m_cacheDir;
 	Atomic<U64> m_uuidIndex = {1};
 	GpuDeviceCapabilities m_capabilities;

+ 33 - 26
AnKi/Gr/Vulkan/GrManagerImpl.cpp

@@ -119,9 +119,6 @@ Error GrManagerImpl::initInternal(const GrManagerInitInfo& init)
 {
 	ANKI_VK_LOGI("Initializing Vulkan backend");
 
-	m_config = init.m_config;
-	ANKI_ASSERT(m_config);
-
 	ANKI_CHECK(initInstance());
 	ANKI_CHECK(initSurface(init));
 	ANKI_CHECK(initDevice(init));
@@ -138,11 +135,11 @@ Error GrManagerImpl::initInternal(const GrManagerInitInfo& init)
 		}
 	}
 
-	m_swapchainFactory.init(this, m_config->getGrVsync());
+	m_swapchainFactory.init(this, ConfigSet::getSingleton().getGrVsync());
 
 	m_crntSwapchain = m_swapchainFactory.newInstance();
 
-	ANKI_CHECK(m_pplineCache.init(m_device, m_physicalDevice, init.m_cacheDirectory, *m_config, m_pool));
+	ANKI_CHECK(m_pplineCache.init(m_device, m_physicalDevice, init.m_cacheDirectory, m_pool));
 
 	ANKI_CHECK(initMemory());
 
@@ -211,8 +208,8 @@ Error GrManagerImpl::initInstance()
 
 	// Create the instance
 	//
-	const U8 vulkanMinor = m_config->getGrVkMinor();
-	const U8 vulkanMajor = m_config->getGrVkMajor();
+	const U8 vulkanMinor = ConfigSet::getSingleton().getGrVkMinor();
+	const U8 vulkanMajor = ConfigSet::getSingleton().getGrVkMajor();
 
 	VkApplicationInfo app = {};
 	app.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
@@ -244,7 +241,8 @@ Error GrManagerImpl::initInstance()
 				CString layerName = layer.layerName;
 
 				static constexpr const Char* kValidationName = "VK_LAYER_KHRONOS_validation";
-				if((m_config->getGrValidation() || m_config->getGrDebugPrintf()) && layerName == kValidationName)
+				if((ConfigSet::getSingleton().getGrValidation() || ConfigSet::getSingleton().getGrDebugPrintf())
+				   && layerName == kValidationName)
 				{
 					layersToEnable.emplaceBack(kValidationName);
 				}
@@ -267,12 +265,12 @@ Error GrManagerImpl::initInstance()
 	// Validation features
 	DynamicArrayRaii<VkValidationFeatureEnableEXT> enabledValidationFeatures(&m_pool);
 	DynamicArrayRaii<VkValidationFeatureDisableEXT> disabledValidationFeatures(&m_pool);
-	if(m_config->getGrDebugPrintf())
+	if(ConfigSet::getSingleton().getGrDebugPrintf())
 	{
 		enabledValidationFeatures.emplaceBack(VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT);
 	}
 
-	if(!m_config->getGrValidation())
+	if(!ConfigSet::getSingleton().getGrValidation())
 	{
 		disabledValidationFeatures.emplaceBack(VK_VALIDATION_FEATURE_DISABLE_ALL_EXT);
 	}
@@ -352,7 +350,8 @@ Error GrManagerImpl::initInstance()
 				instExtensions[instExtensionCount++] = VK_KHR_SURFACE_EXTENSION_NAME;
 			}
 			else if(extensionName == VK_EXT_DEBUG_UTILS_EXTENSION_NAME
-					&& (m_config->getGrDebugMarkers() || m_config->getGrValidation() || m_config->getGrDebugPrintf()))
+					&& (ConfigSet::getSingleton().getGrDebugMarkers() || ConfigSet::getSingleton().getGrValidation()
+						|| ConfigSet::getSingleton().getGrDebugPrintf()))
 			{
 				m_extensions |= VulkanExtensions::kEXT_debug_utils;
 				instExtensions[instExtensionCount++] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
@@ -471,7 +470,7 @@ Error GrManagerImpl::initInstance()
 			}
 		});
 
-		const U32 chosenPhysDevIdx = min<U32>(m_config->getGrDevice(), devs.getSize() - 1);
+		const U32 chosenPhysDevIdx = min<U32>(ConfigSet::getSingleton().getGrDevice(), devs.getSize() - 1);
 
 		ANKI_VK_LOGI("Physical devices:");
 		for(U32 devIdx = 0; devIdx < count; ++devIdx)
@@ -603,7 +602,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 		return Error::kFunctionFailed;
 	}
 
-	if(!m_config->getGrAsyncCompute())
+	if(!ConfigSet::getSingleton().getGrAsyncCompute())
 	{
 		m_queueFamilyIndices[VulkanQueueType::kCompute] = kMaxU32;
 	}
@@ -665,7 +664,8 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 				m_extensions |= VulkanExtensions::kKHR_swapchain;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_AMD_SHADER_INFO_EXTENSION_NAME && m_config->getCoreDisplayStats())
+			else if(extensionName == VK_AMD_SHADER_INFO_EXTENSION_NAME
+					&& ConfigSet::getSingleton().getCoreDisplayStats())
 			{
 				m_extensions |= VulkanExtensions::kAMD_shader_info;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
@@ -675,35 +675,40 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 				m_extensions |= VulkanExtensions::kAMD_rasterization_order;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME && init.m_config->getGrRayTracing())
+			else if(extensionName == VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME
+					&& ConfigSet::getSingleton().getGrRayTracing())
 			{
 				m_extensions |= VulkanExtensions::kKHR_ray_tracing;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 				m_capabilities.m_rayTracingEnabled = true;
 			}
-			else if(extensionName == VK_KHR_RAY_QUERY_EXTENSION_NAME && init.m_config->getGrRayTracing())
+			else if(extensionName == VK_KHR_RAY_QUERY_EXTENSION_NAME && ConfigSet::getSingleton().getGrRayTracing())
 			{
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME && init.m_config->getGrRayTracing())
+			else if(extensionName == VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME
+					&& ConfigSet::getSingleton().getGrRayTracing())
 			{
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME && init.m_config->getGrRayTracing())
+			else if(extensionName == VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME
+					&& ConfigSet::getSingleton().getGrRayTracing())
 			{
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME && init.m_config->getGrRayTracing())
+			else if(extensionName == VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME
+					&& ConfigSet::getSingleton().getGrRayTracing())
 			{
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
 			else if(extensionName == VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME
-					&& m_config->getCoreDisplayStats() > 1)
+					&& ConfigSet::getSingleton().getCoreDisplayStats() > 1)
 			{
 				m_extensions |= VulkanExtensions::kKHR_pipeline_executable_properties;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME && m_config->getGrDebugPrintf())
+			else if(extensionName == VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME
+					&& ConfigSet::getSingleton().getGrDebugPrintf())
 			{
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
@@ -732,7 +737,8 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 				m_extensions |= VulkanExtensions::kKHR_shader_float16_int8;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME && m_config->getGr64bitAtomics())
+			else if(extensionName == VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME
+					&& ConfigSet::getSingleton().getGr64bitAtomics())
 			{
 				m_extensions |= VulkanExtensions::kKHR_shader_atomic_int64;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
@@ -748,7 +754,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
 			else if(extensionName == VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME
-					&& m_config->getGrSamplerFilterMinMax())
+					&& ConfigSet::getSingleton().getGrSamplerFilterMinMax())
 			{
 				m_extensions |= VulkanExtensions::kKHR_sampler_filter_min_max;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
@@ -758,7 +764,8 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 				m_extensions |= VulkanExtensions::kKHR_create_renderpass_2;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME && m_config->getGrVrs())
+			else if(extensionName == VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME
+					&& ConfigSet::getSingleton().getGrVrs())
 			{
 				m_extensions |= VulkanExtensions::kKHR_fragment_shading_rate;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
@@ -812,7 +819,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 		vkGetPhysicalDeviceFeatures2(m_physicalDevice, &devFeatures);
 		m_devFeatures = devFeatures.features;
 		m_devFeatures.robustBufferAccess =
-			(m_config->getGrValidation() && m_devFeatures.robustBufferAccess) ? true : false;
+			(ConfigSet::getSingleton().getGrValidation() && m_devFeatures.robustBufferAccess) ? true : false;
 		ANKI_VK_LOGI("Robust buffer access is %s", (m_devFeatures.robustBufferAccess) ? "enabled" : "disabled");
 
 		ci.pEnabledFeatures = &m_devFeatures;
@@ -896,7 +903,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 		vkGetPhysicalDeviceFeatures2(m_physicalDevice, &features);
 
 		m_deviceBufferFeatures.bufferDeviceAddressCaptureReplay =
-			m_deviceBufferFeatures.bufferDeviceAddressCaptureReplay && m_config->getGrDebugMarkers();
+			m_deviceBufferFeatures.bufferDeviceAddressCaptureReplay && ConfigSet::getSingleton().getGrDebugMarkers();
 		m_deviceBufferFeatures.bufferDeviceAddressMultiDevice = false;
 
 		m_deviceBufferFeatures.pNext = const_cast<void*>(ci.pNext);

+ 0 - 1
AnKi/Gr/Vulkan/GrManagerImpl.h

@@ -30,7 +30,6 @@ namespace anki {
 
 // Forward
 class TextureFallbackUploader;
-class ConfigSet;
 
 /// @addtogroup vulkan
 /// @{

+ 2 - 3
AnKi/Gr/Vulkan/PipelineCache.cpp

@@ -10,11 +10,10 @@
 
 namespace anki {
 
-Error PipelineCache::init(VkDevice dev, VkPhysicalDevice pdev, CString cacheDir, const ConfigSet& cfg,
-						  HeapMemoryPool& pool)
+Error PipelineCache::init(VkDevice dev, VkPhysicalDevice pdev, CString cacheDir, HeapMemoryPool& pool)
 {
 	ANKI_ASSERT(cacheDir && dev && pdev);
-	m_dumpSize = cfg.getGrDiskShaderCacheMaxSize();
+	m_dumpSize = ConfigSet::getSingleton().getGrDiskShaderCacheMaxSize();
 	m_dumpFilename.sprintf(pool, "%s/VkPipelineCache", &cacheDir[0]);
 
 	// Try read the pipeline cache file.

+ 1 - 4
AnKi/Gr/Vulkan/PipelineCache.h

@@ -9,9 +9,6 @@
 
 namespace anki {
 
-// Forward
-class ConfigSet;
-
 /// @addtogroup vulkan
 /// @{
 
@@ -21,7 +18,7 @@ class PipelineCache
 public:
 	VkPipelineCache m_cacheHandle = VK_NULL_HANDLE;
 
-	Error init(VkDevice dev, VkPhysicalDevice pdev, CString cacheDir, const ConfigSet& cfg, HeapMemoryPool& pool);
+	Error init(VkDevice dev, VkPhysicalDevice pdev, CString cacheDir, HeapMemoryPool& pool);
 
 	void destroy(VkDevice dev, VkPhysicalDevice pdev, HeapMemoryPool& pool);
 

+ 13 - 13
AnKi/Renderer/Bloom.cpp

@@ -44,13 +44,13 @@ Error Bloom::initExposure()
 	m_exposure.m_rtDescr.bake();
 
 	// init shaders
-	ANKI_CHECK(getExternalSubsystems().m_resourceManager->loadResource(
-		(getExternalSubsystems().m_config->getRPreferCompute()) ? "ShaderBinaries/BloomCompute.ankiprogbin"
-																: "ShaderBinaries/BloomRaster.ankiprogbin",
-		m_exposure.m_prog));
+	ANKI_CHECK(getExternalSubsystems().m_resourceManager->loadResource((ConfigSet::getSingleton().getRPreferCompute())
+																		   ? "ShaderBinaries/BloomCompute.ankiprogbin"
+																		   : "ShaderBinaries/BloomRaster.ankiprogbin",
+																	   m_exposure.m_prog));
 
 	ShaderProgramResourceVariantInitInfo variantInitInfo(m_exposure.m_prog);
-	if(getExternalSubsystems().m_config->getRPreferCompute())
+	if(ConfigSet::getSingleton().getRPreferCompute())
 	{
 		variantInitInfo.addConstant("kViewport", UVec2(m_exposure.m_width, m_exposure.m_height));
 	}
@@ -74,13 +74,13 @@ Error Bloom::initUpscale()
 
 	// init shaders
 	ANKI_CHECK(getExternalSubsystems().m_resourceManager->loadResource(
-		(getExternalSubsystems().m_config->getRPreferCompute()) ? "ShaderBinaries/BloomUpscaleCompute.ankiprogbin"
-																: "ShaderBinaries/BloomUpscaleRaster.ankiprogbin",
+		(ConfigSet::getSingleton().getRPreferCompute()) ? "ShaderBinaries/BloomUpscaleCompute.ankiprogbin"
+														: "ShaderBinaries/BloomUpscaleRaster.ankiprogbin",
 		m_upscale.m_prog));
 
 	ShaderProgramResourceVariantInitInfo variantInitInfo(m_upscale.m_prog);
 	variantInitInfo.addConstant("kInputTextureSize", UVec2(m_exposure.m_width, m_exposure.m_height));
-	if(getExternalSubsystems().m_config->getRPreferCompute())
+	if(ConfigSet::getSingleton().getRPreferCompute())
 	{
 		variantInitInfo.addConstant("kViewport", UVec2(m_upscale.m_width, m_upscale.m_height));
 	}
@@ -99,7 +99,7 @@ Error Bloom::initUpscale()
 void Bloom::populateRenderGraph(RenderingContext& ctx)
 {
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
-	const Bool preferCompute = getExternalSubsystems().m_config->getRPreferCompute();
+	const Bool preferCompute = ConfigSet::getSingleton().getRPreferCompute();
 
 	// Main pass
 	{
@@ -144,13 +144,13 @@ void Bloom::populateRenderGraph(RenderingContext& ctx)
 			cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
 			rgraphCtx.bindTexture(0, 1, m_r->getDownscaleBlur().getRt(), inputTexSubresource);
 
-			const Vec4 uniforms(getExternalSubsystems().m_config->getRBloomThreshold(),
-								getExternalSubsystems().m_config->getRBloomScale(), 0.0f, 0.0f);
+			const Vec4 uniforms(ConfigSet::getSingleton().getRBloomThreshold(),
+								ConfigSet::getSingleton().getRBloomScale(), 0.0f, 0.0f);
 			cmdb->setPushConstants(&uniforms, sizeof(uniforms));
 
 			rgraphCtx.bindImage(0, 2, m_r->getTonemapping().getRt());
 
-			if(getExternalSubsystems().m_config->getRPreferCompute())
+			if(ConfigSet::getSingleton().getRPreferCompute())
 			{
 				rgraphCtx.bindImage(0, 3, m_runCtx.m_exposureRt, TextureSubresourceInfo());
 
@@ -201,7 +201,7 @@ void Bloom::populateRenderGraph(RenderingContext& ctx)
 			rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_exposureRt);
 			cmdb->bindTexture(0, 2, m_upscale.m_lensDirtImage->getTextureView());
 
-			if(getExternalSubsystems().m_config->getRPreferCompute())
+			if(ConfigSet::getSingleton().getRPreferCompute())
 			{
 				rgraphCtx.bindImage(0, 3, m_runCtx.m_upscaleRt, TextureSubresourceInfo());
 

+ 0 - 1
AnKi/Renderer/Common.h

@@ -80,7 +80,6 @@ public:
 	GrManager* m_grManager = nullptr;
 	RebarStagingGpuMemoryPool* m_rebarStagingPool = nullptr;
 	UiManager* m_uiManager = nullptr;
-	ConfigSet* m_config = nullptr;
 	Timestamp* m_globTimestamp = nullptr;
 	GpuSceneMemoryPool* m_gpuScenePool = nullptr;
 	GpuSceneMicroPatcher* m_gpuSceneMicroPatcher = nullptr;

+ 3 - 3
AnKi/Renderer/Dbg.cpp

@@ -57,7 +57,7 @@ Error Dbg::init()
 
 void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 {
-	ANKI_ASSERT(getExternalSubsystems().m_config->getRDbg());
+	ANKI_ASSERT(ConfigSet::getSingleton().getRDbg());
 
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
@@ -229,7 +229,7 @@ void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 		}
 	}
 
-	if(threadId == (threadCount - 1) && getExternalSubsystems().m_config->getRDbgPhysics())
+	if(threadId == (threadCount - 1) && ConfigSet::getSingleton().getRDbgPhysics())
 	{
 		m_physicsDrawer.start(ctx.m_matrices.m_viewProjection, cmdb, &rebar);
 		m_physicsDrawer.drawWorld(PhysicsWorld::getSingleton());
@@ -242,7 +242,7 @@ void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 
 void Dbg::populateRenderGraph(RenderingContext& ctx)
 {
-	if(!getExternalSubsystems().m_config->getRDbg())
+	if(!ConfigSet::getSingleton().getRDbg())
 	{
 		return;
 	}

+ 2 - 2
AnKi/Renderer/DepthDownscale.cpp

@@ -50,7 +50,7 @@ Error DepthDownscale::initInternal()
 	ANKI_R_LOGV("Initializing HiZ. Mip count %u, last mip size %ux%u", m_mipCount, m_lastMipSize.x(),
 				m_lastMipSize.y());
 
-	const Bool preferCompute = getExternalSubsystems().m_config->getRPreferCompute();
+	const Bool preferCompute = ConfigSet::getSingleton().getRPreferCompute();
 	const Bool supportsReductionSampler =
 		getExternalSubsystems().m_grManager->getDeviceCapabilities().m_samplingFilterMinMax;
 
@@ -185,7 +185,7 @@ void DepthDownscale::populateRenderGraph(RenderingContext& ctx)
 {
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
-	if(getExternalSubsystems().m_config->getRPreferCompute())
+	if(ConfigSet::getSingleton().getRPreferCompute())
 	{
 		// Do it with compute
 

+ 3 - 3
AnKi/Renderer/DownscaleBlur.cpp

@@ -36,7 +36,7 @@ Error DownscaleBlur::initInternal()
 	const UVec2 rez = m_r->getPostProcessResolution() / 2;
 	ANKI_R_LOGV("Initializing downscale pyramid. Resolution %ux%u, mip count %u", rez.x(), rez.y(), m_passCount);
 
-	const Bool preferCompute = getExternalSubsystems().m_config->getRPreferCompute();
+	const Bool preferCompute = ConfigSet::getSingleton().getRPreferCompute();
 
 	// Create the miped texture
 	TextureInitInfo texinit =
@@ -92,7 +92,7 @@ void DownscaleBlur::populateRenderGraph(RenderingContext& ctx)
 													"Down/Blur #4", "Down/Blur #5", "Down/Blur #6", "Down/Blur #7"};
 	const RenderTargetHandle inRt =
 		(m_r->getScale().hasUpscaledHdrRt()) ? m_r->getScale().getUpscaledHdrRt() : m_r->getScale().getTonemappedRt();
-	if(getExternalSubsystems().m_config->getRPreferCompute())
+	if(ConfigSet::getSingleton().getRPreferCompute())
 	{
 		for(U32 i = 0; i < m_passCount; ++i)
 		{
@@ -183,7 +183,7 @@ void DownscaleBlur::run(U32 passIdx, RenderPassWorkContext& rgraphCtx)
 	const UVec4 fbSize(vpWidth, vpHeight, revertTonemap, 0);
 	cmdb->setPushConstants(&fbSize, sizeof(fbSize));
 
-	if(getExternalSubsystems().m_config->getRPreferCompute())
+	if(ConfigSet::getSingleton().getRPreferCompute())
 	{
 		TextureSubresourceInfo sampleSubresource;
 		sampleSubresource.m_firstMipmap = passIdx;

+ 5 - 6
AnKi/Renderer/FinalComposite.cpp

@@ -42,12 +42,11 @@ Error FinalComposite::initInternal()
 		getExternalSubsystems().m_resourceManager->loadResource("ShaderBinaries/FinalComposite.ankiprogbin", m_prog));
 
 	ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
-	variantInitInfo.addMutation("FILM_GRAIN",
-								(getExternalSubsystems().m_config->getRFilmGrainStrength() > 0.0) ? 1 : 0);
+	variantInitInfo.addMutation("FILM_GRAIN", (ConfigSet::getSingleton().getRFilmGrainStrength() > 0.0) ? 1 : 0);
 	variantInitInfo.addMutation("BLOOM_ENABLED", 1);
 	variantInitInfo.addConstant("kLutSize", U32(kLutSize));
 	variantInitInfo.addConstant("kFramebufferSize", m_r->getPostProcessResolution());
-	variantInitInfo.addConstant("kMotionBlurSamples", getExternalSubsystems().m_config->getRMotionBlurSamples());
+	variantInitInfo.addConstant("kMotionBlurSamples", ConfigSet::getSingleton().getRMotionBlurSamples());
 
 	for(U32 dbg = 0; dbg < 2; ++dbg)
 	{
@@ -102,7 +101,7 @@ void FinalComposite::populateRenderGraph(RenderingContext& ctx)
 
 	pass.newTextureDependency(ctx.m_outRenderTarget, TextureUsageBit::kFramebufferWrite);
 
-	if(getExternalSubsystems().m_config->getRDbg())
+	if(ConfigSet::getSingleton().getRDbg())
 	{
 		pass.newTextureDependency(m_r->getDbg().getRt(), TextureUsageBit::kSampledFragment);
 	}
@@ -130,7 +129,7 @@ void FinalComposite::populateRenderGraph(RenderingContext& ctx)
 void FinalComposite::run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
-	const Bool dbgEnabled = getExternalSubsystems().m_config->getRDbg();
+	const Bool dbgEnabled = ConfigSet::getSingleton().getRDbg();
 
 	Array<RenderTargetHandle, kMaxDebugRenderTargets> dbgRts;
 	ShaderProgramPtr optionalDebugProgram;
@@ -170,7 +169,7 @@ void FinalComposite::run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx
 			rgraphCtx.bindColorTexture(0, 8, m_r->getDbg().getRt());
 		}
 
-		const UVec4 pc(0, 0, floatBitsToUint(getExternalSubsystems().m_config->getRFilmGrainStrength()),
+		const UVec4 pc(0, 0, floatBitsToUint(ConfigSet::getSingleton().getRFilmGrainStrength()),
 					   m_r->getFrameCount() & kMaxU32);
 		cmdb->setPushConstants(&pc, sizeof(pc));
 	}

+ 3 - 6
AnKi/Renderer/GBuffer.cpp

@@ -76,8 +76,7 @@ Error GBuffer::initInternal()
 	m_fbDescr.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 1.0f;
 	m_fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::kDepth;
 
-	if(getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs
-	   && getExternalSubsystems().m_config->getRVrs())
+	if(getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs && ConfigSet::getSingleton().getRVrs())
 	{
 		m_fbDescr.m_shadingRateAttachmentTexelWidth = m_r->getVrsSriGeneration().getSriTexelDimension();
 		m_fbDescr.m_shadingRateAttachmentTexelHeight = m_r->getVrsSriGeneration().getSriTexelDimension();
@@ -114,8 +113,7 @@ void GBuffer::runInThread(const RenderingContext& ctx, RenderPassWorkContext& rg
 	cmdb->setRasterizationOrder(RasterizationOrder::kRelaxed);
 
 	const Bool enableVrs = getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs
-						   && getExternalSubsystems().m_config->getRVrs()
-						   && getExternalSubsystems().m_config->getRGBufferVrs();
+						   && ConfigSet::getSingleton().getRVrs() && ConfigSet::getSingleton().getRGBufferVrs();
 	if(enableVrs)
 	{
 		// Just set some low value, the attachment will take over
@@ -171,8 +169,7 @@ void GBuffer::populateRenderGraph(RenderingContext& ctx)
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 	const Bool enableVrs = getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs
-						   && getExternalSubsystems().m_config->getRVrs()
-						   && getExternalSubsystems().m_config->getRGBufferVrs();
+						   && ConfigSet::getSingleton().getRVrs() && ConfigSet::getSingleton().getRGBufferVrs();
 	const Bool fbDescrHasVrs = m_fbDescr.m_shadingRateAttachmentTexelWidth > 0;
 
 	if(enableVrs != fbDescrHasVrs)

+ 16 - 16
AnKi/Renderer/IndirectDiffuse.cpp

@@ -37,7 +37,7 @@ Error IndirectDiffuse::initInternal()
 
 	ANKI_R_LOGV("Initializing indirect diffuse. Resolution %ux%u", size.x(), size.y());
 
-	const Bool preferCompute = getExternalSubsystems().m_config->getRPreferCompute();
+	const Bool preferCompute = ConfigSet::getSingleton().getRPreferCompute();
 
 	// Init textures
 	TextureUsageBit usage = TextureUsageBit::kAllSampled;
@@ -57,7 +57,7 @@ Error IndirectDiffuse::initInternal()
 
 	// Init VRS SRI generation
 	const Bool enableVrs = getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs
-						   && getExternalSubsystems().m_config->getRVrs() && !preferCompute;
+						   && ConfigSet::getSingleton().getRVrs() && !preferCompute;
 	if(enableVrs)
 	{
 		m_vrs.m_sriTexelDimension =
@@ -94,7 +94,7 @@ Error IndirectDiffuse::initInternal()
 			variantInit.addMutation("SHARED_MEMORY", 1);
 		}
 
-		variantInit.addMutation("LIMIT_RATE_TO_2X2", getExternalSubsystems().m_config->getRVrsLimitTo2x2());
+		variantInit.addMutation("LIMIT_RATE_TO_2X2", ConfigSet::getSingleton().getRVrsLimitTo2x2());
 
 		const ShaderProgramResourceVariant* variant;
 		m_vrs.m_prog->getOrCreateVariant(variantInit, variant);
@@ -145,9 +145,9 @@ Error IndirectDiffuse::initInternal()
 void IndirectDiffuse::populateRenderGraph(RenderingContext& ctx)
 {
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
-	const Bool preferCompute = getExternalSubsystems().m_config->getRPreferCompute();
+	const Bool preferCompute = ConfigSet::getSingleton().getRPreferCompute();
 	const Bool enableVrs = getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs
-						   && getExternalSubsystems().m_config->getRVrs() && !preferCompute;
+						   && ConfigSet::getSingleton().getRVrs() && !preferCompute;
 	const Bool fbDescrHasVrs = m_main.m_fbDescr.m_shadingRateAttachmentTexelWidth > 0;
 
 	if(!preferCompute && enableVrs != fbDescrHasVrs)
@@ -197,8 +197,8 @@ void IndirectDiffuse::populateRenderGraph(RenderingContext& ctx)
 				Mat4 m_invertedProjectionJitter;
 			} pc;
 
-			pc.m_v4 = Vec4(1.0f / Vec2(viewport),
-						   getExternalSubsystems().m_config->getRIndirectDiffuseVrsDistanceThreshold(), 0.0f);
+			pc.m_v4 =
+				Vec4(1.0f / Vec2(viewport), ConfigSet::getSingleton().getRIndirectDiffuseVrsDistanceThreshold(), 0.0f);
 			pc.m_invertedProjectionJitter = ctx.m_matrices.m_invertedProjectionJitter;
 
 			cmdb->setPushConstants(&pc, sizeof(pc));
@@ -286,7 +286,7 @@ void IndirectDiffuse::populateRenderGraph(RenderingContext& ctx)
 			rgraphCtx.bindColorTexture(0, 8, m_r->getMotionVectors().getMotionVectorsRt());
 			rgraphCtx.bindColorTexture(0, 9, m_r->getMotionVectors().getHistoryLengthRt());
 
-			if(getExternalSubsystems().m_config->getRPreferCompute())
+			if(ConfigSet::getSingleton().getRPreferCompute())
 			{
 				rgraphCtx.bindImage(0, 10, m_runCtx.m_mainRtHandles[kWrite]);
 			}
@@ -299,14 +299,14 @@ void IndirectDiffuse::populateRenderGraph(RenderingContext& ctx)
 			unis.m_viewportSizef = Vec2(unis.m_viewportSize);
 			const Mat4& pmat = ctx.m_matrices.m_projection;
 			unis.m_projectionMat = Vec4(pmat(0, 0), pmat(1, 1), pmat(2, 2), pmat(2, 3));
-			unis.m_radius = getExternalSubsystems().m_config->getRIndirectDiffuseSsgiRadius();
-			unis.m_sampleCount = getExternalSubsystems().m_config->getRIndirectDiffuseSsgiSampleCount();
+			unis.m_radius = ConfigSet::getSingleton().getRIndirectDiffuseSsgiRadius();
+			unis.m_sampleCount = ConfigSet::getSingleton().getRIndirectDiffuseSsgiSampleCount();
 			unis.m_sampleCountf = F32(unis.m_sampleCount);
-			unis.m_ssaoBias = getExternalSubsystems().m_config->getRIndirectDiffuseSsaoBias();
-			unis.m_ssaoStrength = getExternalSubsystems().m_config->getRIndirectDiffuseSsaoStrength();
+			unis.m_ssaoBias = ConfigSet::getSingleton().getRIndirectDiffuseSsaoBias();
+			unis.m_ssaoStrength = ConfigSet::getSingleton().getRIndirectDiffuseSsaoStrength();
 			cmdb->setPushConstants(&unis, sizeof(unis));
 
-			if(getExternalSubsystems().m_config->getRPreferCompute())
+			if(ConfigSet::getSingleton().getRPreferCompute())
 			{
 				dispatchPPCompute(cmdb, 8, 8, unis.m_viewportSize.x(), unis.m_viewportSize.y());
 			}
@@ -367,7 +367,7 @@ void IndirectDiffuse::populateRenderGraph(RenderingContext& ctx)
 			hizSubresource.m_mipmapCount = 1;
 			rgraphCtx.bindTexture(0, 2, m_r->getDepthDownscale().getHiZRt(), hizSubresource);
 
-			if(getExternalSubsystems().m_config->getRPreferCompute())
+			if(ConfigSet::getSingleton().getRPreferCompute())
 			{
 				rgraphCtx.bindImage(0, 3, m_runCtx.m_mainRtHandles[!readIdx]);
 			}
@@ -376,12 +376,12 @@ void IndirectDiffuse::populateRenderGraph(RenderingContext& ctx)
 			unis.m_invertedViewProjectionJitterMat = ctx.m_matrices.m_invertedViewProjectionJitter;
 			unis.m_viewportSize = m_r->getInternalResolution() / 2u;
 			unis.m_viewportSizef = Vec2(unis.m_viewportSize);
-			unis.m_sampleCountDiv2 = F32(getExternalSubsystems().m_config->getRIndirectDiffuseDenoiseSampleCount());
+			unis.m_sampleCountDiv2 = F32(ConfigSet::getSingleton().getRIndirectDiffuseDenoiseSampleCount());
 			unis.m_sampleCountDiv2 = max(1.0f, std::round(unis.m_sampleCountDiv2 / 2.0f));
 
 			cmdb->setPushConstants(&unis, sizeof(unis));
 
-			if(getExternalSubsystems().m_config->getRPreferCompute())
+			if(ConfigSet::getSingleton().getRPreferCompute())
 			{
 				dispatchPPCompute(cmdb, 8, 8, unis.m_viewportSize.x(), unis.m_viewportSize.y());
 			}

+ 2 - 2
AnKi/Renderer/IndirectDiffuseProbes.cpp

@@ -64,7 +64,7 @@ Error IndirectDiffuseProbes::init()
 
 Error IndirectDiffuseProbes::initInternal()
 {
-	m_tileSize = getExternalSubsystems().m_config->getRIndirectDiffuseProbeTileResolution();
+	m_tileSize = ConfigSet::getSingleton().getRIndirectDiffuseProbeTileResolution();
 
 	ANKI_CHECK(initGBuffer());
 	ANKI_CHECK(initLightShading());
@@ -119,7 +119,7 @@ Error IndirectDiffuseProbes::initGBuffer()
 
 Error IndirectDiffuseProbes::initShadowMapping()
 {
-	const U32 resolution = getExternalSubsystems().m_config->getRIndirectDiffuseProbeShadowMapResolution();
+	const U32 resolution = ConfigSet::getSingleton().getRIndirectDiffuseProbeShadowMapResolution();
 	ANKI_ASSERT(resolution > 8);
 
 	// RT descr

+ 12 - 12
AnKi/Renderer/IndirectSpecular.cpp

@@ -35,7 +35,7 @@ Error IndirectSpecular::init()
 Error IndirectSpecular::initInternal()
 {
 	const UVec2 size = m_r->getInternalResolution() / 2;
-	const Bool preferCompute = getExternalSubsystems().m_config->getRPreferCompute();
+	const Bool preferCompute = ConfigSet::getSingleton().getRPreferCompute();
 
 	ANKI_R_LOGV("Initializing indirect specular. Resolution %ux%u", size.x(), size.y());
 
@@ -58,13 +58,13 @@ Error IndirectSpecular::initInternal()
 
 	// Create shader
 	ANKI_CHECK(getExternalSubsystems().m_resourceManager->loadResource(
-		(getExternalSubsystems().m_config->getRPreferCompute()) ? "ShaderBinaries/IndirectSpecularCompute.ankiprogbin"
-																: "ShaderBinaries/IndirectSpecularRaster.ankiprogbin",
+		(ConfigSet::getSingleton().getRPreferCompute()) ? "ShaderBinaries/IndirectSpecularCompute.ankiprogbin"
+														: "ShaderBinaries/IndirectSpecularRaster.ankiprogbin",
 		m_prog));
 
 	ShaderProgramResourceVariantInitInfo variantInit(m_prog);
 	variantInit.addMutation("EXTRA_REJECTION", false);
-	variantInit.addMutation("STOCHASTIC", getExternalSubsystems().m_config->getRSsrStochastic());
+	variantInit.addMutation("STOCHASTIC", ConfigSet::getSingleton().getRSsrStochastic());
 	const ShaderProgramResourceVariant* variant;
 	m_prog->getOrCreateVariant(variantInit, variant);
 	m_grProg = variant->getProgram();
@@ -75,9 +75,9 @@ Error IndirectSpecular::initInternal()
 void IndirectSpecular::populateRenderGraph(RenderingContext& ctx)
 {
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
-	const Bool preferCompute = getExternalSubsystems().m_config->getRPreferCompute();
+	const Bool preferCompute = ConfigSet::getSingleton().getRPreferCompute();
 	const Bool enableVrs = getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs
-						   && getExternalSubsystems().m_config->getRVrs() && !preferCompute;
+						   && ConfigSet::getSingleton().getRVrs() && !preferCompute;
 	const Bool fbDescrHasVrs = m_fbDescr.m_shadingRateAttachmentTexelWidth > 0;
 
 	// Create/import RTs
@@ -152,7 +152,7 @@ void IndirectSpecular::populateRenderGraph(RenderingContext& ctx)
 
 		TextureSubresourceInfo hizSubresource;
 		hizSubresource.m_mipmapCount =
-			min(getExternalSubsystems().m_config->getRSsrDepthLod() + 1, m_r->getDepthDownscale().getMipmapCount());
+			min(ConfigSet::getSingleton().getRSsrDepthLod() + 1, m_r->getDepthDownscale().getMipmapCount());
 		ppass->newTextureDependency(m_r->getDepthDownscale().getHiZRt(), readUsage, hizSubresource);
 
 		if(m_r->getProbeReflections().getHasCurrentlyRefreshedReflectionRt())
@@ -175,7 +175,7 @@ void IndirectSpecular::run(const RenderingContext& ctx, RenderPassWorkContext& r
 	cmdb->bindShaderProgram(m_grProg);
 
 	const U32 depthLod =
-		min(getExternalSubsystems().m_config->getRSsrDepthLod(), m_r->getDepthDownscale().getMipmapCount() - 1);
+		min(ConfigSet::getSingleton().getRSsrDepthLod(), m_r->getDepthDownscale().getMipmapCount() - 1);
 
 	// Bind uniforms
 	SsrUniforms* unis = allocateAndBindUniforms<SsrUniforms*>(sizeof(SsrUniforms), cmdb, 0, 0);
@@ -183,15 +183,15 @@ void IndirectSpecular::run(const RenderingContext& ctx, RenderPassWorkContext& r
 	unis->m_framebufferSize = UVec2(m_r->getInternalResolution().x(), m_r->getInternalResolution().y()) / 2;
 	unis->m_frameCount = m_r->getFrameCount() & kMaxU32;
 	unis->m_depthMipCount = m_r->getDepthDownscale().getMipmapCount();
-	unis->m_maxSteps = getExternalSubsystems().m_config->getRSsrMaxSteps();
+	unis->m_maxSteps = ConfigSet::getSingleton().getRSsrMaxSteps();
 	unis->m_lightBufferMipCount = m_r->getDownscaleBlur().getMipmapCount();
-	unis->m_firstStepPixels = getExternalSubsystems().m_config->getRSsrFirstStepPixels();
+	unis->m_firstStepPixels = ConfigSet::getSingleton().getRSsrFirstStepPixels();
 	unis->m_prevViewProjMatMulInvViewProjMat =
 		ctx.m_prevMatrices.m_viewProjection * ctx.m_matrices.m_viewProjectionJitter.getInverse();
 	unis->m_projMat = ctx.m_matrices.m_projectionJitter;
 	unis->m_invProjMat = ctx.m_matrices.m_projectionJitter.getInverse();
 	unis->m_normalMat = Mat3x4(Vec3(0.0f), ctx.m_matrices.m_view.getRotationPart());
-	unis->m_roughnessCutoff = getExternalSubsystems().m_config->getRSsrRoughnessCutoff();
+	unis->m_roughnessCutoff = ConfigSet::getSingleton().getRSsrRoughnessCutoff();
 
 	// Bind all
 	cmdb->bindSampler(0, 1, m_r->getSamplers().m_trilinearClamp);
@@ -218,7 +218,7 @@ void IndirectSpecular::run(const RenderingContext& ctx, RenderPassWorkContext& r
 
 	cmdb->bindAllBindless(1);
 
-	if(getExternalSubsystems().m_config->getRPreferCompute())
+	if(ConfigSet::getSingleton().getRPreferCompute())
 	{
 		rgraphCtx.bindImage(0, 14, m_runCtx.m_rts[kWrite], TextureSubresourceInfo());
 

+ 2 - 2
AnKi/Renderer/LensFlare.cpp

@@ -39,8 +39,8 @@ Error LensFlare::initInternal()
 
 Error LensFlare::initSprite()
 {
-	m_maxSpritesPerFlare = getExternalSubsystems().m_config->getRLensFlareMaxSpritesPerFlare();
-	m_maxFlares = getExternalSubsystems().m_config->getRLensFlareMaxFlares();
+	m_maxSpritesPerFlare = ConfigSet::getSingleton().getRLensFlareMaxSpritesPerFlare();
+	m_maxFlares = ConfigSet::getSingleton().getRLensFlareMaxFlares();
 
 	if(m_maxSpritesPerFlare < 1 || m_maxFlares < 1)
 	{

+ 5 - 6
AnKi/Renderer/LightShading.cpp

@@ -93,8 +93,7 @@ Error LightShading::initLightShading()
 	m_lightShading.m_fbDescr.m_depthStencilAttachment.m_stencilLoadOperation = AttachmentLoadOperation::kDontCare;
 	m_lightShading.m_fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::kDepth;
 
-	if(getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs
-	   && getExternalSubsystems().m_config->getRVrs())
+	if(getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs && ConfigSet::getSingleton().getRVrs())
 	{
 		m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelWidth = m_r->getVrsSriGeneration().getSriTexelDimension();
 		m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelHeight = m_r->getVrsSriGeneration().getSriTexelDimension();
@@ -162,8 +161,8 @@ void LightShading::run(const RenderingContext& ctx, RenderPassWorkContext& rgrap
 
 	cmdb->setViewport(0, 0, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
 
-	const Bool enableVrs = getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs
-						   && getExternalSubsystems().m_config->getRVrs();
+	const Bool enableVrs =
+		getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs && ConfigSet::getSingleton().getRVrs();
 	if(enableVrs)
 	{
 		// Just set some low value, the attachment will take over
@@ -332,8 +331,8 @@ void LightShading::populateRenderGraph(RenderingContext& ctx)
 {
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
-	const Bool enableVrs = getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs
-						   && getExternalSubsystems().m_config->getRVrs();
+	const Bool enableVrs =
+		getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs && ConfigSet::getSingleton().getRVrs();
 	const Bool fbDescrHasVrs = m_lightShading.m_fbDescr.m_shadingRateAttachmentTexelWidth > 0;
 
 	if(enableVrs != fbDescrHasVrs)

+ 2 - 2
AnKi/Renderer/MainRenderer.cpp

@@ -35,7 +35,7 @@ Error MainRenderer::init(const MainRendererInitInfo& inf)
 
 	// Init renderer and manipulate the width/height
 	m_swapchainResolution = inf.m_swapchainSize;
-	m_rDrawToDefaultFb = inf.m_config->getRRenderScaling() == 1.0f;
+	m_rDrawToDefaultFb = ConfigSet::getSingleton().getRRenderScaling() == 1.0f;
 
 	ANKI_R_LOGI("Initializing main renderer. Swapchain resolution %ux%u", m_swapchainResolution.x(),
 				m_swapchainResolution.y());
@@ -52,7 +52,7 @@ Error MainRenderer::init(const MainRendererInitInfo& inf)
 		m_blitGrProg = variant->getProgram();
 
 		// The RT desc
-		UVec2 resolution = UVec2(Vec2(m_swapchainResolution) * inf.m_config->getRRenderScaling());
+		UVec2 resolution = UVec2(Vec2(m_swapchainResolution) * ConfigSet::getSingleton().getRRenderScaling());
 		alignRoundDown(2, resolution.x());
 		alignRoundDown(2, resolution.y());
 		m_tmpRtDesc = m_r->create2DRenderTargetDescription(

+ 6 - 6
AnKi/Renderer/MotionVectors.cpp

@@ -31,8 +31,8 @@ Error MotionVectors::initInternal()
 
 	// Prog
 	ANKI_CHECK(getExternalSubsystems().m_resourceManager->loadResource(
-		(getExternalSubsystems().m_config->getRPreferCompute()) ? "ShaderBinaries/MotionVectorsCompute.ankiprogbin"
-																: "ShaderBinaries/MotionVectorsRaster.ankiprogbin",
+		(ConfigSet::getSingleton().getRPreferCompute()) ? "ShaderBinaries/MotionVectorsCompute.ankiprogbin"
+														: "ShaderBinaries/MotionVectorsRaster.ankiprogbin",
 		m_prog));
 	ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
 	variantInitInfo.addConstant("kFramebufferSize",
@@ -47,7 +47,7 @@ Error MotionVectors::initInternal()
 	m_motionVectorsRtDescr.bake();
 
 	TextureUsageBit historyLengthUsage = TextureUsageBit::kAllSampled;
-	if(getExternalSubsystems().m_config->getRPreferCompute())
+	if(ConfigSet::getSingleton().getRPreferCompute())
 	{
 		historyLengthUsage |= TextureUsageBit::kImageComputeWrite;
 	}
@@ -97,7 +97,7 @@ void MotionVectors::populateRenderGraph(RenderingContext& ctx)
 	RenderPassDescriptionBase* ppass;
 	TextureUsageBit readUsage;
 	TextureUsageBit writeUsage;
-	if(getExternalSubsystems().m_config->getRPreferCompute())
+	if(ConfigSet::getSingleton().getRPreferCompute())
 	{
 		ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("MotionVectors");
 
@@ -153,13 +153,13 @@ void MotionVectors::run(const RenderingContext& ctx, RenderPassWorkContext& rgra
 	pc->m_viewProjectionInvMat = ctx.m_matrices.m_invertedViewProjectionJitter;
 	pc->m_prevViewProjectionInvMat = ctx.m_prevMatrices.m_invertedViewProjectionJitter;
 
-	if(getExternalSubsystems().m_config->getRPreferCompute())
+	if(ConfigSet::getSingleton().getRPreferCompute())
 	{
 		rgraphCtx.bindImage(0, 6, m_runCtx.m_motionVectorsRtHandle, TextureSubresourceInfo());
 		rgraphCtx.bindImage(0, 7, m_runCtx.m_historyLengthWriteRtHandle, TextureSubresourceInfo());
 	}
 
-	if(getExternalSubsystems().m_config->getRPreferCompute())
+	if(ConfigSet::getSingleton().getRPreferCompute())
 	{
 		dispatchPPCompute(cmdb, 8, 8, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
 	}

+ 4 - 4
AnKi/Renderer/ProbeReflections.cpp

@@ -62,7 +62,7 @@ Error ProbeReflections::initInternal()
 
 Error ProbeReflections::initGBuffer()
 {
-	m_gbuffer.m_tileSize = getExternalSubsystems().m_config->getSceneReflectionProbeResolution();
+	m_gbuffer.m_tileSize = ConfigSet::getSingleton().getSceneReflectionProbeResolution();
 
 	// Create RT descriptions
 	{
@@ -107,7 +107,7 @@ Error ProbeReflections::initGBuffer()
 
 Error ProbeReflections::initLightShading()
 {
-	m_lightShading.m_tileSize = getExternalSubsystems().m_config->getSceneReflectionProbeResolution();
+	m_lightShading.m_tileSize = ConfigSet::getSingleton().getSceneReflectionProbeResolution();
 	m_lightShading.m_mipCount = computeMaxMipmapCount2d(m_lightShading.m_tileSize, m_lightShading.m_tileSize, 8);
 
 	for(U32 faceIdx = 0; faceIdx < 6; ++faceIdx)
@@ -129,7 +129,7 @@ Error ProbeReflections::initLightShading()
 
 Error ProbeReflections::initIrradiance()
 {
-	m_irradiance.m_workgroupSize = getExternalSubsystems().m_config->getRProbeReflectionIrradianceResolution();
+	m_irradiance.m_workgroupSize = ConfigSet::getSingleton().getRProbeReflectionIrradianceResolution();
 
 	// Create prog
 	{
@@ -175,7 +175,7 @@ Error ProbeReflections::initIrradianceToRefl()
 
 Error ProbeReflections::initShadowMapping()
 {
-	const U32 resolution = getExternalSubsystems().m_config->getRProbeReflectionShadowMapResolution();
+	const U32 resolution = ConfigSet::getSingleton().getRProbeReflectionShadowMapResolution();
 	ANKI_ASSERT(resolution > 8);
 
 	// RT descr

+ 7 - 7
AnKi/Renderer/Renderer.cpp

@@ -115,11 +115,11 @@ Error Renderer::initInternal(UVec2 swapchainResolution)
 	m_frameCount = 0;
 
 	// Set from the config
-	m_postProcessResolution = UVec2(Vec2(swapchainResolution) * m_subsystems.m_config->getRRenderScaling());
+	m_postProcessResolution = UVec2(Vec2(swapchainResolution) * ConfigSet::getSingleton().getRRenderScaling());
 	alignRoundDown(2, m_postProcessResolution.x());
 	alignRoundDown(2, m_postProcessResolution.y());
 
-	m_internalResolution = UVec2(Vec2(m_postProcessResolution) * m_subsystems.m_config->getRInternalRenderScaling());
+	m_internalResolution = UVec2(Vec2(m_postProcessResolution) * ConfigSet::getSingleton().getRInternalRenderScaling());
 	alignRoundDown(2, m_internalResolution.x());
 	alignRoundDown(2, m_internalResolution.y());
 
@@ -127,10 +127,10 @@ Error Renderer::initInternal(UVec2 swapchainResolution)
 				m_postProcessResolution.x(), m_postProcessResolution.y(), m_internalResolution.x(),
 				m_internalResolution.y());
 
-	m_tileSize = m_subsystems.m_config->getRTileSize();
+	m_tileSize = ConfigSet::getSingleton().getRTileSize();
 	m_tileCounts.x() = (m_internalResolution.x() + m_tileSize - 1) / m_tileSize;
 	m_tileCounts.y() = (m_internalResolution.y() + m_tileSize - 1) / m_tileSize;
-	m_zSplitCount = m_subsystems.m_config->getRZSplitCount();
+	m_zSplitCount = ConfigSet::getSingleton().getRZSplitCount();
 
 	// A few sanity checks
 	if(m_internalResolution.x() < 64 || m_internalResolution.y() < 64)
@@ -234,7 +234,7 @@ Error Renderer::initInternal(UVec2 swapchainResolution)
 	ANKI_CHECK(m_indirectDiffuse->init());
 
 	if(m_subsystems.m_grManager->getDeviceCapabilities().m_rayTracingEnabled
-	   && m_subsystems.m_config->getSceneRayTracedShadows())
+	   && ConfigSet::getSingleton().getSceneRayTracedShadows())
 	{
 		m_accelerationStructureBuilder.reset(newInstance<AccelerationStructureBuilder>(*m_pool, this));
 		ANKI_CHECK(m_accelerationStructureBuilder->init());
@@ -275,7 +275,7 @@ Error Renderer::initInternal(UVec2 swapchainResolution)
 		m_samplers.m_trilinearRepeat = m_subsystems.m_grManager->newSampler(sinit);
 
 		sinit.setName("TrilinearRepeatAniso");
-		sinit.m_anisotropyLevel = m_subsystems.m_config->getRTextureAnisotropy();
+		sinit.m_anisotropyLevel = ConfigSet::getSingleton().getRTextureAnisotropy();
 		m_samplers.m_trilinearRepeatAniso = m_subsystems.m_grManager->newSampler(sinit);
 
 		sinit.setName("TrilinearRepeatAnisoRezScalingBias");
@@ -664,7 +664,7 @@ void Renderer::setCurrentDebugRenderTarget(CString rtName)
 Format Renderer::getHdrFormat() const
 {
 	Format out;
-	if(!m_subsystems.m_config->getRHighQualityHdr())
+	if(!ConfigSet::getSingleton().getRHighQualityHdr())
 	{
 		out = Format::kB10G11R11_Ufloat_Pack32;
 	}

+ 0 - 1
AnKi/Renderer/RendererObject.h

@@ -17,7 +17,6 @@ namespace anki {
 // Forward
 class Renderer;
 class ResourceManager;
-class ConfigSet;
 
 /// @addtogroup renderer
 /// @{

+ 3 - 3
AnKi/Renderer/RtShadows.cpp

@@ -39,8 +39,8 @@ Error RtShadows::initInternal()
 {
 	ANKI_R_LOGV("Initializing RT shadows");
 
-	m_useSvgf = getExternalSubsystems().m_config->getRRtShadowsSvgf();
-	m_atrousPassCount = getExternalSubsystems().m_config->getRRtShadowsSvgfAtrousPassCount();
+	m_useSvgf = ConfigSet::getSingleton().getRRtShadowsSvgf();
+	m_atrousPassCount = ConfigSet::getSingleton().getRRtShadowsSvgfAtrousPassCount();
 
 	ANKI_CHECK(getExternalSubsystems().m_resourceManager->loadResource("EngineAssets/BlueNoise_Rgba8_64x64.png",
 																	   m_blueNoiseImage));
@@ -51,7 +51,7 @@ Error RtShadows::initInternal()
 																		   m_rayGenProg));
 
 		ShaderProgramResourceVariantInitInfo variantInitInfo(m_rayGenProg);
-		variantInitInfo.addMutation("RAYS_PER_PIXEL", getExternalSubsystems().m_config->getRRtShadowsRaysPerPixel());
+		variantInitInfo.addMutation("RAYS_PER_PIXEL", ConfigSet::getSingleton().getRRtShadowsRaysPerPixel());
 
 		const ShaderProgramResourceVariant* variant;
 		m_rayGenProg->getOrCreateVariant(variantInitInfo, variant);

+ 9 - 9
AnKi/Renderer/Scale.cpp

@@ -39,15 +39,15 @@ Scale::~Scale()
 Error Scale::init()
 {
 	const Bool needsScaling = m_r->getPostProcessResolution() != m_r->getInternalResolution();
-	const Bool needsSharpening = getExternalSubsystems().m_config->getRSharpness() > 0.0f;
+	const Bool needsSharpening = ConfigSet::getSingleton().getRSharpness() > 0.0f;
 	if(!needsScaling && !needsSharpening)
 	{
 		return Error::kNone;
 	}
 
-	const Bool preferCompute = getExternalSubsystems().m_config->getRPreferCompute();
-	const U32 dlssQuality = getExternalSubsystems().m_config->getRDlssQuality();
-	const U32 fsrQuality = getExternalSubsystems().m_config->getRFsrQuality();
+	const Bool preferCompute = ConfigSet::getSingleton().getRPreferCompute();
+	const U32 dlssQuality = ConfigSet::getSingleton().getRDlssQuality();
+	const U32 fsrQuality = ConfigSet::getSingleton().getRFsrQuality();
 
 	if(needsScaling)
 	{
@@ -188,7 +188,7 @@ void Scale::populateRenderGraph(RenderingContext& ctx)
 	}
 
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
-	const Bool preferCompute = getExternalSubsystems().m_config->getRPreferCompute();
+	const Bool preferCompute = ConfigSet::getSingleton().getRPreferCompute();
 
 	// Step 1: Upscaling
 	if(m_upscalingMethod == UpscalingMethod::kGr)
@@ -323,7 +323,7 @@ void Scale::populateRenderGraph(RenderingContext& ctx)
 void Scale::runFsrOrBilinearScaling(RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
-	const Bool preferCompute = getExternalSubsystems().m_config->getRPreferCompute();
+	const Bool preferCompute = ConfigSet::getSingleton().getRPreferCompute();
 	const RenderTargetHandle inRt = m_r->getTemporalAA().getTonemappedRt();
 	const RenderTargetHandle outRt = m_runCtx.m_upscaledTonemappedRt;
 
@@ -387,7 +387,7 @@ void Scale::runFsrOrBilinearScaling(RenderPassWorkContext& rgraphCtx)
 void Scale::runRcasSharpening(RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
-	const Bool preferCompute = getExternalSubsystems().m_config->getRPreferCompute();
+	const Bool preferCompute = ConfigSet::getSingleton().getRPreferCompute();
 	const RenderTargetHandle inRt = m_runCtx.m_tonemappedRt;
 	const RenderTargetHandle outRt = m_runCtx.m_sharpenedRt;
 
@@ -412,7 +412,7 @@ void Scale::runRcasSharpening(RenderPassWorkContext& rgraphCtx)
 		UVec2 m_padding;
 	} pc;
 
-	F32 sharpness = getExternalSubsystems().m_config->getRSharpness(); // [0, 1]
+	F32 sharpness = ConfigSet::getSingleton().getRSharpness(); // [0, 1]
 	sharpness *= 3.0f; // [0, 3]
 	sharpness = 3.0f - sharpness; // [3, 0], RCAS translates 0 to max sharpness
 	FsrRcasCon(&pc.m_fsrConsts0[0], sharpness);
@@ -455,7 +455,7 @@ void Scale::runGrUpscaling(RenderingContext& ctx, RenderPassWorkContext& rgraphC
 void Scale::runTonemapping(RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
-	const Bool preferCompute = getExternalSubsystems().m_config->getRPreferCompute();
+	const Bool preferCompute = ConfigSet::getSingleton().getRPreferCompute();
 	const RenderTargetHandle inRt = m_runCtx.m_upscaledHdrRt;
 	const RenderTargetHandle outRt = m_runCtx.m_tonemappedRt;
 

+ 6 - 6
AnKi/Renderer/ShadowMapping.cpp

@@ -51,8 +51,8 @@ Error ShadowMapping::initInternal()
 {
 	// Init RT
 	{
-		m_tileResolution = getExternalSubsystems().m_config->getRShadowMappingTileResolution();
-		m_tileCountBothAxis = getExternalSubsystems().m_config->getRShadowMappingTileCountPerRowOrColumn();
+		m_tileResolution = ConfigSet::getSingleton().getRShadowMappingTileResolution();
+		m_tileCountBothAxis = ConfigSet::getSingleton().getRShadowMappingTileCountPerRowOrColumn();
 
 		ANKI_R_LOGV("Initializing shadowmapping. Atlas resolution %ux%u", m_tileResolution * m_tileCountBothAxis,
 					m_tileResolution * m_tileCountBothAxis);
@@ -156,7 +156,7 @@ void ShadowMapping::chooseDetail(const Vec4& cameraOrigin, const PointLightQueue
 								 U32& tileAllocatorHierarchy, U32& renderQueueElementsLod) const
 {
 	const F32 distFromTheCamera = (cameraOrigin - light.m_worldPosition.xyz0()).getLength() - light.m_radius;
-	if(distFromTheCamera < getExternalSubsystems().m_config->getLod0MaxDistance())
+	if(distFromTheCamera < ConfigSet::getSingleton().getLod0MaxDistance())
 	{
 		tileAllocatorHierarchy = kPointLightMaxTileAllocHierarchy;
 		renderQueueElementsLod = 0;
@@ -182,12 +182,12 @@ void ShadowMapping::chooseDetail(const Vec4& cameraOrigin, const SpotLightQueueE
 	const F32 V1len = V.dot(coneDir);
 	const F32 distFromTheCamera = cos(coneAngle) * sqrt(VlenSq - V1len * V1len) - V1len * sin(coneAngle);
 
-	if(distFromTheCamera < getExternalSubsystems().m_config->getLod0MaxDistance())
+	if(distFromTheCamera < ConfigSet::getSingleton().getLod0MaxDistance())
 	{
 		tileAllocatorHierarchy = kSpotLightMaxTileAllocHierarchy;
 		renderQueueElementsLod = 0;
 	}
-	else if(distFromTheCamera < getExternalSubsystems().m_config->getLod1MaxDistance())
+	else if(distFromTheCamera < ConfigSet::getSingleton().getLod1MaxDistance())
 	{
 		tileAllocatorHierarchy = max(kSpotLightMaxTileAllocHierarchy, 1u) - 1;
 		renderQueueElementsLod = kMaxLodCount - 1;
@@ -415,7 +415,7 @@ void ShadowMapping::processLights(RenderingContext& ctx, U32& threadCountForPass
 
 			// Remove a few texels to avoid bilinear filtering bleeding
 			F32 texelsBorder;
-			if(getExternalSubsystems().m_config->getRShadowMappingPcf())
+			if(ConfigSet::getSingleton().getRShadowMappingPcf())
 			{
 				texelsBorder = 2.0f; // 2 texels
 			}

+ 6 - 6
AnKi/Renderer/ShadowmapsResolve.cpp

@@ -31,7 +31,7 @@ Error ShadowmapsResolve::init()
 
 Error ShadowmapsResolve::initInternal()
 {
-	m_quarterRez = getExternalSubsystems().m_config->getRSmResolveQuarterRez();
+	m_quarterRez = ConfigSet::getSingleton().getRSmResolveQuarterRez();
 	const U32 width = m_r->getInternalResolution().x() / (m_quarterRez + 1);
 	const U32 height = m_r->getInternalResolution().y() / (m_quarterRez + 1);
 
@@ -46,15 +46,15 @@ Error ShadowmapsResolve::initInternal()
 
 	// Prog
 	ANKI_CHECK(getExternalSubsystems().m_resourceManager->loadResource(
-		(getExternalSubsystems().m_config->getRPreferCompute()) ? "ShaderBinaries/ShadowmapsResolveCompute.ankiprogbin"
-																: "ShaderBinaries/ShadowmapsResolveRaster.ankiprogbin",
+		(ConfigSet::getSingleton().getRPreferCompute()) ? "ShaderBinaries/ShadowmapsResolveCompute.ankiprogbin"
+														: "ShaderBinaries/ShadowmapsResolveRaster.ankiprogbin",
 		m_prog));
 	ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
 	variantInitInfo.addConstant("kFramebufferSize", UVec2(width, height));
 	variantInitInfo.addConstant("kTileCount", m_r->getTileCounts());
 	variantInitInfo.addConstant("kZSplitCount", m_r->getZSplitCount());
 	variantInitInfo.addConstant("kTileSize", m_r->getTileSize());
-	variantInitInfo.addMutation("PCF", getExternalSubsystems().m_config->getRShadowMappingPcf());
+	variantInitInfo.addMutation("PCF", ConfigSet::getSingleton().getRShadowMappingPcf());
 	const ShaderProgramResourceVariant* variant;
 	m_prog->getOrCreateVariant(variantInitInfo, variant);
 	m_grProg = variant->getProgram();
@@ -70,7 +70,7 @@ void ShadowmapsResolve::populateRenderGraph(RenderingContext& ctx)
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 	m_runCtx.m_rt = rgraph.newRenderTarget(m_rtDescr);
 
-	if(getExternalSubsystems().m_config->getRPreferCompute())
+	if(ConfigSet::getSingleton().getRPreferCompute())
 	{
 		ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("ResolveShadows");
 
@@ -135,7 +135,7 @@ void ShadowmapsResolve::run(RenderPassWorkContext& rgraphCtx)
 	}
 	cmdb->bindTexture(0, 9, m_noiseImage->getTextureView());
 
-	if(getExternalSubsystems().m_config->getRPreferCompute())
+	if(ConfigSet::getSingleton().getRPreferCompute())
 	{
 		rgraphCtx.bindImage(0, 10, m_runCtx.m_rt, TextureSubresourceInfo());
 		dispatchPPCompute(cmdb, 8, 8, m_rtDescr.m_width, m_rtDescr.m_height);

+ 7 - 7
AnKi/Renderer/TemporalAA.cpp

@@ -38,8 +38,8 @@ Error TemporalAA::initInternal()
 	ANKI_R_LOGV("Initializing TAA");
 
 	ANKI_CHECK(getExternalSubsystems().m_resourceManager->loadResource(
-		(getExternalSubsystems().m_config->getRPreferCompute()) ? "ShaderBinaries/TemporalAACompute.ankiprogbin"
-																: "ShaderBinaries/TemporalAARaster.ankiprogbin",
+		(ConfigSet::getSingleton().getRPreferCompute()) ? "ShaderBinaries/TemporalAACompute.ankiprogbin"
+														: "ShaderBinaries/TemporalAARaster.ankiprogbin",
 		m_prog));
 
 	{
@@ -49,7 +49,7 @@ Error TemporalAA::initInternal()
 		variantInitInfo.addMutation("VARIANCE_CLIPPING", 1);
 		variantInitInfo.addMutation("YCBCR", 0);
 
-		if(getExternalSubsystems().m_config->getRPreferCompute())
+		if(ConfigSet::getSingleton().getRPreferCompute())
 		{
 			variantInitInfo.addConstant("kFramebufferSize",
 										UVec2(m_r->getInternalResolution().x(), m_r->getInternalResolution().y()));
@@ -63,8 +63,8 @@ Error TemporalAA::initInternal()
 	for(U i = 0; i < 2; ++i)
 	{
 		TextureUsageBit usage = TextureUsageBit::kSampledFragment | TextureUsageBit::kSampledCompute;
-		usage |= (getExternalSubsystems().m_config->getRPreferCompute()) ? TextureUsageBit::kImageComputeWrite
-																		 : TextureUsageBit::kFramebufferWrite;
+		usage |= (ConfigSet::getSingleton().getRPreferCompute()) ? TextureUsageBit::kImageComputeWrite
+																 : TextureUsageBit::kFramebufferWrite;
 
 		TextureInitInfo texinit =
 			m_r->create2DRenderTargetInitInfo(m_r->getInternalResolution().x(), m_r->getInternalResolution().y(),
@@ -93,7 +93,7 @@ void TemporalAA::populateRenderGraph(RenderingContext& ctx)
 
 	const U32 historyRtIdx = (m_r->getFrameCount() + 1) & 1;
 	const U32 renderRtIdx = !historyRtIdx;
-	const Bool preferCompute = getExternalSubsystems().m_config->getRPreferCompute();
+	const Bool preferCompute = ConfigSet::getSingleton().getRPreferCompute();
 
 	// Import RTs
 	if(m_rtTexturesImportedOnce[historyRtIdx]) [[likely]]
@@ -153,7 +153,7 @@ void TemporalAA::populateRenderGraph(RenderingContext& ctx)
 		rgraphCtx.bindColorTexture(0, 3, m_r->getMotionVectors().getMotionVectorsRt());
 		rgraphCtx.bindImage(0, 4, m_r->getTonemapping().getRt());
 
-		if(getExternalSubsystems().m_config->getRPreferCompute())
+		if(ConfigSet::getSingleton().getRPreferCompute())
 		{
 			rgraphCtx.bindImage(0, 5, m_runCtx.m_renderRt, TextureSubresourceInfo());
 			rgraphCtx.bindImage(0, 6, m_runCtx.m_tonemappedRt, TextureSubresourceInfo());

+ 4 - 4
AnKi/Renderer/VolumetricFog.cpp

@@ -17,10 +17,10 @@ namespace anki {
 Error VolumetricFog::init()
 {
 	// Misc
-	const F32 qualityXY = getExternalSubsystems().m_config->getRVolumetricLightingAccumulationQualityXY();
-	const F32 qualityZ = getExternalSubsystems().m_config->getRVolumetricLightingAccumulationQualityZ();
-	m_finalZSplit = min(m_r->getZSplitCount() - 1,
-						getExternalSubsystems().m_config->getRVolumetricLightingAccumulationFinalZSplit());
+	const F32 qualityXY = ConfigSet::getSingleton().getRVolumetricLightingAccumulationQualityXY();
+	const F32 qualityZ = ConfigSet::getSingleton().getRVolumetricLightingAccumulationQualityZ();
+	m_finalZSplit =
+		min(m_r->getZSplitCount() - 1, ConfigSet::getSingleton().getRVolumetricLightingAccumulationFinalZSplit());
 
 	m_volumeSize[0] = U32(F32(m_r->getTileCounts().x()) * qualityXY);
 	m_volumeSize[1] = U32(F32(m_r->getTileCounts().y()) * qualityXY);

+ 4 - 4
AnKi/Renderer/VolumetricLightingAccumulation.cpp

@@ -26,10 +26,10 @@ VolumetricLightingAccumulation::~VolumetricLightingAccumulation()
 Error VolumetricLightingAccumulation::init()
 {
 	// Misc
-	const F32 qualityXY = getExternalSubsystems().m_config->getRVolumetricLightingAccumulationQualityXY();
-	const F32 qualityZ = getExternalSubsystems().m_config->getRVolumetricLightingAccumulationQualityZ();
-	m_finalZSplit = min(m_r->getZSplitCount() - 1,
-						getExternalSubsystems().m_config->getRVolumetricLightingAccumulationFinalZSplit());
+	const F32 qualityXY = ConfigSet::getSingleton().getRVolumetricLightingAccumulationQualityXY();
+	const F32 qualityZ = ConfigSet::getSingleton().getRVolumetricLightingAccumulationQualityZ();
+	m_finalZSplit =
+		min(m_r->getZSplitCount() - 1, ConfigSet::getSingleton().getRVolumetricLightingAccumulationFinalZSplit());
 
 	m_volumeSize[0] = U32(F32(m_r->getTileCounts().x()) * qualityXY);
 	m_volumeSize[1] = U32(F32(m_r->getTileCounts().y()) * qualityXY);

+ 7 - 7
AnKi/Renderer/VrsSriGeneration.cpp

@@ -81,7 +81,7 @@ Error VrsSriGeneration::initInternal()
 		variantInit.addMutation("SHARED_MEMORY", 1);
 	}
 
-	variantInit.addMutation("LIMIT_RATE_TO_2X2", getExternalSubsystems().m_config->getRVrsLimitTo2x2());
+	variantInit.addMutation("LIMIT_RATE_TO_2X2", ConfigSet::getSingleton().getRVrsLimitTo2x2());
 
 	const ShaderProgramResourceVariant* variant;
 	m_prog->getOrCreateVariant(variantInit, variant);
@@ -118,8 +118,8 @@ void VrsSriGeneration::getDebugRenderTarget(CString rtName, Array<RenderTargetHa
 
 void VrsSriGeneration::importRenderTargets(RenderingContext& ctx)
 {
-	const Bool enableVrs = getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs
-						   && getExternalSubsystems().m_config->getRVrs();
+	const Bool enableVrs =
+		getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs && ConfigSet::getSingleton().getRVrs();
 	if(!enableVrs)
 	{
 		return;
@@ -141,8 +141,8 @@ void VrsSriGeneration::importRenderTargets(RenderingContext& ctx)
 
 void VrsSriGeneration::populateRenderGraph(RenderingContext& ctx)
 {
-	const Bool enableVrs = getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs
-						   && getExternalSubsystems().m_config->getRVrs();
+	const Bool enableVrs =
+		getExternalSubsystems().m_grManager->getDeviceCapabilities().m_vrs && ConfigSet::getSingleton().getRVrs();
 	if(!enableVrs)
 	{
 		return;
@@ -165,8 +165,8 @@ void VrsSriGeneration::populateRenderGraph(RenderingContext& ctx)
 			rgraphCtx.bindColorTexture(0, 0, m_r->getLightShading().getRt());
 			cmdb->bindSampler(0, 1, m_r->getSamplers().m_nearestNearestClamp);
 			rgraphCtx.bindImage(0, 2, m_runCtx.m_rt);
-			const Vec4 pc(1.0f / Vec2(m_r->getInternalResolution()),
-						  getExternalSubsystems().m_config->getRVrsThreshold(), 0.0f);
+			const Vec4 pc(1.0f / Vec2(m_r->getInternalResolution()), ConfigSet::getSingleton().getRVrsThreshold(),
+						  0.0f);
 			cmdb->setPushConstants(&pc, sizeof(pc));
 
 			const U32 fakeWorkgroupSizeXorY = m_sriTexelDimension;

+ 0 - 2
AnKi/Resource/Common.h

@@ -21,7 +21,6 @@ template<typename Type>
 class ResourcePointer;
 class TransferGpuAllocatorHandle;
 class PhysicsWorld;
-class ConfigSet;
 class UnifiedGeometryMemoryPool;
 
 /// @addtogroup resource
@@ -64,7 +63,6 @@ class ResourceManagerExternalSubsystems
 public:
 	GrManager* m_grManager = nullptr;
 	ResourceFilesystem* m_resourceFilesystem = nullptr;
-	ConfigSet* m_config = nullptr;
 	UnifiedGeometryMemoryPool* m_unifiedGometryMemoryPool = nullptr;
 };
 /// @}

+ 1 - 1
AnKi/Resource/ImageResource.cpp

@@ -78,7 +78,7 @@ Error ImageResource::load(const ResourceFilename& filename, Bool async)
 	ResourceFilePtr file;
 	ANKI_CHECK(openFile(filename, file));
 
-	ANKI_CHECK(loader.load(file, filename, getExternalSubsystems().m_config->getRsrcMaxImageSize()));
+	ANKI_CHECK(loader.load(file, filename, ConfigSet::getSingleton().getRsrcMaxImageSize()));
 
 	// Various sizes
 	init.m_width = loader.getWidth();

+ 3 - 3
AnKi/Resource/ResourceFilesystem.cpp

@@ -207,14 +207,14 @@ ResourceFilesystem::~ResourceFilesystem()
 	m_cacheDir.destroy(m_pool);
 }
 
-Error ResourceFilesystem::init(const ConfigSet& config, AllocAlignedCallback allocCallback, void* allocCallbackUserData)
+Error ResourceFilesystem::init(AllocAlignedCallback allocCallback, void* allocCallbackUserData)
 {
 	m_pool.init(allocCallback, allocCallbackUserData);
 	StringListRaii paths(&m_pool);
-	paths.splitString(config.getRsrcDataPaths(), ':');
+	paths.splitString(ConfigSet::getSingleton().getRsrcDataPaths(), ':');
 
 	StringListRaii excludedStrings(&m_pool);
-	excludedStrings.splitString(config.getRsrcDataPathExcludedStrings(), ':');
+	excludedStrings.splitString(ConfigSet::getSingleton().getRsrcDataPathExcludedStrings(), ':');
 
 	// Workaround the fact that : is used in drives in Windows
 #if ANKI_OS_WINDOWS

+ 1 - 4
AnKi/Resource/ResourceFilesystem.h

@@ -13,9 +13,6 @@
 
 namespace anki {
 
-// Forward
-class ConfigSet;
-
 /// @addtogroup resource
 /// @{
 
@@ -92,7 +89,7 @@ public:
 
 	ResourceFilesystem& operator=(const ResourceFilesystem&) = delete; // Non-copyable
 
-	Error init(const ConfigSet& config, AllocAlignedCallback allocCallback, void* allocCallbackUserData);
+	Error init(AllocAlignedCallback allocCallback, void* allocCallbackUserData);
 
 	/// Search the path list to find the file. Then open the file for reading. It's thread-safe.
 	Error openFile(const ResourceFilename& filename, ResourceFilePtr& file);

+ 1 - 1
AnKi/Resource/ResourceManager.cpp

@@ -58,7 +58,7 @@ Error ResourceManager::init(ResourceManagerInitInfo& init)
 	m_asyncLoader->init(&m_pool);
 
 	m_transferGpuAlloc = newInstance<TransferGpuAllocator>(m_pool);
-	ANKI_CHECK(m_transferGpuAlloc->init(m_subsystems.m_config->getRsrcTransferScratchMemorySize(),
+	ANKI_CHECK(m_transferGpuAlloc->init(ConfigSet::getSingleton().getRsrcTransferScratchMemorySize(),
 										m_subsystems.m_grManager, &m_pool));
 
 	// Init the programs

+ 0 - 1
AnKi/Resource/ResourceManager.h

@@ -13,7 +13,6 @@
 namespace anki {
 
 // Forward
-class ConfigSet;
 class GrManager;
 class PhysicsWorld;
 class ResourceManager;

+ 0 - 2
AnKi/Scene/Common.h

@@ -16,7 +16,6 @@ namespace anki {
 // Forward
 class ResourceManager;
 class Input;
-class ConfigSet;
 class UiManager;
 class UnifiedGeometryMemoryPool;
 class GpuSceneMemoryPool;
@@ -46,7 +45,6 @@ class PhysicsWorld;
 class SceneGraphExternalSubsystems
 {
 public:
-	ConfigSet* m_config = nullptr;
 	ThreadHive* m_threadHive = nullptr;
 	ResourceManager* m_resourceManager = nullptr;
 	Input* m_input = nullptr;

+ 1 - 1
AnKi/Scene/Components/CameraComponent.cpp

@@ -14,7 +14,7 @@ namespace anki {
 CameraComponent::CameraComponent(SceneNode* node)
 	: SceneComponent(node, getStaticClassId())
 {
-	const ConfigSet& config = *getExternalSubsystems(*node).m_config;
+	const ConfigSet& config = ConfigSet::getSingleton();
 
 	// Init main frustum
 	m_frustum.init(FrustumType::kPerspective, &node->getMemoryPool());

+ 3 - 4
AnKi/Scene/Components/GlobalIlluminationProbeComponent.cpp

@@ -149,11 +149,10 @@ Error GlobalIlluminationProbeComponent::update(SceneComponentUpdateInfo& info, B
 
 		F32 effectiveDistance = max(m_halfSize.x(), m_halfSize.y());
 		effectiveDistance = max(effectiveDistance, m_halfSize.z());
-		effectiveDistance =
-			max(effectiveDistance, getExternalSubsystems(*info.m_node).m_config->getSceneProbeEffectiveDistance());
+		effectiveDistance = max(effectiveDistance, ConfigSet::getSingleton().getSceneProbeEffectiveDistance());
 
-		const F32 shadowCascadeDistance = min(
-			effectiveDistance, getExternalSubsystems(*info.m_node).m_config->getSceneProbeShadowEffectiveDistance());
+		const F32 shadowCascadeDistance =
+			min(effectiveDistance, ConfigSet::getSingleton().getSceneProbeShadowEffectiveDistance());
 
 		for(U32 i = 0; i < 6; ++i)
 		{

+ 2 - 2
AnKi/Scene/Components/ParticleEmitterComponent.cpp

@@ -128,7 +128,7 @@ class ParticleEmitterComponent::PhysicsParticle : public ParticleEmitterComponen
 public:
 	PhysicsBodyPtr m_body;
 
-	PhysicsParticle(const PhysicsBodyInitInfo& init, SceneNode* node, ParticleEmitterComponent* component)
+	PhysicsParticle(const PhysicsBodyInitInfo& init, ParticleEmitterComponent* component)
 	{
 		m_body = PhysicsWorld::getSingleton().newInstance<PhysicsBody>(init);
 		m_body->setUserData(component);
@@ -265,7 +265,7 @@ void ParticleEmitterComponent::loadParticleEmitterResource(CString filename)
 		for(U32 i = 0; i < m_props.m_maxNumOfParticles; i++)
 		{
 			binit.m_mass = getRandomRange(m_props.m_particle.m_minMass, m_props.m_particle.m_maxMass);
-			m_physicsParticles.emplaceBack(m_node->getMemoryPool(), binit, m_node, this);
+			m_physicsParticles.emplaceBack(m_node->getMemoryPool(), binit, this);
 		}
 	}
 	else

+ 4 - 5
AnKi/Scene/Components/ReflectionProbeComponent.cpp

@@ -49,7 +49,7 @@ Error ReflectionProbeComponent::update(SceneComponentUpdateInfo& info, Bool& upd
 			(getExternalSubsystems(*info.m_node).m_grManager->getDeviceCapabilities().m_unalignedBbpTextureFormats)
 				? Format::kR16G16B16_Sfloat
 				: Format::kR16G16B16A16_Sfloat;
-		texInit.m_width = getExternalSubsystems(*info.m_node).m_config->getSceneReflectionProbeResolution();
+		texInit.m_width = ConfigSet::getSingleton().getSceneReflectionProbeResolution();
 		texInit.m_height = texInit.m_width;
 		texInit.m_mipmapCount = U8(computeMaxMipmapCount2d(texInit.m_width, texInit.m_height, 8));
 		texInit.m_type = TextureType::kCube;
@@ -73,11 +73,10 @@ Error ReflectionProbeComponent::update(SceneComponentUpdateInfo& info, Bool& upd
 
 		F32 effectiveDistance = max(m_halfSize.x(), m_halfSize.y());
 		effectiveDistance = max(effectiveDistance, m_halfSize.z());
-		effectiveDistance =
-			max(effectiveDistance, getExternalSubsystems(*info.m_node).m_config->getSceneProbeEffectiveDistance());
+		effectiveDistance = max(effectiveDistance, ConfigSet::getSingleton().getSceneProbeEffectiveDistance());
 
-		const F32 shadowCascadeDistance = min(
-			effectiveDistance, getExternalSubsystems(*info.m_node).m_config->getSceneProbeShadowEffectiveDistance());
+		const F32 shadowCascadeDistance =
+			min(effectiveDistance, ConfigSet::getSingleton().getSceneProbeShadowEffectiveDistance());
 
 		for(U32 i = 0; i < 6; ++i)
 		{

+ 1 - 1
AnKi/Scene/ContiguousArrayAllocator.cpp

@@ -110,7 +110,7 @@ void AllGpuSceneContiguousArrays::init(SceneGraph* scene)
 {
 	m_scene = scene;
 
-	const ConfigSet& cfg = *scene->m_subsystems.m_config;
+	const ConfigSet& cfg = ConfigSet::getSingleton();
 	constexpr F32 kGrowRate = 2.0;
 
 	const Array<U32, U32(GpuSceneContiguousArrayType::kCount)> minElementCount = {

+ 1 - 1
AnKi/Scene/SceneGraph.cpp

@@ -61,7 +61,7 @@ Error SceneGraph::init(const SceneGraphInitInfo& initInfo)
 	ANKI_CHECK(m_events.init(this));
 
 	m_octree = newInstance<Octree>(m_pool, &m_pool);
-	m_octree->init(m_sceneMin, m_sceneMax, m_subsystems.m_config->getSceneOctreeMaxDepth());
+	m_octree->init(m_sceneMin, m_sceneMax, ConfigSet::getSingleton().getSceneOctreeMaxDepth());
 
 	// Init the default main camera
 	ANKI_CHECK(newSceneNode<SceneNode>("mainCamera", m_defaultMainCam));

+ 1 - 1
AnKi/Scene/SceneGraph.h

@@ -10,7 +10,6 @@
 #include <AnKi/Scene/ContiguousArrayAllocator.h>
 #include <AnKi/Math.h>
 #include <AnKi/Util/HashMap.h>
-#include <AnKi/Core/App.h>
 #include <AnKi/Scene/Events/EventManager.h>
 #include <AnKi/Resource/Common.h>
 
@@ -18,6 +17,7 @@ namespace anki {
 
 // Forward
 class Octree;
+class RenderQueue;
 
 /// @addtogroup scene
 /// @{

+ 2 - 1
AnKi/Util/CMakeLists.txt

@@ -17,7 +17,8 @@ set(sources
 	Xml.cpp
 	F16.cpp
 	Process.cpp
-	Thread.cpp)
+	Thread.cpp
+	Singleton.cpp)
 
 if(LINUX OR ANDROID OR MACOS)
 	set(sources ${sources}

+ 3 - 3
AnKi/Util/MemoryPool.h

@@ -171,18 +171,18 @@ private:
 };
 
 /// The default global memory pool.
-class DefaultHeapMemoryPool : public HeapMemoryPool, public MakeSingleton<DefaultHeapMemoryPool>
+class DefaultMemoryPool : public HeapMemoryPool, public MakeSingleton<DefaultMemoryPool>
 {
 	template<typename>
 	friend class MakeSingleton;
 
 private:
-	DefaultHeapMemoryPool(AllocAlignedCallback allocCb, void* allocCbUserData)
+	DefaultMemoryPool(AllocAlignedCallback allocCb, void* allocCbUserData)
 		: HeapMemoryPool(allocCb, allocCbUserData, "DefaultMemPool")
 	{
 	}
 
-	~DefaultHeapMemoryPool() = default;
+	~DefaultMemoryPool() = default;
 };
 
 /// Thread safe memory pool. It's a preallocated memory pool that is used for memory allocations on top of that

+ 30 - 0
AnKi/Util/Singleton.cpp

@@ -0,0 +1,30 @@
+// Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Util/Singleton.h>
+
+namespace anki {
+
+#if ANKI_ENABLE_ASSERTIONS
+I32 g_singletonsAllocated = 0;
+
+class SingletonsAllocatedChecker
+{
+public:
+	SingletonsAllocatedChecker()
+	{
+		g_singletonsAllocated = 0;
+	}
+
+	~SingletonsAllocatedChecker()
+	{
+		ANKI_ASSERT(g_singletonsAllocated == 0);
+	}
+};
+
+SingletonsAllocatedChecker g_singletonsAllocatedChecker;
+#endif
+
+} // end namespace anki

+ 25 - 9
AnKi/Util/Singleton.h

@@ -6,10 +6,15 @@
 #pragma once
 
 #include <AnKi/Util/StdTypes.h>
+#include <AnKi/Util/Assert.h>
 #include <utility>
 
 namespace anki {
 
+#if ANKI_ENABLE_ASSERTIONS
+extern I32 g_singletonsAllocated;
+#endif
+
 /// @addtogroup util_patterns
 /// @{
 
@@ -24,26 +29,37 @@ public:
 	}
 
 	template<typename... TArgs>
-	static void allocateSingleton(TArgs&&... args)
+	static T& allocateSingleton(TArgs&&... args)
 	{
-		if(m_global == nullptr)
-		{
-			m_global = new T(std::forward<TArgs>(args)...);
-		}
+		ANKI_ASSERT(m_global == nullptr);
+		m_global = new T(std::forward<TArgs>(args)...);
+
+#if ANKI_ENABLE_ASSERTIONS
+		++g_singletonsAllocated;
+#endif
+
+		return *m_global;
 	}
 
 	static void freeSingleton()
 	{
+		ANKI_ASSERT(m_global);
+
 		delete m_global;
 		m_global = nullptr;
+#if ANKI_ENABLE_ASSERTIONS
+		--g_singletonsAllocated;
+#endif
+	}
+
+	static Bool isAllocated()
+	{
+		return m_global != nullptr;
 	}
 
 private:
-	static T* m_global;
+	static inline T* m_global = nullptr;
 };
-
-template<typename T>
-T* MakeSingleton<T>::m_global = nullptr;
 /// @}
 
 } // end namespace anki

+ 9 - 9
Samples/Common/SampleApp.cpp

@@ -12,8 +12,7 @@ Error SampleApp::init(int argc, char** argv, CString sampleName)
 	HeapMemoryPool pool(allocAligned, nullptr);
 
 	// Init the super class
-	m_config.init(allocAligned, nullptr);
-	m_config.setWindowFullscreen(true);
+	ConfigSet::getSingleton().setWindowFullscreen(true);
 
 #if !ANKI_OS_ANDROID
 	StringRaii mainDataPath(&pool, ANKI_SOURCE_DIRECTORY);
@@ -28,12 +27,13 @@ Error SampleApp::init(int argc, char** argv, CString sampleName)
 	}
 	else
 	{
-		m_config.setRsrcDataPaths(StringRaii(&pool).sprintf("%s:%s", mainDataPath.cstr(), assetsDataPath.cstr()));
+		ConfigSet::getSingleton().setRsrcDataPaths(
+			StringRaii(&pool).sprintf("%s:%s", mainDataPath.cstr(), assetsDataPath.cstr()));
 	}
 #endif
 
-	ANKI_CHECK(m_config.setFromCommandLineArguments(argc - 1, argv + 1));
-	ANKI_CHECK(App::init(&m_config, allocAligned, nullptr));
+	ANKI_CHECK(ConfigSet::getSingleton().setFromCommandLineArguments(argc - 1, argv + 1));
+	ANKI_CHECK(App::init(allocAligned, nullptr));
 
 	ANKI_CHECK(sampleExtraInit());
 
@@ -138,7 +138,7 @@ Error SampleApp::userMainLoop(Bool& quit, Second elapsedTime)
 
 	if(in.getKey(KeyCode::kJ) == 1)
 	{
-		m_config.setRVrs(!m_config.getRVrs());
+		ConfigSet::getSingleton().setRVrs(!ConfigSet::getSingleton().getRVrs());
 	}
 
 	static Vec2 mousePosOn1stClick = in.getMousePosition();
@@ -154,17 +154,17 @@ Error SampleApp::userMainLoop(Bool& quit, Second elapsedTime)
 		mode = (mode + 1) % 3;
 		if(mode == 0)
 		{
-			getConfig().setRDbg(false);
+			ConfigSet::getSingleton().setRDbg(false);
 		}
 		else if(mode == 1)
 		{
-			getConfig().setRDbg(true);
+			ConfigSet::getSingleton().setRDbg(true);
 			renderer.getDbg().setDepthTestEnabled(true);
 			renderer.getDbg().setDitheredDepthTestEnabled(false);
 		}
 		else
 		{
-			getConfig().setRDbg(true);
+			ConfigSet::getSingleton().setRDbg(true);
 			renderer.getDbg().setDepthTestEnabled(false);
 			renderer.getDbg().setDitheredDepthTestEnabled(true);
 		}

+ 0 - 2
Samples/Common/SampleApp.h

@@ -10,8 +10,6 @@
 class SampleApp : public anki::App
 {
 public:
-	anki::ConfigSet m_config;
-
 	anki::Error init(int argc, char** argv, anki::CString sampleName);
 	anki::Error userMainLoop(anki::Bool& quit, anki::Second elapsedTime) override;
 

+ 4 - 4
Samples/PhysicsPlayground/Main.cpp

@@ -245,7 +245,7 @@ Error MyApp::userMainLoop(Bool& quit, [[maybe_unused]] Second elapsedTime)
 
 	if(getInput().getKey(KeyCode::kJ) == 1)
 	{
-		m_config.setRVrs(!m_config.getRVrs());
+		ConfigSet::getSingleton().setRVrs(!ConfigSet::getSingleton().getRVrs());
 	}
 
 	if(getInput().getKey(KeyCode::kF1) == 1)
@@ -254,17 +254,17 @@ Error MyApp::userMainLoop(Bool& quit, [[maybe_unused]] Second elapsedTime)
 		mode = (mode + 1) % 3;
 		if(mode == 0)
 		{
-			getConfig().setRDbg(false);
+			ConfigSet::getSingleton().setRDbg(false);
 		}
 		else if(mode == 1)
 		{
-			getConfig().setRDbg(true);
+			ConfigSet::getSingleton().setRDbg(true);
 			getMainRenderer().getDbg().setDepthTestEnabled(true);
 			getMainRenderer().getDbg().setDitheredDepthTestEnabled(false);
 		}
 		else
 		{
-			getConfig().setRDbg(true);
+			ConfigSet::getSingleton().setRDbg(true);
 			getMainRenderer().getDbg().setDepthTestEnabled(false);
 			getMainRenderer().getDbg().setDitheredDepthTestEnabled(true);
 		}

+ 1 - 1
Samples/SkeletalAnimation/Main.cpp

@@ -31,7 +31,7 @@ public:
 			.getFirstComponentOfType<SkinComponent>()
 			.playAnimation(0, m_floatAnim, animInfo);
 
-		getConfig().setRBloomThreshold(5.0f);
+		ConfigSet::getSingleton().setRBloomThreshold(5.0f);
 		return Error::kNone;
 	}
 

+ 10 - 12
Sandbox/Main.cpp

@@ -17,7 +17,6 @@ class MyApp : public App
 {
 public:
 	Bool m_profile = false;
-	ConfigSet m_config;
 
 	Error init(int argc, char* argv[]);
 	Error userMainLoop(Bool& quit, Second elapsedTime) override;
@@ -36,15 +35,14 @@ Error MyApp::init(int argc, char* argv[])
 #endif
 
 	// Config
-	m_config.init(allocAligned, nullptr);
 #if ANKI_OS_ANDROID
 	ANKI_CHECK(m_config.setFromCommandLineArguments(argc - 1, argv + 1));
 #else
-	ANKI_CHECK(m_config.setFromCommandLineArguments(argc - 2, argv + 2));
+	ANKI_CHECK(ConfigSet::getSingleton().setFromCommandLineArguments(argc - 2, argv + 2));
 #endif
 
 	// Init super class
-	ANKI_CHECK(App::init(&m_config, allocAligned, nullptr));
+	ANKI_CHECK(App::init(allocAligned, nullptr));
 
 	// Other init
 	ResourceManager& resources = getResourceManager();
@@ -52,7 +50,7 @@ Error MyApp::init(int argc, char* argv[])
 	if(getenv("PROFILE"))
 	{
 		m_profile = true;
-		m_config.setCoreTargetFps(240);
+		ConfigSet::getSingleton().setCoreTargetFps(240);
 		Tracer::getSingleton().setEnabled(true);
 	}
 
@@ -125,17 +123,17 @@ Error MyApp::userMainLoop(Bool& quit, Second elapsedTime)
 		mode = (mode + 1) % 3;
 		if(mode == 0)
 		{
-			getConfig().setRDbg(false);
+			ConfigSet::getSingleton().setRDbg(false);
 		}
 		else if(mode == 1)
 		{
-			getConfig().setRDbg(true);
+			ConfigSet::getSingleton().setRDbg(true);
 			renderer.getDbg().setDepthTestEnabled(true);
 			renderer.getDbg().setDitheredDepthTestEnabled(false);
 		}
 		else
 		{
-			getConfig().setRDbg(true);
+			ConfigSet::getSingleton().setRDbg(true);
 			renderer.getDbg().setDepthTestEnabled(false);
 			renderer.getDbg().setDitheredDepthTestEnabled(true);
 		}
@@ -188,17 +186,17 @@ Error MyApp::userMainLoop(Bool& quit, Second elapsedTime)
 			mode = (mode + 1) % 3;
 			if(mode == 0)
 			{
-				getConfig().setRDbg(false);
+				ConfigSet::getSingleton().setRDbg(false);
 			}
 			else if(mode == 1)
 			{
-				getConfig().setRDbg(true);
+				ConfigSet::getSingleton().setRDbg(true);
 				renderer.getDbg().setDepthTestEnabled(true);
 				renderer.getDbg().setDitheredDepthTestEnabled(false);
 			}
 			else
 			{
-				getConfig().setRDbg(true);
+				ConfigSet::getSingleton().setRDbg(true);
 				renderer.getDbg().setDepthTestEnabled(false);
 				renderer.getDbg().setDitheredDepthTestEnabled(true);
 			}
@@ -409,7 +407,7 @@ Error MyApp::userMainLoop(Bool& quit, Second elapsedTime)
 
 	if(in.getKey(KeyCode::kJ) == 1)
 	{
-		m_config.setRVrs(!m_config.getRVrs());
+		ConfigSet::getSingleton().setRVrs(!ConfigSet::getSingleton().getRVrs());
 	}
 
 	if(in.getEvent(InputEvent::kWindowClosed))

+ 3 - 5
Tests/Framework/Framework.cpp

@@ -259,7 +259,7 @@ NativeWindow* createWindow(ConfigSet& cfg)
 	return win;
 }
 
-GrManager* createGrManager(ConfigSet* cfg, NativeWindow* win)
+GrManager* createGrManager(NativeWindow* win)
 {
 	GrManagerInitInfo inf;
 	inf.m_allocCallback = allocAligned;
@@ -271,7 +271,6 @@ GrManager* createGrManager(ConfigSet* cfg, NativeWindow* win)
 		return nullptr;
 	}
 	inf.m_cacheDirectory = home;
-	inf.m_config = cfg;
 	inf.m_window = win;
 	GrManager* gr;
 	ANKI_TEST_EXPECT_NO_ERR(GrManager::newInstance(inf, gr));
@@ -279,15 +278,14 @@ GrManager* createGrManager(ConfigSet* cfg, NativeWindow* win)
 	return gr;
 }
 
-ResourceManager* createResourceManager(ConfigSet* cfg, GrManager* gr, ResourceFilesystem*& resourceFs)
+ResourceManager* createResourceManager(GrManager* gr, ResourceFilesystem*& resourceFs)
 {
 	resourceFs = new ResourceFilesystem();
-	ANKI_TEST_EXPECT_NO_ERR(resourceFs->init(*cfg, allocAligned, nullptr));
+	ANKI_TEST_EXPECT_NO_ERR(resourceFs->init(allocAligned, nullptr));
 
 	ResourceManagerInitInfo rinit;
 	rinit.m_grManager = gr;
 	rinit.m_resourceFilesystem = resourceFs;
-	rinit.m_config = cfg;
 	rinit.m_allocCallback = allocAligned;
 	rinit.m_allocCallbackData = nullptr;
 	ResourceManager* resources = new ResourceManager();

+ 2 - 2
Tests/Framework/Framework.h

@@ -224,9 +224,9 @@ void initConfig(ConfigSet& cfg);
 
 NativeWindow* createWindow(ConfigSet& cfg);
 
-GrManager* createGrManager(ConfigSet* cfg, NativeWindow* win);
+GrManager* createGrManager(NativeWindow* win);
 
-ResourceManager* createResourceManager(ConfigSet* cfg, GrManager* gr, ResourceFilesystem*& resourceFs);
+ResourceManager* createResourceManager(GrManager* gr, ResourceFilesystem*& resourceFs);
 
 /// Stolen from https://en.cppreference.com/w/cpp/algorithm/random_shuffle because std::random_suffle got deprecated
 template<class TRandomIt>

+ 5 - 4
Tests/Gr/Gr.cpp

@@ -235,18 +235,18 @@ static RebarStagingGpuMemoryPool* stagingMem = nullptr;
 static Input* input = nullptr;
 
 #define COMMON_BEGIN() \
-	stagingMem = new RebarStagingGpuMemoryPool(); \
-	ConfigSet cfg(allocAligned, nullptr); \
+	ConfigSet& cfg = ConfigSet::allocateSingleton(allocAligned, nullptr); \
 	cfg.setWidth(WIDTH); \
 	cfg.setHeight(HEIGHT); \
 	cfg.setGrValidation(true); \
 	cfg.setGrVsync(false); \
 	cfg.setGrRayTracing(true); \
 	cfg.setGrDebugMarkers(true); \
+	stagingMem = new RebarStagingGpuMemoryPool(); \
 	g_win = createWindow(cfg); \
 	ANKI_TEST_EXPECT_NO_ERR(Input::newInstance(allocAligned, nullptr, g_win, input)); \
-	g_gr = createGrManager(&cfg, g_win); \
-	ANKI_TEST_EXPECT_NO_ERR(stagingMem->init(g_gr, cfg)); \
+	g_gr = createGrManager(g_win); \
+	ANKI_TEST_EXPECT_NO_ERR(stagingMem->init(g_gr)); \
 	TransferGpuAllocator* transfAlloc = new TransferGpuAllocator(); \
 	ANKI_TEST_EXPECT_NO_ERR(transfAlloc->init(128_MB, g_gr, &g_gr->getMemoryPool())); \
 	while(true) \
@@ -261,6 +261,7 @@ static Input* input = nullptr;
 	GrManager::deleteInstance(g_gr); \
 	Input::deleteInstance(input); \
 	NativeWindow::deleteInstance(g_win); \
+	ConfigSet::freeSingleton(); \
 	g_win = nullptr; \
 	g_gr = nullptr; \
 	stagingMem = nullptr;

+ 2 - 2
Tests/Gr/GrTextureBuffer.cpp

@@ -9,11 +9,11 @@
 
 ANKI_TEST(Gr, TextureBuffer)
 {
-	ConfigSet cfg(allocAligned, nullptr);
+	ConfigSet& cfg = ConfigSet::allocateSingleton(allocAligned, nullptr);
 	cfg.setGrValidation(true);
 
 	NativeWindow* win = createWindow(cfg);
-	GrManager* gr = createGrManager(&cfg, win);
+	GrManager* gr = createGrManager(win);
 
 	{
 		const CString shaderSrc = R"(

+ 2 - 2
Tests/Resource/ResourceFilesystem.cpp

@@ -10,11 +10,11 @@ ANKI_TEST(Resource, ResourceFilesystem)
 {
 	printf("Test requires the Data dir\n");
 
-	ConfigSet config(allocAligned, nullptr);
+	ConfigSet::allocateSingleton(allocAligned, nullptr);
 
 	HeapMemoryPool pool(allocAligned, nullptr);
 	ResourceFilesystem fs;
-	ANKI_TEST_EXPECT_NO_ERR(fs.init(config, allocAligned, nullptr));
+	ANKI_TEST_EXPECT_NO_ERR(fs.init(allocAligned, nullptr));
 
 	{
 		ANKI_TEST_EXPECT_NO_ERR(fs.addNewPath("Tests/Data/Dir/../Dir/", StringListRaii(&pool)));

+ 1 - 2
Tests/Resource/ResourceManager.cpp

@@ -11,13 +11,12 @@
 ANKI_TEST(Resource, ResourceManager)
 {
 	// Create
-	ConfigSet config;
+	ConfigSet::allocateSingleton(allocAligned, nullptr);
 
 	HeapAllocator<U8> alloc(allocAligned, nullptr);
 
 	ResourceManagerInitInfo rinit;
 	rinit.m_grManager = nullptr;
-	rinit.m_config = &config;
 	rinit.m_allocCallback = allocAligned;
 	rinit.m_allocCallbackData = nullptr;
 	ResourceManager* resources = alloc.newInstance<ResourceManager>();

+ 4 - 4
Tests/Ui/Ui.cpp

@@ -57,7 +57,7 @@ public:
 
 ANKI_TEST(Ui, Ui)
 {
-	ConfigSet cfg;
+	ConfigSet& cfg = ConfigSet::allocateSingleton(allocAligned, nullptr);
 	initConfig(cfg);
 	cfg.setGrVsync(true);
 	cfg.setGrValidation(false);
@@ -68,13 +68,13 @@ ANKI_TEST(Ui, Ui)
 	NativeWindow* win = createWindow(cfg);
 	Input* in;
 	ANKI_TEST_EXPECT_NO_ERR(Input::newInstance(allocAligned, nullptr, win, in));
-	GrManager* gr = createGrManager(&cfg, win);
+	GrManager* gr = createGrManager(win);
 	ResourceFilesystem* fs;
-	ResourceManager* resource = createResourceManager(&cfg, gr, fs);
+	ResourceManager* resource = createResourceManager(gr, fs);
 	UiManager* ui = new UiManager();
 
 	RebarStagingGpuMemoryPool* stagingMem = new RebarStagingGpuMemoryPool();
-	ANKI_TEST_EXPECT_NO_ERR(stagingMem->init(gr, cfg));
+	ANKI_TEST_EXPECT_NO_ERR(stagingMem->init(gr));
 
 	HeapAllocator<U8> alloc(allocAligned, nullptr);
 	UiManagerInitInfo uiInitInfo;

+ 8 - 9
Tools/Image/ImageViewerMain.cpp

@@ -264,7 +264,7 @@ private:
 class MyApp : public App
 {
 public:
-	Error init(ConfigSet* config, int argc, char** argv, [[maybe_unused]] CString appName)
+	Error init(int argc, char** argv, [[maybe_unused]] CString appName)
 	{
 		if(argc < 2)
 		{
@@ -275,13 +275,13 @@ public:
 		HeapMemoryPool pool(allocAligned, nullptr);
 		StringRaii mainDataPath(&pool, ANKI_SOURCE_DIRECTORY);
 
-		config->setWindowFullscreen(false);
-		config->setRsrcDataPaths(mainDataPath);
-		config->setGrValidation(false);
-		config->setGrDebugMarkers(false);
-		ANKI_CHECK(config->setFromCommandLineArguments(argc - 2, argv + 2));
+		ConfigSet::getSingleton().setWindowFullscreen(false);
+		ConfigSet::getSingleton().setRsrcDataPaths(mainDataPath);
+		ConfigSet::getSingleton().setGrValidation(false);
+		ConfigSet::getSingleton().setGrDebugMarkers(false);
+		ANKI_CHECK(ConfigSet::getSingleton().setFromCommandLineArguments(argc - 2, argv + 2));
 
-		ANKI_CHECK(App::init(config, allocAligned, nullptr));
+		ANKI_CHECK(App::init(allocAligned, nullptr));
 
 		// Load the texture
 		ImageResourcePtr image;
@@ -318,9 +318,8 @@ int main(int argc, char* argv[])
 {
 	Error err = Error::kNone;
 
-	ConfigSet config(allocAligned, nullptr);
 	MyApp* app = new MyApp;
-	err = app->init(&config, argc, argv, "Texture Viewer");
+	err = app->init(argc, argv, "Texture Viewer");
 	if(!err)
 	{
 		err = app->mainLoop();