Browse Source

Refactor the config options

Panagiotis Christopoulos Charitos 4 years ago
parent
commit
b418ba6ad8
100 changed files with 953 additions and 1097 deletions
  1. 46 0
      AnKi/Core/AllConfigVars.defs.h
  2. 42 41
      AnKi/Core/App.cpp
  3. 17 26
      AnKi/Core/App.h
  4. 0 20
      AnKi/Core/ConfigDefs.h
  5. 151 326
      AnKi/Core/ConfigSet.cpp
  6. 125 66
      AnKi/Core/ConfigSet.h
  7. 23 0
      AnKi/Core/ConfigVars.defs.h
  8. 5 5
      AnKi/Core/GpuMemoryPools.cpp
  9. 0 8
      AnKi/Gr/Common.h
  10. 0 21
      AnKi/Gr/ConfigDefs.h
  11. 24 0
      AnKi/Gr/ConfigVars.defs.h
  12. 3 3
      AnKi/Gr/Enums.h
  13. 0 0
      AnKi/Gr/Format.defs.h
  14. 12 7
      AnKi/Gr/GrManager.h
  15. 0 0
      AnKi/Gr/ShaderVariableDataType.defs.h
  16. 3 3
      AnKi/Gr/Utils/Functions.cpp
  17. 1 1
      AnKi/Gr/Utils/Functions.h
  18. 15 15
      AnKi/Gr/Vulkan/DescriptorSet.cpp
  19. 4 2
      AnKi/Gr/Vulkan/DescriptorSet.h
  20. 32 34
      AnKi/Gr/Vulkan/GrManagerImpl.cpp
  21. 1 1
      AnKi/Gr/Vulkan/GrManagerImpl.h
  22. 2 2
      AnKi/Gr/Vulkan/PipelineCache.cpp
  23. 1 1
      AnKi/Renderer/AccelerationStructureBuilder.h
  24. 3 6
      AnKi/Renderer/Bloom.cpp
  25. 7 30
      AnKi/Renderer/Bloom.h
  26. 1 1
      AnKi/Renderer/ClusterBinning.cpp
  27. 1 1
      AnKi/Renderer/ClusterBinning.h
  28. 1 1
      AnKi/Renderer/Common.h
  29. 0 64
      AnKi/Renderer/ConfigDefs.h
  30. 67 0
      AnKi/Renderer/ConfigVars.defs.h
  31. 5 19
      AnKi/Renderer/Dbg.cpp
  32. 1 15
      AnKi/Renderer/Dbg.h
  33. 3 5
      AnKi/Renderer/DepthDownscale.cpp
  34. 2 2
      AnKi/Renderer/DepthDownscale.h
  35. 3 3
      AnKi/Renderer/DownscaleBlur.cpp
  36. 2 3
      AnKi/Renderer/DownscaleBlur.h
  37. 7 10
      AnKi/Renderer/FinalComposite.cpp
  38. 2 2
      AnKi/Renderer/FinalComposite.h
  39. 0 6
      AnKi/Renderer/ForwardShading.cpp
  40. 4 1
      AnKi/Renderer/ForwardShading.h
  41. 3 6
      AnKi/Renderer/GBuffer.cpp
  42. 2 2
      AnKi/Renderer/GBuffer.h
  43. 3 4
      AnKi/Renderer/GBufferPost.cpp
  44. 2 2
      AnKi/Renderer/GBufferPost.h
  45. 1 1
      AnKi/Renderer/GenericCompute.h
  46. 10 15
      AnKi/Renderer/IndirectDiffuse.cpp
  47. 2 7
      AnKi/Renderer/IndirectDiffuse.h
  48. 15 17
      AnKi/Renderer/IndirectDiffuseProbes.cpp
  49. 6 6
      AnKi/Renderer/IndirectDiffuseProbes.h
  50. 9 11
      AnKi/Renderer/LensFlare.cpp
  51. 4 4
      AnKi/Renderer/LensFlare.h
  52. 7 10
      AnKi/Renderer/LightShading.cpp
  53. 4 4
      AnKi/Renderer/LightShading.h
  54. 10 12
      AnKi/Renderer/MainRenderer.cpp
  55. 18 3
      AnKi/Renderer/MainRenderer.h
  56. 1 3
      AnKi/Renderer/MotionVectors.cpp
  57. 1 1
      AnKi/Renderer/MotionVectors.h
  58. 18 20
      AnKi/Renderer/ProbeReflections.cpp
  59. 7 7
      AnKi/Renderer/ProbeReflections.h
  60. 40 42
      AnKi/Renderer/Renderer.cpp
  61. 12 5
      AnKi/Renderer/Renderer.h
  62. 5 0
      AnKi/Renderer/RendererObject.cpp
  63. 0 0
      AnKi/Renderer/RendererObject.defs.h
  64. 2 0
      AnKi/Renderer/RendererObject.h
  65. 6 6
      AnKi/Renderer/RtShadows.cpp
  66. 2 2
      AnKi/Renderer/RtShadows.h
  67. 3 3
      AnKi/Renderer/Scale.cpp
  68. 1 1
      AnKi/Renderer/Scale.h
  69. 22 26
      AnKi/Renderer/ShadowMapping.cpp
  70. 4 5
      AnKi/Renderer/ShadowMapping.h
  71. 5 5
      AnKi/Renderer/ShadowmapsResolve.cpp
  72. 2 2
      AnKi/Renderer/ShadowmapsResolve.h
  73. 6 9
      AnKi/Renderer/Ssr.cpp
  74. 2 4
      AnKi/Renderer/Ssr.h
  75. 3 5
      AnKi/Renderer/TemporalAA.cpp
  76. 2 2
      AnKi/Renderer/TemporalAA.h
  77. 3 4
      AnKi/Renderer/Tonemapping.cpp
  78. 2 2
      AnKi/Renderer/Tonemapping.h
  79. 1 1
      AnKi/Renderer/UiStage.cpp
  80. 1 1
      AnKi/Renderer/UiStage.h
  81. 4 5
      AnKi/Renderer/VolumetricFog.cpp
  82. 1 1
      AnKi/Renderer/VolumetricFog.h
  83. 4 4
      AnKi/Renderer/VolumetricLightingAccumulation.cpp
  84. 1 1
      AnKi/Renderer/VolumetricLightingAccumulation.h
  85. 0 14
      AnKi/Resource/ConfigDefs.h
  86. 16 0
      AnKi/Resource/ConfigVars.defs.h
  87. 2 1
      AnKi/Resource/ImageResource.cpp
  88. 4 4
      AnKi/Resource/MaterialResource.cpp
  89. 2 2
      AnKi/Resource/MaterialResource.h
  90. 2 2
      AnKi/Resource/ResourceFilesystem.cpp
  91. 2 5
      AnKi/Resource/ResourceManager.cpp
  92. 8 13
      AnKi/Resource/ResourceManager.h
  93. 5 0
      AnKi/Resource/ResourceObject.cpp
  94. 2 0
      AnKi/Resource/ResourceObject.h
  95. 3 1
      AnKi/Resource/ShaderProgramResourceSystem.cpp
  96. 7 7
      AnKi/Scene/CameraNode.cpp
  97. 0 19
      AnKi/Scene/ConfigDefs.h
  98. 21 0
      AnKi/Scene/ConfigVars.defs.h
  99. 3 3
      AnKi/Scene/GlobalIlluminationProbeNode.cpp
  100. 3 4
      AnKi/Scene/ReflectionProbeNode.cpp

+ 46 - 0
AnKi/Core/AllConfigVars.defs.h

@@ -0,0 +1,46 @@
+// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#if !defined(ANKI_CONFIG_VAR_GROUP)
+#	define ANKI_CONFIG_VAR_GROUP(name)
+#endif
+
+#if !defined(ANKI_CONFIG_VAR_U8)
+#	define ANKI_CONFIG_VAR_U8(name, defaultValue, minValue, maxValue, description)
+#endif
+
+#if !defined(ANKI_CONFIG_VAR_U32)
+#	define ANKI_CONFIG_VAR_U32(name, defaultValue, minValue, maxValue, description)
+#endif
+
+#if !defined(ANKI_CONFIG_VAR_PTR_SIZE)
+#	define ANKI_CONFIG_VAR_PTR_SIZE(name, defaultValue, minValue, maxValue, description)
+#endif
+
+#if !defined(ANKI_CONFIG_VAR_F32)
+#	define ANKI_CONFIG_VAR_F32(name, defaultValue, minValue, maxValue, description)
+#endif
+
+#if !defined(ANKI_CONFIG_VAR_BOOL)
+#	define ANKI_CONFIG_VAR_BOOL(name, defaultValue, description)
+#endif
+
+#if !defined(ANKI_CONFIG_VAR_STRING)
+#	define ANKI_CONFIG_VAR_STRING(name, defaultValue, description)
+#endif
+
+#include <AnKi/Core/ConfigVars.defs.h>
+#include <AnKi/Gr/ConfigVars.defs.h>
+#include <AnKi/Resource/ConfigVars.defs.h>
+#include <AnKi/Scene/ConfigVars.defs.h>
+#include <AnKi/Renderer/ConfigVars.defs.h>
+
+#undef ANKI_CONFIG_VAR_GROUP
+#undef ANKI_CONFIG_VAR_U8
+#undef ANKI_CONFIG_VAR_U32
+#undef ANKI_CONFIG_VAR_PTR_SIZE
+#undef ANKI_CONFIG_VAR_F32
+#undef ANKI_CONFIG_VAR_BOOL
+#undef ANKI_CONFIG_VAR_STRING

+ 42 - 41
AnKi/Core/App.cpp

@@ -152,9 +152,11 @@ void App::cleanup()
 	m_cacheDir.destroy(m_heapAlloc);
 }
 
-Error App::init(const ConfigSet& config, AllocAlignedCallback allocCb, void* allocCbUserData)
+Error App::init(ConfigSet* config, AllocAlignedCallback allocCb, void* allocCbUserData)
 {
-	const Error err = initInternal(config, allocCb, allocCbUserData);
+	ANKI_ASSERT(config);
+	m_config = config;
+	const Error err = initInternal(allocCb, allocCbUserData);
 	if(err)
 	{
 		ANKI_CORE_LOGE("App initialization failed. Shutting down");
@@ -164,19 +166,16 @@ Error App::init(const ConfigSet& config, AllocAlignedCallback allocCb, void* all
 	return err;
 }
 
-Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb, void* allocCbUserData)
+Error App::initInternal(AllocAlignedCallback allocCb, void* allocCbUserData)
 {
 	setSignalHandlers();
 
 	Thread::setNameOfCurrentThread("anki_main");
 
-	ConfigSet config = config_;
-	m_displayStats = config.getNumberU32("core_displayStats");
-
 	initMemoryCallbacks(allocCb, allocCbUserData);
 	m_heapAlloc = HeapAllocator<U8>(m_allocCb, m_allocCbData, "Core");
 
-	ANKI_CHECK(initDirs(config));
+	ANKI_CHECK(initDirs());
 
 	// Print a message
 	const char* buildType =
@@ -209,8 +208,6 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 				   "commit %s)",
 				   ANKI_VERSION_MAJOR, ANKI_VERSION_MINOR, buildType, ANKI_COMPILER_STR, __DATE__, ANKI_REVISION);
 
-	m_timerTick = 1.0 / F32(config.getNumberU32("core_targetFps")); // in sec. 1.0 / period
-
 // Check SIMD support
 #if ANKI_SIMD_SSE && ANKI_COMPILER_GCC_COMPATIBLE
 	if(!__builtin_cpu_supports("sse4.2"))
@@ -220,7 +217,7 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 	}
 #endif
 
-	ANKI_CORE_LOGI("Number of main threads: %u", config.getNumberU32("core_mainThreadCount"));
+	ANKI_CORE_LOGI("Number of job threads: %u", m_config->getCoreJobThreadCount());
 
 	//
 	// Core tracer
@@ -236,11 +233,11 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 	NativeWindowInitInfo nwinit;
 	nwinit.m_allocCallback = m_allocCb;
 	nwinit.m_allocCallbackUserData = m_allocCbData;
-	nwinit.m_width = config.getNumberU32("width");
-	nwinit.m_height = config.getNumberU32("height");
+	nwinit.m_width = m_config->getWidth();
+	nwinit.m_height = m_config->getHeight();
 	nwinit.m_depthBits = 0;
 	nwinit.m_stencilBits = 0;
-	nwinit.m_fullscreenDesktopRez = config.getBool("window_fullscreen");
+	nwinit.m_fullscreenDesktopRez = m_config->getWindowFullscreen();
 	ANKI_CHECK(NativeWindow::newInstance(nwinit, m_window));
 
 	//
@@ -251,7 +248,7 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 	//
 	// ThreadPool
 	//
-	m_threadHive = m_heapAlloc.newInstance<ThreadHive>(config.getNumberU32("core_mainThreadCount"), m_heapAlloc, true);
+	m_threadHive = m_heapAlloc.newInstance<ThreadHive>(m_config->getCoreJobThreadCount(), m_heapAlloc, true);
 
 	//
 	// Graphics API
@@ -260,7 +257,7 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 	grInit.m_allocCallback = m_allocCb;
 	grInit.m_allocCallbackUserData = m_allocCbData;
 	grInit.m_cacheDirectory = m_cacheDir.toCString();
-	grInit.m_config = &config;
+	grInit.m_config = m_config;
 	grInit.m_window = m_window;
 
 	ANKI_CHECK(GrManager::newInstance(grInit, m_gr));
@@ -268,7 +265,7 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 	//
 	// Mali HW counters
 	//
-	if(m_gr->getDeviceCapabilities().m_gpuVendor == GpuVendor::ARM && config.getBool("core_maliHwCounters"))
+	if(m_gr->getDeviceCapabilities().m_gpuVendor == GpuVendor::ARM && m_config->getCoreMaliHwCounters())
 	{
 		m_maliHwCounters = m_heapAlloc.newInstance<MaliHwCounters>(m_heapAlloc);
 	}
@@ -277,10 +274,10 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 	// GPU mem
 	//
 	m_vertexMem = m_heapAlloc.newInstance<VertexGpuMemoryPool>();
-	ANKI_CHECK(m_vertexMem->init(m_heapAlloc, m_gr, config));
+	ANKI_CHECK(m_vertexMem->init(m_heapAlloc, m_gr, *m_config));
 
 	m_stagingMem = m_heapAlloc.newInstance<StagingGpuMemoryPool>();
-	ANKI_CHECK(m_stagingMem->init(m_gr, config));
+	ANKI_CHECK(m_stagingMem->init(m_gr, *m_config));
 
 	//
 	// Physics
@@ -293,7 +290,7 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 	// Resource FS
 	//
 	m_resourceFs = m_heapAlloc.newInstance<ResourceFilesystem>(m_heapAlloc);
-	ANKI_CHECK(m_resourceFs->init(config, m_cacheDir.toCString()));
+	ANKI_CHECK(m_resourceFs->init(*m_config, m_cacheDir.toCString()));
 
 	//
 	// Resources
@@ -303,7 +300,7 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 	rinit.m_physics = m_physics;
 	rinit.m_resourceFs = m_resourceFs;
 	rinit.m_vertexMemory = m_vertexMem;
-	rinit.m_config = &config;
+	rinit.m_config = m_config;
 	rinit.m_cacheDir = m_cacheDir.toCString();
 	rinit.m_allocCallback = m_allocCb;
 	rinit.m_allocCallbackData = m_allocCbData;
@@ -320,16 +317,19 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 	//
 	// Renderer
 	//
-	if(nwinit.m_fullscreenDesktopRez)
-	{
-		config.set("width", m_window->getWidth());
-		config.set("height", m_window->getHeight());
-	}
-
+	MainRendererInitInfo renderInit;
+	renderInit.m_swapchainSize = UVec2(m_window->getWidth(), m_window->getHeight());
+	renderInit.m_allocCallback = m_allocCb;
+	renderInit.m_allocCallbackUserData = m_allocCbData;
+	renderInit.m_threadHive = m_threadHive;
+	renderInit.m_resourceManager = m_resources;
+	renderInit.m_gr = m_gr;
+	renderInit.m_stagingMemory = m_stagingMem;
+	renderInit.m_ui = m_ui;
+	renderInit.m_config = m_config;
+	renderInit.m_globTimestamp = &m_globalTimestamp;
 	m_renderer = m_heapAlloc.newInstance<MainRenderer>();
-
-	ANKI_CHECK(m_renderer->init(m_threadHive, m_resources, m_gr, m_stagingMem, m_ui, m_allocCb, m_allocCbData, config,
-								&m_globalTimestamp));
+	ANKI_CHECK(m_renderer->init(renderInit));
 
 	//
 	// Script
@@ -342,8 +342,8 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 	//
 	m_scene = m_heapAlloc.newInstance<SceneGraph>();
 
-	ANKI_CHECK(m_scene->init(m_allocCb, m_allocCbData, m_threadHive, m_resources, m_input, m_script, m_ui,
-							 &m_globalTimestamp, config));
+	ANKI_CHECK(m_scene->init(m_allocCb, m_allocCbData, m_threadHive, m_resources, m_input, m_script, m_ui, m_config,
+							 &m_globalTimestamp));
 
 	// Inform the script engine about some subsystems
 	m_script->setRenderer(m_renderer);
@@ -360,7 +360,7 @@ Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb,
 	return Error::NONE;
 }
 
-Error App::initDirs(const ConfigSet& cfg)
+Error App::initDirs()
 {
 	// Settings path
 #if !ANKI_OS_ANDROID
@@ -386,7 +386,7 @@ Error App::initDirs(const ConfigSet& cfg)
 	m_cacheDir.sprintf(m_heapAlloc, "%s/cache", &m_settingsDir[0]);
 
 	const Bool cacheDirExists = directoryExists(m_cacheDir.toCString());
-	if(cfg.getBool("core_clearCaches") && cacheDirExists)
+	if(m_config->getCoreClearCaches() && cacheDirExists)
 	{
 		ANKI_CORE_LOGI("Will delete the cache dir and start fresh: %s", &m_cacheDir[0]);
 		ANKI_CHECK(removeDirectory(m_cacheDir.toCString(), m_heapAlloc));
@@ -435,7 +435,7 @@ Error App::mainLoop()
 
 			// Render
 			TexturePtr presentableTex = m_gr->acquireNextPresentableTexture();
-			m_renderer->setStatsEnabled(m_displayStats
+			m_renderer->setStatsEnabled(m_config->getCoreDisplayStats()
 #if ANKI_ENABLE_TRACE
 										|| TracerSingleton::get().getEnabled()
 #endif
@@ -459,14 +459,15 @@ Error App::mainLoop()
 			// Sleep
 			const Second endTime = HighRezTimer::getCurrentTime();
 			const Second frameTime = endTime - startTime;
-			if(frameTime < m_timerTick)
+			const Second timerTick = 1.0 / Second(m_config->getCoreTargetFps());
+			if(frameTime < timerTick)
 			{
 				ANKI_TRACE_SCOPED_EVENT(TIMER_TICK_SLEEP);
-				HighRezTimer::sleep(m_timerTick - frameTime);
+				HighRezTimer::sleep(timerTick - frameTime);
 			}
 
 			// Stats
-			if(m_displayStats)
+			if(m_config->getCoreDisplayStats())
 			{
 				StatsUi& statsUi = *static_cast<StatsUi*>(m_statsUi.get());
 
@@ -522,9 +523,9 @@ Error App::mainLoop()
 void App::injectUiElements(DynamicArrayAuto<UiQueueElement>& newUiElementArr, RenderQueue& rqueue)
 {
 	const U32 originalCount = rqueue.m_uis.getSize();
-	if(m_displayStats || m_consoleEnabled)
+	if(m_config->getCoreDisplayStats() || m_consoleEnabled)
 	{
-		const U32 extraElements = (m_displayStats != 0) + (m_consoleEnabled != 0);
+		const U32 extraElements = m_config->getCoreDisplayStats() + (m_consoleEnabled != 0);
 		newUiElementArr.create(originalCount + extraElements);
 
 		if(originalCount > 0)
@@ -536,7 +537,7 @@ void App::injectUiElements(DynamicArrayAuto<UiQueueElement>& newUiElementArr, Re
 	}
 
 	U32 count = originalCount;
-	if(m_displayStats)
+	if(m_config->getCoreDisplayStats())
 	{
 		newUiElementArr[count].m_userData = m_statsUi.get();
 		newUiElementArr[count].m_drawCallback = [](CanvasPtr& canvas, void* userData) -> void {
@@ -557,7 +558,7 @@ void App::injectUiElements(DynamicArrayAuto<UiQueueElement>& newUiElementArr, Re
 
 void App::initMemoryCallbacks(AllocAlignedCallback allocCb, void* allocCbUserData)
 {
-	if(m_displayStats)
+	if(m_config->getCoreDisplayStats())
 	{
 		m_memStats.m_originalAllocCallback = allocCb;
 		m_memStats.m_originalUserData = allocCbUserData;

+ 17 - 26
AnKi/Core/App.h

@@ -40,17 +40,9 @@ public:
 	App();
 	virtual ~App();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& config, AllocAlignedCallback allocCb, void* allocCbUserData);
-
-	Second getTimerTick() const
-	{
-		return m_timerTick;
-	}
-
-	void setTimerTick(const F32 x)
-	{
-		m_timerTick = x;
-	}
+	/// Initialize the application.
+	/// @param[in,out] config The config. Needs to be alive as long as the app is alive.
+	ANKI_USE_RESULT Error init(ConfigSet* config, AllocAlignedCallback allocCb, void* allocCbUserData);
 
 	const String& getSettingsDirectory() const
 	{
@@ -97,6 +89,16 @@ public:
 		return Error::NONE;
 	}
 
+	const ConfigSet& getConfig() const
+	{
+		return *m_config;
+	}
+
+	ConfigSet& getConfig()
+	{
+		return *m_config;
+	}
+
 	Input& getInput()
 	{
 		return *m_input;
@@ -137,16 +139,6 @@ public:
 		return m_heapAlloc;
 	}
 
-	void setDisplayStats(Bool enable)
-	{
-		m_displayStats = enable;
-	}
-
-	Bool getDisplayStats() const
-	{
-		return m_displayStats;
-	}
-
 	void setDisplayDeveloperConsole(Bool display)
 	{
 		m_consoleEnabled = display;
@@ -164,11 +156,13 @@ private:
 	HeapAllocator<U8> m_heapAlloc;
 
 	// Sybsystems
+	ConfigSet* m_config = nullptr;
 #if ANKI_ENABLE_TRACE
 	CoreTracer* m_coreTracer = nullptr;
 #endif
 	NativeWindow* m_window = nullptr;
 	Input* m_input = nullptr;
+	ThreadHive* m_threadHive = nullptr;
 	GrManager* m_gr = nullptr;
 	MaliHwCounters* m_maliHwCounters = nullptr;
 	VertexGpuMemoryPool* m_vertexMem = nullptr;
@@ -183,14 +177,11 @@ private:
 
 	// Misc
 	UiImmediateModeBuilderPtr m_statsUi;
-	Bool m_displayStats = false;
 	UiImmediateModeBuilderPtr m_console;
 	Bool m_consoleEnabled = false;
 	Timestamp m_globalTimestamp = 1;
-	ThreadHive* m_threadHive = nullptr;
 	String m_settingsDir; ///< The path that holds the configuration
 	String m_cacheDir; ///< This is used as a cache
-	Second m_timerTick;
 	U64 m_resourceCompletedAsyncTaskCount = 0;
 
 	class MemStats
@@ -208,9 +199,9 @@ private:
 
 	void initMemoryCallbacks(AllocAlignedCallback allocCb, void* allocCbUserData);
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& config, AllocAlignedCallback allocCb, void* allocCbUserData);
+	ANKI_USE_RESULT Error initInternal(AllocAlignedCallback allocCb, void* allocCbUserData);
 
-	ANKI_USE_RESULT Error initDirs(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initDirs();
 	void cleanup();
 
 	/// Inject a new UI element in the render queue for displaying various stuff.

+ 0 - 20
AnKi/Core/ConfigDefs.h

@@ -1,20 +0,0 @@
-// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-ANKI_CONFIG_OPTION(core_uniformPerFrameMemorySize, 24_MB, 1_MB, 1_GB)
-ANKI_CONFIG_OPTION(core_storagePerFrameMemorySize, 24_MB, 1_MB, 1_GB)
-ANKI_CONFIG_OPTION(core_vertexPerFrameMemorySize, 12_MB, 1_MB, 1_GB)
-ANKI_CONFIG_OPTION(core_textureBufferPerFrameMemorySize, 1_MB, 1_MB, 1_GB)
-ANKI_CONFIG_OPTION(core_globalVertexMemorySize, 128_MB, 16_MB, 2_GB)
-ANKI_CONFIG_OPTION(core_maliHwCounters, 0, 0, 1)
-
-ANKI_CONFIG_OPTION(width, 1920, 16, 16 * 1024, "Width")
-ANKI_CONFIG_OPTION(height, 1080, 16, 16 * 1024, "Height")
-ANKI_CONFIG_OPTION(core_targetFps, 60u, 30u, MAX_U32, "Target FPS")
-
-ANKI_CONFIG_OPTION(core_mainThreadCount, max(2u, getCpuCoresCount() / 2u), 2u, 1024u)
-ANKI_CONFIG_OPTION(core_displayStats, 0, 0, 1)
-ANKI_CONFIG_OPTION(core_clearCaches, 0, 0, 1)
-ANKI_CONFIG_OPTION(window_fullscreen, 0, 0, 1)

+ 151 - 326
AnKi/Core/ConfigSet.cpp

@@ -8,116 +8,72 @@
 #include <AnKi/Util/Logger.h>
 #include <AnKi/Util/File.h>
 
-// Used by the config options
+// Because some cvars set their default values
 #include <AnKi/Util/System.h>
-#include <AnKi/Math.h>
 #include <AnKi/Shaders/Include/ClusteredShadingTypes.h>
 
 namespace anki {
 
-class ConfigSet::Option
+ConfigSet::~ConfigSet()
 {
-public:
-	enum Type
-	{
-		NONE,
-		FLOAT,
-		UNSIGNED,
-		STRING
-	};
-
-	String m_name;
-	String m_helpMsg;
-
-	String m_str;
-	F64 m_float = 0.0;
-	F64 m_minFloat = 0.0;
-	F64 m_maxFloat = 0.0;
-	U64 m_unsigned = 0;
-	U64 m_minUnsigned = 0;
-	U64 m_maxUnsigned = 0;
-
-	Type m_type = NONE;
-
-	Option() = default;
-
-	Option(const Option&) = delete; // Non-copyable
-
-	Option(Option&& b)
-		: m_name(std::move(b.m_name))
-		, m_helpMsg(std::move(b.m_helpMsg))
-		, m_str(std::move(b.m_str))
-		, m_float(b.m_float)
-		, m_minFloat(b.m_minFloat)
-		, m_maxFloat(b.m_maxFloat)
-		, m_unsigned(b.m_unsigned)
-		, m_minUnsigned(b.m_minUnsigned)
-		, m_maxUnsigned(b.m_maxUnsigned)
-		, m_type(b.m_type)
+#define ANKI_CONFIG_VAR_STRING(name, defaultValue, description) m_alloc.getMemoryPool().free(m_##name.m_value);
+#include <AnKi/Core/AllConfigVars.defs.h>
+
+#if ANKI_EXTRA_CHECKS
+	for(const Var& var : m_vars)
 	{
+		if(var.m_timesAccessed.load() == 0)
+		{
+			ANKI_CORE_LOGW("Config var doesn't appear to have been accessed. Maybe unused: %s", var.m_name.cstr());
+		}
 	}
+#endif
+}
 
-	~Option() = default;
+void ConfigSet::init(AllocAlignedCallback allocCb, void* allocCbUserData)
+{
+	ANKI_ASSERT(!isInitialized());
+	m_alloc = HeapAllocator<U8>(allocCb, allocCbUserData);
 
-	Option& operator=(const Option&) = delete; // Non-copyable
+#define ANKI_CONFIG_VAR_NUMERIC(name, defaultValue, minValue, maxValue, description) \
+	ANKI_ASSERT(minValue <= maxValue && defaultValue >= minValue && defaultValue <= maxValue); \
+	m_##name.m_name = #name; \
+	m_##name.m_description = description; \
+	m_##name.m_value = defaultValue; \
+	m_##name.m_min = minValue; \
+	m_##name.m_max = minValue; \
+	m_vars.pushBack(&m_##name);
 
-	Option& operator=(Option&& b) = delete;
-};
+#define ANKI_CONFIG_VAR_U8(name, defaultValue, minValue, maxValue, description) \
+	ANKI_CONFIG_VAR_NUMERIC(name, defaultValue, minValue, maxValue, description)
 
-ConfigSet::ConfigSet()
-{
-	m_alloc = HeapAllocator<U8>(allocAligned, nullptr, "ConfigSet");
-
-#define ANKI_CONFIG_OPTION(name, ...) newOption(ANKI_STRINGIZE(name), __VA_ARGS__);
-#include <AnKi/Core/ConfigDefs.h>
-#include <AnKi/Resource/ConfigDefs.h>
-#include <AnKi/Renderer/ConfigDefs.h>
-#include <AnKi/Scene/ConfigDefs.h>
-#include <AnKi/Gr/ConfigDefs.h>
-#undef ANKI_CONFIG_OPTION
-}
+#define ANKI_CONFIG_VAR_U32(name, defaultValue, minValue, maxValue, description) \
+	ANKI_CONFIG_VAR_NUMERIC(name, defaultValue, minValue, maxValue, description)
 
-ConfigSet::~ConfigSet()
-{
-	for(Option& o : m_options)
-	{
-		o.m_name.destroy(m_alloc);
-		o.m_str.destroy(m_alloc);
-		o.m_helpMsg.destroy(m_alloc);
-	}
+#define ANKI_CONFIG_VAR_PTR_SIZE(name, defaultValue, minValue, maxValue, description) \
+	ANKI_CONFIG_VAR_NUMERIC(name, defaultValue, minValue, maxValue, description)
 
-	m_options.destroy(m_alloc);
-}
+#define ANKI_CONFIG_VAR_F32(name, defaultValue, minValue, maxValue, description) \
+	ANKI_CONFIG_VAR_NUMERIC(name, defaultValue, minValue, maxValue, description)
 
-ConfigSet& ConfigSet::operator=(const ConfigSet& b)
-{
-	m_alloc = b.m_alloc; // Not a copy but we are fine
+#define ANKI_CONFIG_VAR_BOOL(name, defaultValue, description) \
+	m_##name.m_name = #name; \
+	m_##name.m_description = description; \
+	m_##name.m_value = defaultValue; \
+	m_vars.pushBack(&m_##name);
 
-	for(const Option& o : b.m_options)
-	{
-		Option newO;
-		newO.m_name.create(m_alloc, o.m_name.toCString());
-		if(o.m_type == Option::STRING)
-		{
-			newO.m_str.create(m_alloc, o.m_str.toCString());
-		}
-		newO.m_float = o.m_float;
-		newO.m_minFloat = o.m_minFloat;
-		newO.m_maxFloat = o.m_maxFloat;
-		newO.m_unsigned = o.m_unsigned;
-		newO.m_minUnsigned = o.m_minUnsigned;
-		newO.m_maxUnsigned = o.m_maxUnsigned;
-		newO.m_type = o.m_type;
-
-		m_options.emplaceBack(m_alloc, std::move(newO));
-	}
+#define ANKI_CONFIG_VAR_STRING(name, defaultValue, description) \
+	m_##name.m_name = #name; \
+	m_##name.m_description = description; \
+	setStringVar(defaultValue, m_##name); \
+	m_vars.pushBack(&m_##name);
 
-	return *this;
+#include <AnKi/Core/AllConfigVars.defs.h>
 }
 
-ConfigSet::Option* ConfigSet::tryFind(CString optionName)
+ConfigSet::Var* ConfigSet::tryFind(CString optionName)
 {
-	for(List<Option>::Iterator it = m_options.getBegin(); it != m_options.getEnd(); ++it)
+	for(auto it = m_vars.getBegin(); it != m_vars.getEnd(); ++it)
 	{
 		if((*it).m_name == optionName)
 		{
@@ -128,9 +84,9 @@ ConfigSet::Option* ConfigSet::tryFind(CString optionName)
 	return nullptr;
 }
 
-const ConfigSet::Option* ConfigSet::tryFind(CString optionName) const
+const ConfigSet::Var* ConfigSet::tryFind(CString optionName) const
 {
-	for(List<Option>::ConstIterator it = m_options.getBegin(); it != m_options.getEnd(); ++it)
+	for(auto it = m_vars.getBegin(); it != m_vars.getEnd(); ++it)
 	{
 		if((*it).m_name == optionName)
 		{
@@ -141,154 +97,10 @@ const ConfigSet::Option* ConfigSet::tryFind(CString optionName) const
 	return nullptr;
 }
 
-void ConfigSet::newOption(CString optionName, CString value, CString helpMsg)
-{
-	ANKI_ASSERT(!tryFind(optionName));
-
-	Option o;
-	o.m_name.create(m_alloc, optionName);
-	o.m_str.create(m_alloc, value);
-	o.m_type = Option::STRING;
-	if(!helpMsg.isEmpty())
-	{
-		o.m_helpMsg.create(m_alloc, helpMsg);
-	}
-
-	m_options.emplaceBack(m_alloc, std::move(o));
-}
-
-void ConfigSet::newOptionInternal(CString optionName, F64 value, F64 minValue, F64 maxValue, CString helpMsg)
-{
-	ANKI_ASSERT(!tryFind(optionName));
-	ANKI_ASSERT(value >= minValue && value <= maxValue && minValue <= maxValue);
-
-	Option o;
-	o.m_name.create(m_alloc, optionName);
-	o.m_float = value;
-	o.m_minFloat = minValue;
-	o.m_maxFloat = maxValue;
-	o.m_type = Option::FLOAT;
-	if(!helpMsg.isEmpty())
-	{
-		o.m_helpMsg.create(m_alloc, helpMsg);
-	}
-
-	m_options.emplaceBack(m_alloc, std::move(o));
-}
-
-void ConfigSet::newOptionInternal(CString optionName, U64 value, U64 minValue, U64 maxValue, CString helpMsg)
-{
-	ANKI_ASSERT(!tryFind(optionName));
-	ANKI_ASSERT(value >= minValue && value <= maxValue && minValue <= maxValue);
-
-	Option o;
-	o.m_name.create(m_alloc, optionName);
-	o.m_unsigned = value;
-	o.m_minUnsigned = minValue;
-	o.m_maxUnsigned = maxValue;
-	o.m_type = Option::UNSIGNED;
-	if(!helpMsg.isEmpty())
-	{
-		o.m_helpMsg.create(m_alloc, helpMsg);
-	}
-
-	m_options.emplaceBack(m_alloc, std::move(o));
-}
-
-void ConfigSet::set(CString optionName, CString value)
-{
-	Option& o = find(optionName);
-	ANKI_ASSERT(o.m_type == Option::STRING);
-	o.m_str.destroy(m_alloc);
-	o.m_str.create(m_alloc, value);
-}
-
-void ConfigSet::setInternal(CString optionName, F64 value)
-{
-	Option& o = find(optionName);
-	ANKI_ASSERT(o.m_type == Option::FLOAT);
-	ANKI_ASSERT(value >= o.m_minFloat);
-	ANKI_ASSERT(value <= o.m_maxFloat);
-	o.m_float = value;
-}
-
-void ConfigSet::setInternal(CString optionName, U64 value)
-{
-	Option& o = find(optionName);
-	ANKI_ASSERT(o.m_type == Option::UNSIGNED);
-	ANKI_ASSERT(value >= o.m_minUnsigned);
-	ANKI_ASSERT(value <= o.m_maxUnsigned);
-	o.m_unsigned = value;
-}
-
-F64 ConfigSet::getNumberF64(CString optionName) const
-{
-	const Option& option = find(optionName);
-	ANKI_ASSERT(option.m_type == Option::FLOAT);
-	return option.m_float;
-}
-
-F32 ConfigSet::getNumberF32(CString optionName) const
-{
-	return F32(getNumberF64(optionName));
-}
-
-U64 ConfigSet::getNumberU64(CString optionName) const
-{
-	const Option& option = find(optionName);
-	ANKI_ASSERT(option.m_type == Option::UNSIGNED);
-	return option.m_unsigned;
-}
-
-U32 ConfigSet::getNumberU32(CString optionName) const
-{
-	const U64 out = getNumberU64(optionName);
-	if(out > MAX_U32)
-	{
-		ANKI_CORE_LOGW("Option is out of U32 range: %s", optionName.cstr());
-	}
-	return U32(out);
-}
-
-U16 ConfigSet::getNumberU16(CString optionName) const
-{
-	const U64 out = getNumberU64(optionName);
-	if(out > MAX_U16)
-	{
-		ANKI_CORE_LOGW("Option is out of U16 range: %s", optionName.cstr());
-	}
-	return U16(out);
-}
-
-U8 ConfigSet::getNumberU8(CString optionName) const
-{
-	const U64 out = getNumberU64(optionName);
-	if(out > MAX_U8)
-	{
-		ANKI_CORE_LOGW("Option is out of U8 range: %s", optionName.cstr());
-	}
-	return U8(out);
-}
-
-Bool ConfigSet::getBool(CString optionName) const
-{
-	const U64 val = getNumberU64(optionName);
-	if((val & ~U64(1)) != 0)
-	{
-		ANKI_CORE_LOGW("Expecting 0 or 1 for the config option \"%s\". Will mask out extra bits", optionName.cstr());
-	}
-	return val & 1;
-}
-
-CString ConfigSet::getString(CString optionName) const
-{
-	const Option& o = find(optionName);
-	ANKI_ASSERT(o.m_type == Option::STRING);
-	return o.m_str.toCString();
-}
-
 Error ConfigSet::loadFromFile(CString filename)
 {
+	ANKI_ASSERT(isInitialized());
+
 	ANKI_CORE_LOGI("Loading config file %s", filename.cstr());
 	XmlDocument xml;
 	ANKI_CHECK(xml.loadFile(filename, m_alloc));
@@ -296,56 +108,59 @@ Error ConfigSet::loadFromFile(CString filename)
 	XmlElement rootel;
 	ANKI_CHECK(xml.getChildElement("config", rootel));
 
-	for(Option& option : m_options)
-	{
-		XmlElement el;
-		ANKI_CHECK(rootel.getChildElementOptional(option.m_name.toCString(), el));
+	XmlElement el;
 
-		if(el)
-		{
-			if(option.m_type == Option::FLOAT)
-			{
-				ANKI_CHECK(el.getNumber(option.m_float));
-			}
-			else if(option.m_type == Option::UNSIGNED)
-			{
-				ANKI_CHECK(el.getNumber(option.m_unsigned));
-			}
-			else
-			{
-				ANKI_ASSERT(option.m_type == Option::STRING);
-				CString txt;
-				ANKI_CHECK(el.getText(txt));
-				option.m_str.destroy(m_alloc);
-				option.m_str.create(m_alloc, txt);
-			}
-		}
-		else
-		{
-			if(option.m_type == Option::FLOAT)
-			{
-				ANKI_CORE_LOGW("Missing option for \"%s\". Will use the default value: %f", &option.m_name[0],
-							   option.m_float);
-			}
-			else if(option.m_type == Option::UNSIGNED)
-			{
-				ANKI_CORE_LOGW("Missing option for \"%s\". Will use the default value: %" PRIu64, &option.m_name[0],
-							   option.m_unsigned);
-			}
-			else
-			{
-				ANKI_ASSERT(option.m_type == Option::STRING);
-				ANKI_CORE_LOGW("Missing option for \"%s\". Will use the default value: %s", option.m_name.cstr(),
-							   option.m_str.cstr());
-			}
-		}
+#define ANKI_NUMERIC(name) \
+	ANKI_CHECK(rootel.getChildElementOptional(m_##name.m_name, el)); \
+	if(el) \
+	{ \
+		ANKI_CHECK(el.getNumber(m_##name.m_value)); \
+	}
+
+#define ANKI_CONFIG_VAR_U8(name, defaultValue, minValue, maxValue, description) ANKI_NUMERIC(name)
+#define ANKI_CONFIG_VAR_U32(name, defaultValue, minValue, maxValue, description) ANKI_NUMERIC(name)
+#define ANKI_CONFIG_VAR_PTR_SIZE(name, defaultValue, minValue, maxValue, description) ANKI_NUMERIC(name)
+#define ANKI_CONFIG_VAR_F32(name, defaultValue, minValue, maxValue, description) ANKI_NUMERIC(name)
+
+#define ANKI_CONFIG_VAR_BOOL(name, defaultValue, description) \
+	ANKI_CHECK(rootel.getChildElementOptional(m_##name.m_name, el)); \
+	if(el) \
+	{ \
+		CString txt; \
+		ANKI_CHECK(el.getText(txt)); \
+		if(txt == "true") \
+		{ \
+			m_##name.m_value = true; \
+		} \
+		else if(txt == "false") \
+		{ \
+			m_##name.m_value = false; \
+		} \
+		else \
+		{ \
+			ANKI_CORE_LOGE("Wrong value for %s", m_##name.m_name.cstr()); \
+			return Error::USER_DATA; \
+		} \
 	}
 
+#define ANKI_CONFIG_VAR_STRING(name, defaultValue, description) \
+	ANKI_CHECK(rootel.getChildElementOptional(m_##name.m_name, el)); \
+	if(el) \
+	{ \
+		CString txt; \
+		ANKI_CHECK(el.getText(txt)); \
+		setStringVar(txt, m_##name); \
+	}
+
+#include <AnKi/Core/AllConfigVars.defs.h>
+#undef ANKI_NUMERIC
+
 	return Error::NONE;
 }
 
 Error ConfigSet::saveToFile(CString filename) const
 {
+	ANKI_ASSERT(isInitialized());
 	ANKI_CORE_LOGI("Saving config file %s", &filename[0]);
 
 	File file;
@@ -353,29 +168,24 @@ Error ConfigSet::saveToFile(CString filename) const
 
 	ANKI_CHECK(file.writeText("%s\n<config>\n", XmlDocument::XML_HEADER.cstr()));
 
-	for(const Option& option : m_options)
-	{
-		if(!option.m_helpMsg.isEmpty())
-		{
-			ANKI_CHECK(file.writeText("\t<!-- %s -->\n", option.m_helpMsg.cstr()));
-		}
-
-		if(option.m_type == Option::FLOAT)
-		{
-			ANKI_CHECK(file.writeText("\t<%s>%f</%s>\n", option.m_name.cstr(), option.m_float, option.m_name.cstr()));
-		}
-		else if(option.m_type == Option::UNSIGNED)
-		{
-			ANKI_CHECK(file.writeText("\t<%s>%" PRIu64 "</%s>\n", option.m_name.cstr(), option.m_unsigned,
-									  option.m_name.cstr()));
-		}
-		else
-		{
-			ANKI_ASSERT(option.m_type == Option::STRING);
-			ANKI_CHECK(file.writeText("\t<%s><![CDATA[%s]]></%s>\n", option.m_name.cstr(), option.m_str.cstr(),
-									  option.m_name.cstr()));
-		}
-	}
+#define ANKI_NUMERIC_UINT(name) \
+	ANKI_CHECK(file.writeText("\t<!-- %s -->\n", m_##name.m_description.cstr())); \
+	ANKI_CHECK( \
+		file.writeText("\t<%s>%llu</%s>\n", m_##name.m_name.cstr(), U64(m_##name.m_value), m_##name.m_name.cstr()));
+
+#define ANKI_CONFIG_VAR_U8(name, defaultValue, minValue, maxValue, description) ANKI_NUMERIC_UINT(name)
+#define ANKI_CONFIG_VAR_U32(name, defaultValue, minValue, maxValue, description) ANKI_NUMERIC_UINT(name)
+#define ANKI_CONFIG_VAR_PTR_SIZE(name, defaultValue, minValue, maxValue, description) ANKI_NUMERIC_UINT(name)
+#define ANKI_CONFIG_VAR_F32(name, defaultValue, minValue, maxValue, description) ANKI_NUMERIC_UINT(name)
+#define ANKI_CONFIG_VAR_BOOL(name, defaultValue, description) \
+	ANKI_CHECK(file.writeText("\t<!-- %s -->\n", m_##name.m_description.cstr())); \
+	ANKI_CHECK(file.writeText("\t<%s>%s</%s>\n", m_##name.m_name.cstr(), (m_##name.m_value) ? "true" : "false", \
+							  m_##name.m_name.cstr()));
+#define ANKI_CONFIG_VAR_STRING(name, defaultValue, description) \
+	ANKI_CHECK(file.writeText("\t<!-- %s -->\n", m_##name.m_description.cstr())); \
+	ANKI_CHECK(file.writeText("\t<%s>%s</%s>\n", m_##name.m_name.cstr(), m_##name.m_value, m_##name.m_name.cstr()));
+#include <AnKi/Core/AllConfigVars.defs.h>
+#undef ANKI_NUMERIC_UINT
 
 	ANKI_CHECK(file.writeText("</config>\n"));
 	return Error::NONE;
@@ -383,43 +193,58 @@ Error ConfigSet::saveToFile(CString filename) const
 
 Error ConfigSet::setFromCommandLineArguments(U32 cmdLineArgsCount, char* cmdLineArgs[])
 {
+	ANKI_ASSERT(isInitialized());
+
 	for(U i = 0; i < cmdLineArgsCount; ++i)
 	{
-		const char* arg = cmdLineArgs[i];
-		ANKI_ASSERT(arg);
-
-		Option* option = tryFind(arg);
-		if(option == nullptr)
-		{
-			ANKI_CORE_LOGW("Can't recognize command line argument: %s", arg);
-			continue;
-		}
+		ANKI_ASSERT(cmdLineArgs[i]);
+		const CString varName = cmdLineArgs[i];
 
 		// Set the value
 		++i;
 		if(i >= cmdLineArgsCount)
 		{
-			ANKI_CORE_LOGE("Expecting a command line argument after %s", arg);
+			ANKI_CORE_LOGE("Expecting a command line argument after %s", varName.cstr());
 			return Error::USER_DATA;
 		}
 
-		arg = cmdLineArgs[i];
-		ANKI_ASSERT(arg);
-		if(option->m_type == Option::STRING)
-		{
-			option->m_str.destroy(m_alloc);
-			option->m_str.create(m_alloc, arg);
-		}
-		else if(option->m_type == Option::FLOAT)
+		ANKI_ASSERT(cmdLineArgs[i]);
+		const CString value = cmdLineArgs[i];
+
+		if(false)
 		{
-			CString val(arg);
-			ANKI_CHECK(val.toNumber(option->m_float));
 		}
+
+#define ANKI_NUMERIC(name) \
+	else if(varName == m_##name.m_name) \
+	{ \
+		ANKI_CHECK(value.toNumber(m_##name.m_value)); \
+	}
+
+#define ANKI_CONFIG_VAR_U8(name, defaultValue, minValue, maxValue, description) ANKI_NUMERIC(name)
+#define ANKI_CONFIG_VAR_U32(name, defaultValue, minValue, maxValue, description) ANKI_NUMERIC(name)
+#define ANKI_CONFIG_VAR_PTR_SIZE(name, defaultValue, minValue, maxValue, description) ANKI_NUMERIC(name)
+#define ANKI_CONFIG_VAR_F32(name, defaultValue, minValue, maxValue, description) ANKI_NUMERIC(name)
+
+#define ANKI_CONFIG_VAR_BOOL(name, defaultValue, description) \
+	else if(varName == m_##name.m_name) \
+	{ \
+		U32 v; \
+		ANKI_CHECK(value.toNumber(v)); \
+		m_##name.m_value = v != 0; \
+	}
+
+#define ANKI_CONFIG_VAR_STRING(name, defaultValue, description) \
+	else if(varName == m_##name.m_name) \
+	{ \
+		setStringVar(value, m_##name); \
+	}
+
+#include <AnKi/Core/AllConfigVars.defs.h>
+#undef ANKI_NUMERIC
 		else
 		{
-			ANKI_ASSERT(option->m_type == Option::UNSIGNED);
-			CString val(arg);
-			ANKI_CHECK(val.toNumber(option->m_unsigned));
+			ANKI_CORE_LOGW("Can't recognize command line argument: %s. Skipping", varName.cstr());
 		}
 	}
 

+ 125 - 66
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/Math/Functions.h>
 
 namespace anki {
 
@@ -18,103 +19,161 @@ namespace anki {
 class ConfigSet
 {
 public:
-	ConfigSet();
+	/// @note Need to call init() if using this constructor.
+	ConfigSet()
+	{
+	}
 
-	/// Copy.
-	ConfigSet(const ConfigSet& b)
+	ConfigSet(AllocAlignedCallback allocCb, void* allocCbUserData)
 	{
-		operator=(b);
+		init(allocCb, allocCbUserData);
 	}
 
+	ConfigSet(const ConfigSet& b) = delete; // Non-copyable
+
 	~ConfigSet();
 
-	/// Copy.
-	ConfigSet& operator=(const ConfigSet& b);
+	ConfigSet& operator=(const ConfigSet& b) = delete; // Non-copyable
 
-	/// @name Set the value of an option.
-	/// @{
-	void set(CString option, CString value);
+	void init(AllocAlignedCallback allocCb, void* allocCbUserData);
 
-	template<typename T, ANKI_ENABLE(std::is_integral<T>::value)>
-	void set(CString option, T value)
-	{
-		setInternal(option, U64(value));
-	}
+	ANKI_USE_RESULT Error loadFromFile(CString filename);
 
-	template<typename T, ANKI_ENABLE(std::is_floating_point<T>::value)>
-	void set(CString option, T value)
-	{
-		setInternal(option, F64(value));
+	ANKI_USE_RESULT Error saveToFile(CString filename) const;
+
+	ANKI_USE_RESULT Error setFromCommandLineArguments(U32 cmdLineArgsCount, char* cmdLineArgs[]);
+
+	// Define getters and setters
+#if ANKI_EXTRA_CHECKS
+#	define ANKI_CONFIG_VAR_GET(type, name, defaultValue, minValue, maxValue, description) \
+		type get##name() const \
+		{ \
+			ANKI_ASSERT(isInitialized()); \
+			m_##name.m_timesAccessed.fetchAdd(1); \
+			return m_##name.m_value; \
+		}
+#else
+#	define ANKI_CONFIG_VAR_GET(type, name, defaultValue, minValue, maxValue, description) \
+		type get##name() const \
+		{ \
+			ANKI_ASSERT(isInitialized()); \
+			return m_##name.m_value; \
+		}
+#endif
+#define ANKI_CONFIG_VAR_SET(type, name, defaultValue, minValue, maxValue, description) \
+	void set##name(type value) \
+	{ \
+		ANKI_ASSERT(isInitialized()); \
+		const type newValue = clamp(value, m_##name.m_min, m_##name.m_max); \
+		if(newValue != value) \
+		{ \
+			ANKI_CORE_LOGW("Out of range value set for config var: %s", m_##name.m_name.cstr()); \
+		} \
+		m_##name.m_value = newValue; \
 	}
-	/// @}
-
-	/// @name Find an option and return its value.
-	/// @{
-	F64 getNumberF64(CString option) const;
-	F32 getNumberF32(CString option) const;
-	U64 getNumberU64(CString option) const;
-	U32 getNumberU32(CString option) const;
-	U16 getNumberU16(CString option) const;
-	U8 getNumberU8(CString option) const;
-	Bool getBool(CString option) const;
-	CString getString(CString option) const;
-	/// @}
-
-	/// @name Create new options.
-	/// @{
-	void newOption(CString optionName, CString value, CString helpMsg);
-
-	template<typename T, ANKI_ENABLE(std::is_integral<T>::value)>
-	void newOption(CString optionName, T value, T minValue, T maxValue, CString helpMsg = "")
-	{
-		newOptionInternal(optionName, U64(value), U64(minValue), U64(maxValue), helpMsg);
+#define ANKI_CONFIG_VAR_U8(name, defaultValue, minValue, maxValue, description) \
+	ANKI_CONFIG_VAR_GET(U8, name, defaultValue, minValue, maxValue, description) \
+	ANKI_CONFIG_VAR_SET(U8, name, defaultValue, minValue, maxValue, description)
+#define ANKI_CONFIG_VAR_U32(name, defaultValue, minValue, maxValue, description) \
+	ANKI_CONFIG_VAR_GET(U32, name, defaultValue, minValue, maxValue, description) \
+	ANKI_CONFIG_VAR_SET(U32, name, defaultValue, minValue, maxValue, description)
+#define ANKI_CONFIG_VAR_PTR_SIZE(name, defaultValue, minValue, maxValue, description) \
+	ANKI_CONFIG_VAR_GET(PtrSize, name, defaultValue, minValue, maxValue, description) \
+	ANKI_CONFIG_VAR_SET(PtrSize, name, defaultValue, minValue, maxValue, description)
+#define ANKI_CONFIG_VAR_F32(name, defaultValue, minValue, maxValue, description) \
+	ANKI_CONFIG_VAR_GET(F32, name, defaultValue, minValue, maxValue, description) \
+	ANKI_CONFIG_VAR_SET(F32, name, defaultValue, minValue, maxValue, description)
+#define ANKI_CONFIG_VAR_BOOL(name, defaultValue, description) \
+	ANKI_CONFIG_VAR_GET(Bool, name, defaultValue, minValue, maxValue, description) \
+	void set##name(Bool value) \
+	{ \
+		ANKI_ASSERT(isInitialized()); \
+		m_##name.m_value = value; \
 	}
+#define ANKI_CONFIG_VAR_STRING(name, defaultValue, description) \
+	ANKI_CONFIG_VAR_GET(CString, name, defaultValue, minValue, maxValue, description) \
+	void set##name(CString value) \
+	{ \
+		ANKI_ASSERT(isInitialized()); \
+		setStringVar(value, m_##name); \
+	}
+#include <AnKi/Core/AllConfigVars.defs.h>
+#undef ANKI_CONFIG_VAR_GET
+#undef ANKI_CONFIG_VAR_SET
 
-	template<typename T, ANKI_ENABLE(std::is_floating_point<T>::value)>
-	void newOption(CString optionName, T value, T minValue, T maxValue, CString helpMsg = "")
+private:
+	class Var : public IntrusiveListEnabled<Var>
 	{
-		newOptionInternal(optionName, F64(value), F64(minValue), F64(maxValue), helpMsg);
-	}
-	/// @}
+	public:
+		CString m_name;
+		CString m_description;
+#if ANKI_EXTRA_CHECKS
+		mutable Atomic<U32> m_timesAccessed = {0};
+#endif
+	};
+
+	template<typename T>
+	class NumberVar : public Var
+	{
+	public:
+		T m_value;
+		T m_min;
+		T m_max;
+	};
 
-	ANKI_USE_RESULT Error loadFromFile(CString filename);
+	class StringVar : public Var
+	{
+	public:
+		Char* m_value = nullptr;
+	};
 
-	ANKI_USE_RESULT Error saveToFile(CString filename) const;
+	class BoolVar : public Var
+	{
+	public:
+		Bool m_value;
+	};
 
-	ANKI_USE_RESULT Error setFromCommandLineArguments(U32 cmdLineArgsCount, char* cmdLineArgs[]);
+	HeapAllocator<U8> m_alloc;
+	IntrusiveList<Var> m_vars;
 
-private:
-	class Option;
+#define ANKI_CONFIG_VAR_U8(name, defaultValue, minValue, maxValue, description) NumberVar<U8> m_##name;
+#define ANKI_CONFIG_VAR_U32(name, defaultValue, minValue, maxValue, description) NumberVar<U32> m_##name;
+#define ANKI_CONFIG_VAR_PTR_SIZE(name, defaultValue, minValue, maxValue, description) NumberVar<PtrSize> m_##name;
+#define ANKI_CONFIG_VAR_F32(name, defaultValue, minValue, maxValue, description) NumberVar<F32> m_##name;
+#define ANKI_CONFIG_VAR_BOOL(name, defaultValue, description) BoolVar m_##name;
+#define ANKI_CONFIG_VAR_STRING(name, defaultValue, description) StringVar m_##name;
+#include <AnKi/Core/AllConfigVars.defs.h>
 
-	HeapAllocator<U8> m_alloc;
-	List<Option> m_options;
+	Bool isInitialized() const
+	{
+		return !m_vars.isEmpty();
+	}
 
-	Option* tryFind(CString name);
-	const Option* tryFind(CString name) const;
+	Var* tryFind(CString name);
+	const Var* tryFind(CString name) const;
 
-	Option& find(CString name)
+	Var& find(CString name)
 	{
-		Option* o = tryFind(name);
+		Var* o = tryFind(name);
 		ANKI_ASSERT(o && "Couldn't find config option");
 		return *o;
 	}
 
-	const Option& find(CString name) const
+	const Var& find(CString name) const
 	{
-		const Option* o = tryFind(name);
+		const Var* o = tryFind(name);
 		ANKI_ASSERT(o && "Couldn't find config option");
 		return *o;
 	}
 
-	void setInternal(CString option, F64 value);
-	void setInternal(CString option, U64 value);
-
-	void newOptionInternal(CString optionName, U64 value, U64 minValue, U64 maxValue, CString helpMsg);
-	void newOptionInternal(CString optionName, F64 value, F64 minValue, F64 maxValue, CString helpMsg);
+	void setStringVar(CString val, StringVar& var)
+	{
+		m_alloc.getMemoryPool().free(var.m_value);
+		const U32 len = val.getLength();
+		var.m_value = static_cast<Char*>(m_alloc.getMemoryPool().allocate(len + 1, alignof(Char)));
+		memcpy(var.m_value, val.getBegin(), len + 1);
+	}
 };
-
-/// The default config set. Copy that to your own to override.
-using DefaultConfigSet = Singleton<ConfigSet>;
 /// @}
 
 } // end namespace anki

+ 23 - 0
AnKi/Core/ConfigVars.defs.h

@@ -0,0 +1,23 @@
+// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+ANKI_CONFIG_VAR_GROUP(CORE)
+
+ANKI_CONFIG_VAR_PTR_SIZE(CoreUniformPerFrameMemorySize, 24_MB, 1_MB, 1_GB, "Uniform staging buffer size")
+ANKI_CONFIG_VAR_PTR_SIZE(CoreStoragePerFrameMemorySize, 24_MB, 1_MB, 1_GB, "Storage staging buffer size")
+ANKI_CONFIG_VAR_PTR_SIZE(CoreVertexPerFrameMemorySize, 12_MB, 1_MB, 1_GB, "Vertex staging buffer size")
+ANKI_CONFIG_VAR_PTR_SIZE(CoreTextureBufferPerFrameMemorySize, 1_MB, 1_MB, 1_GB, "Texture staging buffer size")
+ANKI_CONFIG_VAR_PTR_SIZE(CoreGlobalVertexMemorySize, 128_MB, 16_MB, 2_GB, "Global index and vertex buffer size")
+
+ANKI_CONFIG_VAR_BOOL(CoreMaliHwCounters, false, "Enable Mali counters")
+
+ANKI_CONFIG_VAR_U32(Width, 1920, 16, 16 * 1024, "Width")
+ANKI_CONFIG_VAR_U32(Height, 1080, 16, 16 * 1024, "Height")
+ANKI_CONFIG_VAR_BOOL(WindowFullscreen, false, "Start at fullscreen")
+
+ANKI_CONFIG_VAR_U32(CoreTargetFps, 60u, 30u, MAX_U32, "Target FPS")
+ANKI_CONFIG_VAR_U32(CoreJobThreadCount, max(2u, getCpuCoresCount() / 2u), 2u, 1024u, "Number of job thread")
+ANKI_CONFIG_VAR_BOOL(CoreDisplayStats, false, "Display stats")
+ANKI_CONFIG_VAR_BOOL(CoreClearCaches, false, "Clear all caches")

+ 5 - 5
AnKi/Core/GpuMemoryPools.cpp

@@ -21,7 +21,7 @@ Error VertexGpuMemoryPool::init(GenericMemoryPoolAllocator<U8> alloc, GrManager*
 
 	// Create the GPU buffer.
 	BufferInitInfo bufferInit("Global vertex & index");
-	bufferInit.m_size = cfg.getNumberU64("core_globalVertexMemorySize");
+	bufferInit.m_size = cfg.getCoreGlobalVertexMemorySize();
 	if(!isPowerOfTwo(bufferInit.m_size))
 	{
 		ANKI_CORE_LOGE("core_globalVertexMemorySize should be a power of two (because of the buddy allocator");
@@ -77,10 +77,10 @@ Error StagingGpuMemoryPool::init(GrManager* gr, const ConfigSet& cfg)
 {
 	m_gr = gr;
 
-	m_perFrameBuffers[StagingGpuMemoryType::UNIFORM].m_size = cfg.getNumberU32("core_uniformPerFrameMemorySize");
-	m_perFrameBuffers[StagingGpuMemoryType::STORAGE].m_size = cfg.getNumberU32("core_storagePerFrameMemorySize");
-	m_perFrameBuffers[StagingGpuMemoryType::VERTEX].m_size = cfg.getNumberU32("core_vertexPerFrameMemorySize");
-	m_perFrameBuffers[StagingGpuMemoryType::TEXTURE].m_size = cfg.getNumberU32("core_textureBufferPerFrameMemorySize");
+	m_perFrameBuffers[StagingGpuMemoryType::UNIFORM].m_size = cfg.getCoreUniformPerFrameMemorySize();
+	m_perFrameBuffers[StagingGpuMemoryType::STORAGE].m_size = cfg.getCoreStoragePerFrameMemorySize();
+	m_perFrameBuffers[StagingGpuMemoryType::VERTEX].m_size = cfg.getCoreVertexPerFrameMemorySize();
+	m_perFrameBuffers[StagingGpuMemoryType::TEXTURE].m_size = cfg.getCoreTextureBufferPerFrameMemorySize();
 
 	initBuffer(StagingGpuMemoryType::UNIFORM, gr->getDeviceCapabilities().m_uniformBufferBindOffsetAlignment,
 			   gr->getDeviceCapabilities().m_uniformBufferMaxRange, BufferUsageBit::ALL_UNIFORM, *gr);

+ 0 - 8
AnKi/Gr/Common.h

@@ -167,14 +167,6 @@ static_assert(sizeof(GpuDeviceCapabilities)
 				  == sizeof(PtrSize) * 4 + sizeof(U32) * 5 + sizeof(U8) * 3 + sizeof(Bool) * 4,
 			  "Should be packed");
 
-/// Bindless related info.
-class BindlessLimits
-{
-public:
-	U32 m_bindlessTextureCount = 0;
-	U32 m_bindlessImageCount = 0;
-};
-
 /// The type of the allocator for heap allocations
 template<typename T>
 using GrAllocator = HeapAllocator<T>;

+ 0 - 21
AnKi/Gr/ConfigDefs.h

@@ -1,21 +0,0 @@
-// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-ANKI_CONFIG_OPTION(gr_validation, 0, 0, 1)
-ANKI_CONFIG_OPTION(gr_debugPrintf, 0, 0, 1)
-ANKI_CONFIG_OPTION(gr_debugMarkers, 0, 0, 1)
-ANKI_CONFIG_OPTION(gr_vsync, 0, 0, 1)
-ANKI_CONFIG_OPTION(gr_maxBindlessTextures, 256, 8, 1024)
-ANKI_CONFIG_OPTION(gr_maxBindlessImages, 32, 8, 1024)
-ANKI_CONFIG_OPTION(gr_rayTracing, 0, 0, 1, "Try enabling ray tracing")
-ANKI_CONFIG_OPTION(gr_64bitAtomics, 1, 0, 1)
-ANKI_CONFIG_OPTION(gr_samplerFilterMinMax, 1, 0, 1)
-ANKI_CONFIG_OPTION(gr_vrs, 0, 0, 1)
-
-// Vulkan
-ANKI_CONFIG_OPTION(gr_diskShaderCacheMaxSize, 128_MB, 1_MB, 1_GB)
-ANKI_CONFIG_OPTION(gr_vkminor, 1, 1, 1)
-ANKI_CONFIG_OPTION(gr_vkmajor, 1, 1, 1)
-ANKI_CONFIG_OPTION(gr_asyncCompute, 1, 0, 1, "Enable or not async compute")

+ 24 - 0
AnKi/Gr/ConfigVars.defs.h

@@ -0,0 +1,24 @@
+// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+ANKI_CONFIG_VAR_GROUP(GR)
+
+ANKI_CONFIG_VAR_BOOL(GrValidation, false, "Enable or not validation")
+ANKI_CONFIG_VAR_BOOL(GrDebugPrintf, false, "Enable or not debug printf")
+ANKI_CONFIG_VAR_BOOL(GrDebugMarkers, false, "Enable or not debug markers")
+ANKI_CONFIG_VAR_BOOL(GrVsync, false, "Enable or not vsync")
+
+ANKI_CONFIG_VAR_U32(GrMaxBindlessTextures, 256, 8, 1024, "Max number of bindless textures")
+ANKI_CONFIG_VAR_U32(GrMaxBindlessImages, 32, 8, 1024, "Max number of bindless images")
+ANKI_CONFIG_VAR_PTR_SIZE(GrDiskShaderCacheMaxSize, 128_MB, 1_MB, 1_GB, "Max size of the pipeline cache file")
+
+ANKI_CONFIG_VAR_BOOL(GrRayTracing, false, "Try enabling ray tracing")
+ANKI_CONFIG_VAR_BOOL(Gr64bitAtomics, true, "Enable or not 64bit atomics")
+ANKI_CONFIG_VAR_BOOL(GrSamplerFilterMinMax, true, "Enable or not min/max sample filtering")
+ANKI_CONFIG_VAR_BOOL(GrVrs, false, "Enable or not VRS")
+ANKI_CONFIG_VAR_BOOL(GrAsyncCompute, true, "Enable or not async compute")
+
+ANKI_CONFIG_VAR_U8(GrVkMinor, 1, 1, 1, "Vulkan minor version")
+ANKI_CONFIG_VAR_U8(GrVkMajor, 1, 1, 1, "Vulkan major version")

+ 3 - 3
AnKi/Gr/Enums.h

@@ -138,7 +138,7 @@ enum class Format : U32
 #define ANKI_FORMAT_DEF(type, id, componentCount, texelSize, blockWidth, blockHeight, blockSize, shaderType, \
 						depthStencil) \
 	type = id,
-#include <AnKi/Gr/FormatDefs.h>
+#include <AnKi/Gr/Format.defs.h>
 #undef ANKI_FORMAT_DEF
 };
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(Format)
@@ -176,7 +176,7 @@ inline FormatInfo getFormatInfo(Format fmt)
 		out.m_depthStencil = DepthStencilAspectBit::depthStencil; \
 		out.m_name = #type; \
 		break;
-#include <AnKi/Gr/FormatDefs.h>
+#include <AnKi/Gr/Format.defs.h>
 #undef ANKI_FORMAT_DEF
 
 	default:
@@ -349,7 +349,7 @@ enum class ShaderVariableDataType : U8
 
 #define ANKI_SVDT_MACRO(capital, type, baseType, rowCount, columnCount) capital,
 #define ANKI_SVDT_MACRO_OPAQUE(capital, type) capital,
-#include <AnKi/Gr/ShaderVariableDataTypeDefs.h>
+#include <AnKi/Gr/ShaderVariableDataType.defs.h>
 #undef ANKI_SVDT_MACRO
 #undef ANKI_SVDT_MACRO_OPAQUE
 

+ 0 - 0
AnKi/Gr/FormatDefs.h → AnKi/Gr/Format.defs.h


+ 12 - 7
AnKi/Gr/GrManager.h

@@ -27,7 +27,7 @@ public:
 
 	CString m_cacheDirectory;
 
-	const ConfigSet* m_config = nullptr;
+	ConfigSet* m_config = nullptr;
 	NativeWindow* m_window = nullptr;
 };
 
@@ -55,11 +55,6 @@ public:
 		return m_capabilities;
 	}
 
-	const BindlessLimits& getBindlessLimits() const
-	{
-		return m_bindlessLimits;
-	}
-
 	/// Get next presentable image. The returned Texture is valid until the following swapBuffers. After that it might
 	/// dissapear even if you hold the reference.
 	TexturePtr acquireNextPresentableTexture();
@@ -108,12 +103,22 @@ public:
 		return m_uuidIndex.fetchAdd(1);
 	}
 
+	ANKI_INTERNAL const ConfigSet& getConfig() const
+	{
+		return *m_config;
+	}
+
+	ANKI_INTERNAL ConfigSet& getConfig()
+	{
+		return *m_config;
+	}
+
 protected:
 	GrAllocator<U8> m_alloc; ///< Keep it first to get deleted last
+	ConfigSet* m_config = nullptr;
 	String m_cacheDir;
 	Atomic<U64> m_uuidIndex = {1};
 	GpuDeviceCapabilities m_capabilities;
-	BindlessLimits m_bindlessLimits;
 
 	GrManager();
 

+ 0 - 0
AnKi/Gr/ShaderVariableDataTypeDefs.h → AnKi/Gr/ShaderVariableDataType.defs.h


+ 3 - 3
AnKi/Gr/Utils/Functions.cpp

@@ -96,7 +96,7 @@ public:
 	public: \
 		static constexpr Bool VALUE = rowCount * columnCount > 4; \
 	};
-#include <AnKi/Gr/ShaderVariableDataTypeDefs.h>
+#include <AnKi/Gr/ShaderVariableDataType.defs.h>
 #undef ANKI_SVDT_MACRO
 
 template<typename T, Bool isMatrix = IsShaderVarDataTypeAMatrix<T>::VALUE>
@@ -133,7 +133,7 @@ void writeShaderBlockMemory(ShaderVariableDataType type, const ShaderVariableBlo
 	case ShaderVariableDataType::capital: \
 		WriteShaderBlockMemory<type>()(varBlkInfo, elements, elementsCount, buffBegin, buffEnd); \
 		break;
-#include <AnKi/Gr/ShaderVariableDataTypeDefs.h>
+#include <AnKi/Gr/ShaderVariableDataType.defs.h>
 #undef ANKI_SVDT_MACRO
 
 	default:
@@ -152,7 +152,7 @@ const CString shaderVariableDataTypeToString(ShaderVariableDataType t)
 	case ShaderVariableDataType::capital: \
 		return ANKI_STRINGIZE(type);
 #define ANKI_SVDT_MACRO_OPAQUE(capital, type) ANKI_SVDT_MACRO(capital, type, 0, 0, 0)
-#include <AnKi/Gr/ShaderVariableDataTypeDefs.h>
+#include <AnKi/Gr/ShaderVariableDataType.defs.h>
 #undef ANKI_SVDT_MACRO
 #undef ANKI_SVDT_MACRO_OPAQUE
 

+ 1 - 1
AnKi/Gr/Utils/Functions.h

@@ -38,7 +38,7 @@ ShaderVariableDataType getShaderVariableTypeFromTypename();
 		return ShaderVariableDataType::capital; \
 	}
 
-#include <AnKi/Gr/ShaderVariableDataTypeDefs.h>
+#include <AnKi/Gr/ShaderVariableDataType.defs.h>
 #undef ANKI_SVDT_MACRO
 
 /// Populate the memory of a variable that is inside a shader block.

+ 15 - 15
AnKi/Gr/Vulkan/DescriptorSet.cpp

@@ -19,7 +19,7 @@ class DescriptorSetFactory::BindlessDescriptorSet
 public:
 	~BindlessDescriptorSet();
 
-	Error init(const GrAllocator<U8>& alloc, VkDevice dev, const BindlessLimits& bindlessLimits);
+	Error init(const GrAllocator<U8>& alloc, VkDevice dev, const U32 bindlessTextureCount, U32 bindlessImageCount);
 
 	/// Bind a sampled image.
 	/// @note It's thread-safe.
@@ -95,11 +95,9 @@ DescriptorSetFactory::BindlessDescriptorSet::~BindlessDescriptorSet()
 }
 
 Error DescriptorSetFactory::BindlessDescriptorSet::init(const GrAllocator<U8>& alloc, VkDevice dev,
-														const BindlessLimits& bindlessLimits)
+														U32 bindlessTextureCount, U32 bindlessImageCount)
 {
 	ANKI_ASSERT(dev);
-	ANKI_ASSERT(bindlessLimits.m_bindlessTextureCount <= MAX_U16);
-	ANKI_ASSERT(bindlessLimits.m_bindlessImageCount <= MAX_U16);
 	m_alloc = alloc;
 	m_dev = dev;
 
@@ -108,11 +106,11 @@ Error DescriptorSetFactory::BindlessDescriptorSet::init(const GrAllocator<U8>& a
 		Array<VkDescriptorSetLayoutBinding, 2> bindings = {};
 		bindings[0].binding = 0;
 		bindings[0].stageFlags = VK_SHADER_STAGE_ALL;
-		bindings[0].descriptorCount = bindlessLimits.m_bindlessTextureCount;
+		bindings[0].descriptorCount = bindlessTextureCount;
 		bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
 		bindings[1].binding = 1;
 		bindings[1].stageFlags = VK_SHADER_STAGE_ALL;
-		bindings[1].descriptorCount = bindlessLimits.m_bindlessImageCount;
+		bindings[1].descriptorCount = bindlessImageCount;
 		bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
 
 		Array<VkDescriptorBindingFlagsEXT, 2> bindingFlags = {};
@@ -140,9 +138,9 @@ Error DescriptorSetFactory::BindlessDescriptorSet::init(const GrAllocator<U8>& a
 	{
 		Array<VkDescriptorPoolSize, 2> sizes = {};
 		sizes[0].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
-		sizes[0].descriptorCount = bindlessLimits.m_bindlessTextureCount;
+		sizes[0].descriptorCount = bindlessTextureCount;
 		sizes[1].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
-		sizes[1].descriptorCount = bindlessLimits.m_bindlessImageCount;
+		sizes[1].descriptorCount = bindlessImageCount;
 
 		VkDescriptorPoolCreateInfo ci = {};
 		ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
@@ -167,7 +165,7 @@ Error DescriptorSetFactory::BindlessDescriptorSet::init(const GrAllocator<U8>& a
 
 	// Init the free arrays
 	{
-		m_freeTexIndices.create(m_alloc, bindlessLimits.m_bindlessTextureCount);
+		m_freeTexIndices.create(m_alloc, bindlessTextureCount);
 		m_freeTexIndexCount = U16(m_freeTexIndices.getSize());
 
 		for(U32 i = 0; i < m_freeTexIndices.getSize(); ++i)
@@ -175,7 +173,7 @@ Error DescriptorSetFactory::BindlessDescriptorSet::init(const GrAllocator<U8>& a
 			m_freeTexIndices[i] = U16(m_freeTexIndices.getSize() - i - 1);
 		}
 
-		m_freeImgIndices.create(m_alloc, bindlessLimits.m_bindlessImageCount);
+		m_freeImgIndices.create(m_alloc, bindlessImageCount);
 		m_freeImgIndexCount = U16(m_freeImgIndices.getSize());
 
 		for(U32 i = 0; i < m_freeImgIndices.getSize(); ++i)
@@ -929,14 +927,16 @@ DescriptorSetFactory::~DescriptorSetFactory()
 {
 }
 
-Error DescriptorSetFactory::init(const GrAllocator<U8>& alloc, VkDevice dev, const BindlessLimits& bindlessLimits)
+Error DescriptorSetFactory::init(const GrAllocator<U8>& alloc, VkDevice dev, U32 bindlessTextureCount,
+								 U32 bindlessImageCount)
 {
 	m_alloc = alloc;
 	m_dev = dev;
 
 	m_bindless = m_alloc.newInstance<BindlessDescriptorSet>();
-	ANKI_CHECK(m_bindless->init(alloc, dev, bindlessLimits));
-	m_bindlessLimits = bindlessLimits;
+	ANKI_CHECK(m_bindless->init(alloc, dev, bindlessTextureCount, bindlessImageCount));
+	m_bindlessTextureCount = bindlessTextureCount;
+	m_bindlessImageCount = bindlessImageCount;
 
 	return Error::NONE;
 }
@@ -988,12 +988,12 @@ Error DescriptorSetFactory::newDescriptorSetLayout(const DescriptorSetLayoutInit
 		{
 			const DescriptorBinding& binding = bindings[i];
 			if(binding.m_binding == 0 && binding.m_type == DescriptorType::TEXTURE
-			   && binding.m_arraySizeMinusOne == m_bindlessLimits.m_bindlessTextureCount - 1)
+			   && binding.m_arraySizeMinusOne == m_bindlessTextureCount - 1)
 			{
 				// All good
 			}
 			else if(binding.m_binding == 1 && binding.m_type == DescriptorType::IMAGE
-					&& binding.m_arraySizeMinusOne == m_bindlessLimits.m_bindlessImageCount - 1)
+					&& binding.m_arraySizeMinusOne == m_bindlessImageCount - 1)
 			{
 				// All good
 			}

+ 4 - 2
AnKi/Gr/Vulkan/DescriptorSet.h

@@ -389,7 +389,8 @@ public:
 	DescriptorSetFactory() = default;
 	~DescriptorSetFactory();
 
-	ANKI_USE_RESULT Error init(const GrAllocator<U8>& alloc, VkDevice dev, const BindlessLimits& bindlessLimits);
+	ANKI_USE_RESULT Error init(const GrAllocator<U8>& alloc, VkDevice dev, U32 bindlessTextureCount,
+							   U32 bindlessImageCount);
 
 	void destroy();
 
@@ -432,7 +433,8 @@ private:
 	SpinLock m_cachesMtx; ///< Not a mutex because after a while there will be no reason to lock
 
 	BindlessDescriptorSet* m_bindless = nullptr;
-	BindlessLimits m_bindlessLimits;
+	U32 m_bindlessTextureCount = MAX_U32;
+	U32 m_bindlessImageCount = MAX_U32;
 };
 /// @}
 

+ 32 - 34
AnKi/Gr/Vulkan/GrManagerImpl.cpp

@@ -110,6 +110,10 @@ Error GrManagerImpl::init(const GrManagerInitInfo& init)
 Error GrManagerImpl::initInternal(const GrManagerInitInfo& init)
 {
 	ANKI_VK_LOGI("Initializing Vulkan backend");
+
+	m_config = init.m_config;
+	ANKI_ASSERT(m_config);
+
 	ANKI_CHECK(initInstance(init));
 	ANKI_CHECK(initSurface(init));
 	ANKI_CHECK(initDevice(init));
@@ -126,13 +130,13 @@ Error GrManagerImpl::initInternal(const GrManagerInitInfo& init)
 		}
 	}
 
-	m_swapchainFactory.init(this, init.m_config->getBool("gr_vsync"));
+	m_swapchainFactory.init(this, m_config->getGrVsync());
 
 	m_crntSwapchain = m_swapchainFactory.newInstance();
 
-	ANKI_CHECK(m_pplineCache.init(m_device, m_physicalDevice, init.m_cacheDirectory, *init.m_config, getAllocator()));
+	ANKI_CHECK(m_pplineCache.init(m_device, m_physicalDevice, init.m_cacheDirectory, *m_config, getAllocator()));
 
-	ANKI_CHECK(initMemory(*init.m_config));
+	ANKI_CHECK(initMemory());
 
 	ANKI_CHECK(m_cmdbFactory.init(getAllocator(), m_device, m_queueFamilyIndices));
 
@@ -209,9 +213,8 @@ Error GrManagerImpl::initInternal(const GrManagerInitInfo& init)
 		}
 	}
 
-	m_bindlessLimits.m_bindlessTextureCount = init.m_config->getNumberU32("gr_maxBindlessTextures");
-	m_bindlessLimits.m_bindlessImageCount = init.m_config->getNumberU32("gr_maxBindlessImages");
-	ANKI_CHECK(m_descrFactory.init(getAllocator(), m_device, m_bindlessLimits));
+	ANKI_CHECK(m_descrFactory.init(getAllocator(), m_device, m_config->getGrMaxBindlessTextures(),
+								   m_config->getGrMaxBindlessImages()));
 	m_pplineLayoutFactory.init(getAllocator(), m_device);
 
 	return Error::NONE;
@@ -225,8 +228,8 @@ Error GrManagerImpl::initInstance(const GrManagerInitInfo& init)
 
 	// Create the instance
 	//
-	const U8 vulkanMinor = init.m_config->getNumberU8("gr_vkminor");
-	const U8 vulkanMajor = init.m_config->getNumberU8("gr_vkmajor");
+	const U8 vulkanMinor = m_config->getGrVkMinor();
+	const U8 vulkanMajor = m_config->getGrVkMajor();
 
 	VkApplicationInfo app = {};
 	app.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
@@ -243,7 +246,7 @@ Error GrManagerImpl::initInstance(const GrManagerInitInfo& init)
 	// Validation layers
 	static Array<const char*, 1> LAYERS = {"VK_LAYER_KHRONOS_validation"};
 	Array<const char*, LAYERS.getSize()> layersToEnable; // Keep it alive in the stack
-	if(init.m_config->getBool("gr_validation") || init.m_config->getBool("gr_debugPrintf"))
+	if(m_config->getGrValidation() || m_config->getGrDebugPrintf())
 	{
 		uint32_t count;
 		vkEnumerateInstanceLayerProperties(&count, nullptr);
@@ -285,12 +288,12 @@ Error GrManagerImpl::initInstance(const GrManagerInitInfo& init)
 	// Validation features
 	DynamicArrayAuto<VkValidationFeatureEnableEXT> enabledValidationFeatures(getAllocator());
 	DynamicArrayAuto<VkValidationFeatureDisableEXT> disabledValidationFeatures(getAllocator());
-	if(init.m_config->getBool("gr_debugPrintf"))
+	if(m_config->getGrDebugPrintf())
 	{
 		enabledValidationFeatures.emplaceBack(VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT);
 	}
 
-	if(!init.m_config->getBool("gr_validation"))
+	if(!m_config->getGrValidation())
 	{
 		disabledValidationFeatures.emplaceBack(VK_VALIDATION_FEATURE_DISABLE_ALL_EXT);
 	}
@@ -362,7 +365,7 @@ Error GrManagerImpl::initInstance(const GrManagerInitInfo& init)
 				instExtensions[instExtensionCount++] = VK_KHR_SURFACE_EXTENSION_NAME;
 			}
 			else if(CString(instExtensionInf[i].extensionName) == VK_EXT_DEBUG_REPORT_EXTENSION_NAME
-					&& (init.m_config->getBool("gr_validation") || init.m_config->getBool("gr_debugPrintf")))
+					&& (m_config->getGrValidation() || m_config->getGrDebugPrintf()))
 			{
 				m_extensions |= VulkanExtensions::EXT_DEBUG_REPORT;
 				instExtensions[instExtensionCount++] = VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
@@ -410,7 +413,7 @@ Error GrManagerImpl::initInstance(const GrManagerInitInfo& init)
 		ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT
 				   | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
 
-		if(init.m_config->getBool("gr_debugPrintf"))
+		if(m_config->getGrDebugPrintf())
 		{
 			ci.flags |= VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
 		}
@@ -559,7 +562,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 		return Error::FUNCTION_FAILED;
 	}
 
-	if(!init.m_config->getBool("gr_asyncCompute"))
+	if(!m_config->getGrAsyncCompute())
 	{
 		m_queueFamilyIndices[VulkanQueueType::COMPUTE] = MAX_U32;
 	}
@@ -621,12 +624,12 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 				m_extensions |= VulkanExtensions::KHR_SWAPCHAIN;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_EXT_DEBUG_MARKER_EXTENSION_NAME && init.m_config->getBool("gr_debugMarkers"))
+			else if(extensionName == VK_EXT_DEBUG_MARKER_EXTENSION_NAME && m_config->getGrDebugMarkers())
 			{
 				m_extensions |= VulkanExtensions::EXT_DEBUG_MARKER;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_AMD_SHADER_INFO_EXTENSION_NAME && init.m_config->getBool("core_displayStats"))
+			else if(extensionName == VK_AMD_SHADER_INFO_EXTENSION_NAME && m_config->getCoreDisplayStats())
 			{
 				m_extensions |= VulkanExtensions::AMD_SHADER_INFO;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
@@ -636,39 +639,35 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 				m_extensions |= VulkanExtensions::AMD_RASTERIZATION_ORDER;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME
-					&& init.m_config->getBool("gr_rayTracing"))
+			else if(extensionName == VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME && init.m_config->getGrRayTracing())
 			{
 				m_extensions |= VulkanExtensions::KHR_RAY_TRACING;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 				m_capabilities.m_rayTracingEnabled = true;
 			}
-			else if(extensionName == VK_KHR_RAY_QUERY_EXTENSION_NAME && init.m_config->getBool("gr_rayTracing"))
+			else if(extensionName == VK_KHR_RAY_QUERY_EXTENSION_NAME && init.m_config->getGrRayTracing())
 			{
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME
-					&& init.m_config->getBool("gr_rayTracing"))
+			else if(extensionName == VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME && init.m_config->getGrRayTracing())
 			{
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME
-					&& init.m_config->getBool("gr_rayTracing"))
+			else if(extensionName == VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME && init.m_config->getGrRayTracing())
 			{
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME && init.m_config->getBool("gr_rayTracing"))
+			else if(extensionName == VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME && init.m_config->getGrRayTracing())
 			{
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
 			else if(extensionName == VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME
-					&& init.m_config->getBool("core_displayStats"))
+					&& m_config->getCoreDisplayStats())
 			{
 				m_extensions |= VulkanExtensions::KHR_PIPELINE_EXECUTABLE_PROPERTIES;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME
-					&& init.m_config->getBool("gr_debugPrintf"))
+			else if(extensionName == VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME && m_config->getGrDebugPrintf())
 			{
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
@@ -697,8 +696,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 				m_extensions |= VulkanExtensions::KHR_SHADER_FLOAT16_INT8;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME
-					&& init.m_config->getBool("gr_64bitAtomics"))
+			else if(extensionName == VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME && m_config->getGr64bitAtomics())
 			{
 				m_extensions |= VulkanExtensions::KHR_SHADER_ATOMIC_INT64;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
@@ -714,7 +712,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
 			else if(extensionName == VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME
-					&& init.m_config->getBool("gr_samplerFilterMinMax"))
+					&& m_config->getGrSamplerFilterMinMax())
 			{
 				m_extensions |= VulkanExtensions::EXT_SAMPLER_FILTER_MIN_MAX;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
@@ -724,7 +722,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 				m_extensions |= VulkanExtensions::KHR_CREATE_RENDERPASS_2;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
 			}
-			else if(extensionName == VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME && init.m_config->getBool("gr_vrs"))
+			else if(extensionName == VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME && m_config->getGrVrs())
 			{
 				m_extensions |= VulkanExtensions::KHR_FRAGMENT_SHADING_RATE;
 				extensionsToEnable[extensionsToEnableCount++] = extensionName.cstr();
@@ -753,7 +751,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 		vkGetPhysicalDeviceFeatures2(m_physicalDevice, &devFeatures);
 		m_devFeatures = devFeatures.features;
 		m_devFeatures.robustBufferAccess =
-			(init.m_config->getBool("gr_validation") && m_devFeatures.robustBufferAccess) ? true : false;
+			(m_config->getGrValidation() && m_devFeatures.robustBufferAccess) ? true : false;
 		ANKI_VK_LOGI("Robust buffer access is %s", (m_devFeatures.robustBufferAccess) ? "enabled" : "disabled");
 
 		ci.pEnabledFeatures = &m_devFeatures;
@@ -829,7 +827,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 		vkGetPhysicalDeviceFeatures2(m_physicalDevice, &features);
 
 		m_deviceBufferFeatures.bufferDeviceAddressCaptureReplay =
-			m_deviceBufferFeatures.bufferDeviceAddressCaptureReplay && init.m_config->getBool("gr_debugMarkers");
+			m_deviceBufferFeatures.bufferDeviceAddressCaptureReplay && m_config->getGrDebugMarkers();
 		m_deviceBufferFeatures.bufferDeviceAddressMultiDevice = false;
 
 		m_deviceBufferFeatures.pNext = const_cast<void*>(ci.pNext);
@@ -1057,7 +1055,7 @@ Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
 	return Error::NONE;
 }
 
-Error GrManagerImpl::initMemory(const ConfigSet& cfg)
+Error GrManagerImpl::initMemory()
 {
 	vkGetPhysicalDeviceMemoryProperties(m_physicalDevice, &m_memoryProperties);
 

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

@@ -326,7 +326,7 @@ private:
 	ANKI_USE_RESULT Error initSurface(const GrManagerInitInfo& init);
 	ANKI_USE_RESULT Error initDevice(const GrManagerInitInfo& init);
 	ANKI_USE_RESULT Error initFramebuffers(const GrManagerInitInfo& init);
-	ANKI_USE_RESULT Error initMemory(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initMemory();
 
 #if ANKI_GR_MANAGER_DEBUG_MEMMORY
 	static void* allocateCallback(void* userData, size_t size, size_t alignment,

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

@@ -14,7 +14,7 @@ Error PipelineCache::init(VkDevice dev, VkPhysicalDevice pdev, CString cacheDir,
 						  GrAllocator<U8> alloc)
 {
 	ANKI_ASSERT(cacheDir && dev && pdev);
-	m_dumpSize = cfg.getNumberU32("gr_diskShaderCacheMaxSize");
+	m_dumpSize = cfg.getGrDiskShaderCacheMaxSize();
 	m_dumpFilename.sprintf(alloc, "%s/vk_pipeline_cache", &cacheDir[0]);
 
 	// Try read the pipeline cache file.
@@ -24,7 +24,7 @@ Error PipelineCache::init(VkDevice dev, VkPhysicalDevice pdev, CString cacheDir,
 		File file;
 		ANKI_CHECK(file.open(m_dumpFilename.toCString(), FileOpenFlag::BINARY | FileOpenFlag::READ));
 
-		PtrSize diskDumpSize = file.getSize();
+		const PtrSize diskDumpSize = file.getSize();
 		if(diskDumpSize <= sizeof(U8) * VK_UUID_SIZE)
 		{
 			ANKI_VK_LOGI("Pipeline cache dump appears to be empty: %s", &m_dumpFilename[0]);

+ 1 - 1
AnKi/Renderer/AccelerationStructureBuilder.h

@@ -25,7 +25,7 @@ public:
 	{
 	}
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg)
+	ANKI_USE_RESULT Error init()
 	{
 		return Error::NONE;
 	}

+ 3 - 6
AnKi/Renderer/Bloom.cpp

@@ -21,14 +21,11 @@ Bloom::~Bloom()
 {
 }
 
-Error Bloom::initExposure(const ConfigSet& config)
+Error Bloom::initExposure()
 {
 	m_exposure.m_width = m_r->getDownscaleBlur().getPassWidth(MAX_U32) * 2;
 	m_exposure.m_height = m_r->getDownscaleBlur().getPassHeight(MAX_U32) * 2;
 
-	m_exposure.m_threshold = config.getNumberF32("r_bloomThreshold");
-	m_exposure.m_scale = config.getNumberF32("r_bloomScale");
-
 	// Create RT info
 	m_exposure.m_rtDescr =
 		m_r->create2DRenderTargetDescription(m_exposure.m_width, m_exposure.m_height, RT_PIXEL_FORMAT, "Bloom Exp");
@@ -50,7 +47,7 @@ Error Bloom::initExposure(const ConfigSet& config)
 	return Error::NONE;
 }
 
-Error Bloom::initUpscale(const ConfigSet& config)
+Error Bloom::initUpscale()
 {
 	m_upscale.m_width = m_r->getPostProcessResolution().x() / BLOOM_FRACTION;
 	m_upscale.m_height = m_r->getPostProcessResolution().y() / BLOOM_FRACTION;
@@ -108,7 +105,7 @@ void Bloom::populateRenderGraph(RenderingContext& ctx)
 			cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
 			rgraphCtx.bindTexture(0, 1, m_r->getDownscaleBlur().getRt(), inputTexSubresource);
 
-			Vec4 uniforms(m_exposure.m_threshold, m_exposure.m_scale, 0.0f, 0.0f);
+			const Vec4 uniforms(getConfig().getRBloomThreshold(), getConfig().getRBloomScale(), 0.0f, 0.0f);
 			cmdb->setPushConstants(&uniforms, sizeof(uniforms));
 
 			rgraphCtx.bindStorageBuffer(0, 2, m_r->getTonemapping().getAverageLuminanceBuffer());

+ 7 - 30
AnKi/Renderer/Bloom.h

@@ -22,10 +22,9 @@ public:
 
 	~Bloom();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg)
+	ANKI_USE_RESULT Error init()
 	{
-		ANKI_R_LOGI("Initializing bloom passes");
-		Error err = initInternal(cfg);
+		const Error err = initInternal();
 		if(err)
 		{
 			ANKI_R_LOGE("Failed to initialize bloom passes");
@@ -41,26 +40,6 @@ public:
 		return m_runCtx.m_upscaleRt;
 	}
 
-	F32 getThreshold() const
-	{
-		return m_exposure.m_threshold;
-	}
-
-	void setThreshold(F32 t)
-	{
-		m_exposure.m_threshold = t;
-	}
-
-	F32 getScale() const
-	{
-		return m_exposure.m_scale;
-	}
-
-	void setScale(F32 t)
-	{
-		m_exposure.m_scale = t;
-	}
-
 private:
 	static constexpr Format RT_PIXEL_FORMAT = Format::A2B10G10R10_UNORM_PACK32;
 
@@ -72,8 +51,6 @@ private:
 		ShaderProgramResourcePtr m_prog;
 		ShaderProgramPtr m_grProg;
 
-		F32 m_threshold = 10.0f; ///< How bright it is
-		F32 m_scale = 1.0f;
 		U32 m_width = 0;
 		U32 m_height = 0;
 
@@ -100,13 +77,13 @@ private:
 		RenderTargetHandle m_upscaleRt;
 	} m_runCtx;
 
-	ANKI_USE_RESULT Error initExposure(const ConfigSet& cfg);
-	ANKI_USE_RESULT Error initUpscale(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initExposure();
+	ANKI_USE_RESULT Error initUpscale();
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg)
+	ANKI_USE_RESULT Error initInternal()
 	{
-		ANKI_CHECK(initExposure(cfg));
-		ANKI_CHECK(initUpscale(cfg));
+		ANKI_CHECK(initExposure());
+		ANKI_CHECK(initUpscale());
 		return Error::NONE;
 	}
 };

+ 1 - 1
AnKi/Renderer/ClusterBinning.cpp

@@ -25,7 +25,7 @@ ClusterBinning::~ClusterBinning()
 {
 }
 
-Error ClusterBinning::init(const ConfigSet& config)
+Error ClusterBinning::init()
 {
 	ANKI_R_LOGI("Initializing clusterer binning");
 

+ 1 - 1
AnKi/Renderer/ClusterBinning.h

@@ -20,7 +20,7 @@ public:
 
 	~ClusterBinning();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& config);
+	ANKI_USE_RESULT Error init();
 
 	/// Populate the rendergraph.
 	void populateRenderGraph(RenderingContext& ctx);

+ 1 - 1
AnKi/Renderer/Common.h

@@ -20,7 +20,7 @@ namespace anki {
 
 // Forward
 #define ANKI_RENDERER_OBJECT_DEF(a, b) class a;
-#include <AnKi/Renderer/RendererObjectDefs.h>
+#include <AnKi/Renderer/RendererObject.defs.h>
 #undef ANKI_RENDERER_OBJECT_DEF
 
 class Renderer;

+ 0 - 64
AnKi/Renderer/ConfigDefs.h

@@ -1,64 +0,0 @@
-// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-ANKI_CONFIG_OPTION(r_textureAnisotropy, 8, 1, 16)
-ANKI_CONFIG_OPTION(r_tileSize, 64, 8, 256, "Tile lighting tile size")
-ANKI_CONFIG_OPTION(r_zSplitCount, 64, 8, 1024, "Clusterer number of Z splits")
-
-ANKI_CONFIG_OPTION(r_internalRenderScaling, 1.0, 0.5, 1.0,
-				   "A factor over the requested swapchain resolution. Applies to all passes up to TAA")
-ANKI_CONFIG_OPTION(r_renderScaling, 1.0, 0.5, 1.0,
-				   "A factor over the requested swapchain resolution. Applies to post-processing and UI")
-
-ANKI_CONFIG_OPTION(r_volumetricLightingAccumulationQualityXY, 4.0, 1.0, 16.0)
-ANKI_CONFIG_OPTION(r_volumetricLightingAccumulationQualityZ, 4.0, 1.0, 16.0)
-ANKI_CONFIG_OPTION(r_volumetricLightingAccumulationFinalZSplit, 26, 1, 256)
-
-ANKI_CONFIG_OPTION(r_ssrMaxSteps, 64, 1, 2048)
-ANKI_CONFIG_OPTION(r_ssrDepthLod, 2, 0, 1000)
-
-ANKI_CONFIG_OPTION(r_ssgiMaxSteps, 32, 1, 2048)
-ANKI_CONFIG_OPTION(r_ssgiDepthLod, 2, 0, 1000)
-
-ANKI_CONFIG_OPTION(r_indirectDiffuseSsgiSamples, 8, 1, 1024)
-ANKI_CONFIG_OPTION(r_indirectDiffuseSsgiRadius, 2.0, 0.1, 100.0)
-ANKI_CONFIG_OPTION(r_indirectDiffuseDenoiseSampleCount, 4, 1, 128)
-
-ANKI_CONFIG_OPTION(r_shadowMappingTileResolution, 128, 16, 2048)
-ANKI_CONFIG_OPTION(r_shadowMappingTileCountPerRowOrColumn, 16, 1, 256)
-ANKI_CONFIG_OPTION(r_shadowMappingScratchTileCountX, 4 * (MAX_SHADOW_CASCADES2 + 2), 1u, 256u,
-				   "Number of tiles of the scratch buffer in X")
-ANKI_CONFIG_OPTION(r_shadowMappingScratchTileCountY, 4, 1, 256, "Number of tiles of the scratch buffer in Y")
-
-ANKI_CONFIG_OPTION(r_probeReflectionResolution, 128, 4, 2048)
-ANKI_CONFIG_OPTION(r_probeReflectionIrradianceResolution, 16, 4, 2048)
-ANKI_CONFIG_OPTION(r_probeRefectionlMaxSimultaneousProbeCount, 32, 4, 256)
-ANKI_CONFIG_OPTION(r_probeReflectionShadowMapResolution, 64, 4, 2048)
-
-ANKI_CONFIG_OPTION(r_lensFlareMaxSpritesPerFlare, 8, 4, 256)
-ANKI_CONFIG_OPTION(r_lensFlareMaxFlares, 16, 8, 256)
-
-ANKI_CONFIG_OPTION(r_giTileResolution, (ANKI_OS_ANDROID) ? 16 : 32, 4, 2048)
-ANKI_CONFIG_OPTION(r_giShadowMapResolution, 128, 4, 2048)
-ANKI_CONFIG_OPTION(r_giMaxCachedProbes, 16, 4, 2048)
-ANKI_CONFIG_OPTION(r_giMaxVisibleProbes, 8, 1, 256)
-
-ANKI_CONFIG_OPTION(r_motionBlurSamples, 32, 1, 2048)
-
-ANKI_CONFIG_OPTION(r_dbgEnabled, 0, 0, 1)
-
-ANKI_CONFIG_OPTION(r_avgObjectsPerCluster, 16, 16, 256)
-
-ANKI_CONFIG_OPTION(r_bloomThreshold, 2.5, 0.0, 256.0)
-ANKI_CONFIG_OPTION(r_bloomScale, 2.5, 0.0, 256.0)
-
-ANKI_CONFIG_OPTION(r_smResolveFactor, 0.5, 0.25, 1.0)
-
-ANKI_CONFIG_OPTION(r_rtShadowsSvgf, 0, 0, 1)
-ANKI_CONFIG_OPTION(r_rtShadowsSvgfAtrousPassCount, 3, 1, 20)
-ANKI_CONFIG_OPTION(r_rtShadowsRaysPerPixel, 1, 1, 8)
-
-ANKI_CONFIG_OPTION(r_fsr, 1, 0, 2, "0: Use bilinear, 1: FSR low quality, 2: FSR high quality")
-ANKI_CONFIG_OPTION(r_sharpen, 1, 0, 1)

+ 67 - 0
AnKi/Renderer/ConfigVars.defs.h

@@ -0,0 +1,67 @@
+// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+ANKI_CONFIG_VAR_GROUP(R)
+
+ANKI_CONFIG_VAR_U8(RTextureAnisotropy, 8, 1, 16, "Texture anisotropy for the main passes")
+ANKI_CONFIG_VAR_U32(RTileSize, 64, 8, 256, "Tile lighting tile size")
+ANKI_CONFIG_VAR_U32(RZSplitCount, 64, 8, 1024, "Clusterer number of Z splits")
+
+ANKI_CONFIG_VAR_F32(RInternalRenderScaling, 1.0f, 0.5f, 1.0f,
+					"A factor over the requested swapchain resolution. Applies to all passes up to TAA")
+ANKI_CONFIG_VAR_F32(RRenderScaling, 1.0f, 0.5f, 1.0f,
+					"A factor over the requested swapchain resolution. Applies to post-processing and UI")
+
+ANKI_CONFIG_VAR_F32(RVolumetricLightingAccumulationQualityXY, 4.0f, 1.0f, 16.0f,
+					"Quality of XY dimensions of volumetric lights")
+ANKI_CONFIG_VAR_F32(RVolumetricLightingAccumulationQualityZ, 4.0f, 1.0f, 16.0f,
+					"Quality of Z dimension of volumetric lights")
+ANKI_CONFIG_VAR_U32(RVolumetricLightingAccumulationFinalZSplit, 26, 1, 256,
+					"Final cluster split that will recieve volumetric lights")
+
+ANKI_CONFIG_VAR_U32(RSsrMaxSteps, 64, 1, 256, "Max SSR raymarching steps")
+ANKI_CONFIG_VAR_U32(RSsrDepthLod, 2, 0, 1000, "Texture LOD of the depth texture that will be raymarched")
+
+ANKI_CONFIG_VAR_U32(RIndirectDiffuseSsgiSampleCount, 8, 1, 1024, "SSGI sample count")
+ANKI_CONFIG_VAR_F32(RIndirectDiffuseSsgiRadius, 2.0f, 0.1f, 100.0f, "SSGI radius in meters")
+ANKI_CONFIG_VAR_U32(RIndirectDiffuseDenoiseSampleCount, 4, 1, 128, "Indirect diffuse denoise sample count")
+ANKI_CONFIG_VAR_F32(RIndirectDiffuseSsaoStrength, 2.5f, 0.1f, 10.0f, "SSAO strength")
+ANKI_CONFIG_VAR_F32(RIndirectDiffuseSsaoBias, -0.1f, -10.0f, 10.0f, "SSAO bias")
+
+ANKI_CONFIG_VAR_U32(RShadowMappingTileResolution, 128, 16, 2048, "Shadowmapping tile resolution")
+ANKI_CONFIG_VAR_U32(RShadowMappingTileCountPerRowOrColumn, 16, 1, 256,
+					"Shadowmapping atlas will have this number squared number of tiles")
+ANKI_CONFIG_VAR_U32(RShadowMappingScratchTileCountX, 4 * (MAX_SHADOW_CASCADES2 + 2), 1, 256,
+					"Number of tiles of the scratch buffer in X")
+ANKI_CONFIG_VAR_U32(RShadowMappingScratchTileCountY, 4, 1, 256, "Number of tiles of the scratch buffer in Y")
+
+ANKI_CONFIG_VAR_U32(RProbeReflectionResolution, 128, 4, 2048, "Reflection probe face resolution")
+ANKI_CONFIG_VAR_U32(RProbeReflectionIrradianceResolution, 16, 4, 2048, "Reflection probe irradiance resolution")
+ANKI_CONFIG_VAR_U32(RProbeRefectionMaxCachedProbes, 32, 4, 256, "Max cached number of reflection probes")
+ANKI_CONFIG_VAR_U32(RProbeReflectionShadowMapResolution, 64, 4, 2048, "Reflection probe shadow resolution")
+
+ANKI_CONFIG_VAR_U8(RLensFlareMaxSpritesPerFlare, 8, 4, 255, "Max sprites per lens flare")
+ANKI_CONFIG_VAR_U8(RLensFlareMaxFlares, 16, 8, 256, "Max flare count")
+
+ANKI_CONFIG_VAR_U32(RGiTileResolution, (ANKI_OS_ANDROID) ? 16 : 32, 4, 2048, "GI tile resolution")
+ANKI_CONFIG_VAR_U32(RGiShadowMapResolution, 128, 4, 2048, "GI shadowmap resolution")
+ANKI_CONFIG_VAR_U32(RGiMaxCachedProbes, 16, 4, 2048, "Max cached probes")
+ANKI_CONFIG_VAR_U32(RGiMaxVisibleProbes, 8, 1, 256, "Max visible GI probes")
+
+ANKI_CONFIG_VAR_U32(RMotionBlurSamples, 32, 1, 2048, "Max motion blur samples")
+
+ANKI_CONFIG_VAR_BOOL(RDbgEnabled, false, "Enable or not debugging")
+
+ANKI_CONFIG_VAR_F32(RBloomThreshold, 2.5f, 0.0f, 256.0f, "Bloom threshold")
+ANKI_CONFIG_VAR_F32(RBloomScale, 2.5f, 0.0f, 256.0f, "Bloom scale")
+
+ANKI_CONFIG_VAR_F32(RSmResolveFactor, 0.5f, 0.25f, 1.0f, "Shadowmapping resolve quality")
+
+ANKI_CONFIG_VAR_BOOL(RRtShadowsSvgf, false, "Enable or not RT shadows SVGF")
+ANKI_CONFIG_VAR_U8(RRtShadowsSvgfAtrousPassCount, 3, 1, 20, "Number of atrous passes of SVGF")
+ANKI_CONFIG_VAR_U32(RRtShadowsRaysPerPixel, 1, 1, 8, "Number of shadow rays per pixel")
+
+ANKI_CONFIG_VAR_U8(RFsr, 1, 0, 2, "0: Use bilinear, 1: FSR low quality, 2: FSR high quality")
+ANKI_CONFIG_VAR_BOOL(RSharpen, true, "Sharpen the image")

+ 5 - 19
AnKi/Renderer/Dbg.cpp

@@ -26,16 +26,8 @@ Dbg::~Dbg()
 {
 }
 
-Error Dbg::init(const ConfigSet& initializer)
+Error Dbg::init()
 {
-	m_enabled = initializer.getBool("r_dbgEnabled");
-	return Error::NONE;
-}
-
-Error Dbg::lazyInit()
-{
-	ANKI_ASSERT(!m_initialized);
-
 	// RT descr
 	m_rtDescr = m_r->create2DRenderTargetDescription(m_r->getInternalResolution().x(), m_r->getInternalResolution().y(),
 													 DBG_COLOR_ATTACHMENT_PIXEL_FORMAT, "Dbg");
@@ -54,7 +46,10 @@ Error Dbg::lazyInit()
 
 void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 {
-	ANKI_ASSERT(m_enabled);
+	if(ANKI_LIKELY(!getConfig().getRDbgEnabled()))
+	{
+		return;
+	}
 
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
@@ -167,15 +162,6 @@ void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 
 void Dbg::populateRenderGraph(RenderingContext& ctx)
 {
-	if(!m_initialized)
-	{
-		if(lazyInit())
-		{
-			return;
-		}
-		m_initialized = true;
-	}
-
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 	// Create RT

+ 1 - 15
AnKi/Renderer/Dbg.h

@@ -23,7 +23,7 @@ public:
 
 	~Dbg();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
+	ANKI_USE_RESULT Error init();
 
 	/// Populate the rendergraph.
 	void populateRenderGraph(RenderingContext& ctx);
@@ -33,16 +33,6 @@ public:
 		return m_runCtx.m_rt;
 	}
 
-	Bool getEnabled() const
-	{
-		return m_enabled;
-	}
-
-	void setEnabled(Bool e)
-	{
-		m_enabled = e;
-	}
-
 	Bool getDepthTestEnabled() const
 	{
 		return m_debugDrawFlags.get(RenderQueueDebugDrawFlag::DEPTH_TEST_ON);
@@ -74,8 +64,6 @@ public:
 	}
 
 private:
-	Bool m_enabled = false;
-	Bool m_initialized = false; ///< Lazily initialize.
 	RenderTargetDescription m_rtDescr;
 	FramebufferDescription m_fbDescr;
 	BitSet<U(RenderQueueDebugDrawFlag::COUNT), U32> m_debugDrawFlags = {false};
@@ -86,8 +74,6 @@ private:
 		RenderTargetHandle m_rt;
 	} m_runCtx;
 
-	ANKI_USE_RESULT Error lazyInit();
-
 	void run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx);
 };
 /// @}

+ 3 - 5
AnKi/Renderer/DepthDownscale.cpp

@@ -29,7 +29,7 @@ DepthDownscale::~DepthDownscale()
 	}
 }
 
-Error DepthDownscale::initInternal(const ConfigSet&)
+Error DepthDownscale::initInternal()
 {
 	const U32 width = m_r->getInternalResolution().x() >> 1;
 	const U32 height = m_r->getInternalResolution().y() >> 1;
@@ -107,11 +107,9 @@ Error DepthDownscale::initInternal(const ConfigSet&)
 	return Error::NONE;
 }
 
-Error DepthDownscale::init(const ConfigSet& cfg)
+Error DepthDownscale::init()
 {
-	ANKI_R_LOGI("Initializing depth downscale passes");
-
-	const Error err = initInternal(cfg);
+	const Error err = initInternal();
 	if(err)
 	{
 		ANKI_R_LOGE("Failed to initialize depth downscale passes");

+ 2 - 2
AnKi/Renderer/DepthDownscale.h

@@ -25,7 +25,7 @@ public:
 
 	~DepthDownscale();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error init();
 
 	/// Import render targets
 	void importRenderTargets(RenderingContext& ctx);
@@ -77,7 +77,7 @@ private:
 		RenderTargetHandle m_hizRt;
 	} m_runCtx; ///< Run context.
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initInternal();
 
 	Bool doesSamplerReduction() const
 	{

+ 3 - 3
AnKi/Renderer/DownscaleBlur.cpp

@@ -14,9 +14,9 @@ DownscaleBlur::~DownscaleBlur()
 	m_fbDescrs.destroy(getAllocator());
 }
 
-Error DownscaleBlur::init(const ConfigSet& cfg)
+Error DownscaleBlur::init()
 {
-	Error err = initInternal(cfg);
+	const Error err = initInternal();
 	if(err)
 	{
 		ANKI_R_LOGE("Failed to initialize downscale blur");
@@ -25,7 +25,7 @@ Error DownscaleBlur::init(const ConfigSet& cfg)
 	return err;
 }
 
-Error DownscaleBlur::initInternal(const ConfigSet&)
+Error DownscaleBlur::initInternal()
 {
 	m_passCount = computeMaxMipmapCount2d(m_r->getPostProcessResolution().x(), m_r->getPostProcessResolution().y(),
 										  DOWNSCALE_BLUR_DOWN_TO)

+ 2 - 3
AnKi/Renderer/DownscaleBlur.h

@@ -23,7 +23,7 @@ public:
 
 	~DownscaleBlur();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error init();
 
 	/// Import render targets
 	void importRenderTargets(RenderingContext& ctx);
@@ -70,8 +70,7 @@ private:
 		RenderTargetHandle m_rt;
 	} m_runCtx;
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
-	ANKI_USE_RESULT Error initSubpass(U idx, const UVec2& inputTexSize);
+	ANKI_USE_RESULT Error initInternal();
 
 	void run(U32 passIdx, RenderPassWorkContext& rgraphCtx);
 };

+ 7 - 10
AnKi/Renderer/FinalComposite.cpp

@@ -11,7 +11,6 @@
 #include <AnKi/Renderer/LightShading.h>
 #include <AnKi/Renderer/GBuffer.h>
 #include <AnKi/Renderer/Dbg.h>
-#include <AnKi/Renderer/Ssr.h>
 #include <AnKi/Renderer/DownscaleBlur.h>
 #include <AnKi/Renderer/UiStage.h>
 #include <AnKi/Renderer/MotionVectors.h>
@@ -29,10 +28,8 @@ FinalComposite::~FinalComposite()
 {
 }
 
-Error FinalComposite::initInternal(const ConfigSet& config)
+Error FinalComposite::initInternal()
 {
-	ANKI_ASSERT("Initializing PPS");
-
 	ANKI_CHECK(loadColorGradingTextureImage("EngineAssets/DefaultLut.ankitex"));
 
 	m_fbDescr.m_colorAttachmentCount = 1;
@@ -49,7 +46,7 @@ Error FinalComposite::initInternal(const ConfigSet& config)
 	variantInitInfo.addMutation("BLOOM_ENABLED", 1);
 	variantInitInfo.addConstant("LUT_SIZE", U32(LUT_SIZE));
 	variantInitInfo.addConstant("FB_SIZE", m_r->getPostProcessResolution());
-	variantInitInfo.addConstant("MOTION_BLUR_SAMPLES", config.getNumberU32("r_motionBlurSamples"));
+	variantInitInfo.addConstant("MOTION_BLUR_SAMPLES", getConfig().getRMotionBlurSamples());
 
 	for(U32 dbg = 0; dbg < 2; ++dbg)
 	{
@@ -68,12 +65,12 @@ Error FinalComposite::initInternal(const ConfigSet& config)
 	return Error::NONE;
 }
 
-Error FinalComposite::init(const ConfigSet& config)
+Error FinalComposite::init()
 {
-	Error err = initInternal(config);
+	const Error err = initInternal();
 	if(err)
 	{
-		ANKI_R_LOGE("Failed to init PPS");
+		ANKI_R_LOGE("Failed to init final composite");
 	}
 
 	return err;
@@ -104,7 +101,7 @@ void FinalComposite::populateRenderGraph(RenderingContext& ctx)
 
 	pass.newDependency({ctx.m_outRenderTarget, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
 
-	if(m_r->getDbg().getEnabled())
+	if(getConfig().getRDbgEnabled())
 	{
 		pass.newDependency({m_r->getDbg().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 	}
@@ -127,7 +124,7 @@ void FinalComposite::populateRenderGraph(RenderingContext& ctx)
 void FinalComposite::run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
-	const Bool dbgEnabled = m_r->getDbg().getEnabled();
+	const Bool dbgEnabled = getConfig().getRDbgEnabled();
 	RenderTargetHandle dbgRt;
 	Bool dbgRtValid;
 	ShaderProgramPtr optionalDebugProgram;

+ 2 - 2
AnKi/Renderer/FinalComposite.h

@@ -20,7 +20,7 @@ public:
 	FinalComposite(Renderer* r);
 	~FinalComposite();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& config);
+	ANKI_USE_RESULT Error init();
 
 	/// Populate the rendergraph.
 	void populateRenderGraph(RenderingContext& ctx);
@@ -42,7 +42,7 @@ private:
 	ImageResourcePtr m_lut; ///< Color grading lookup texture.
 	ImageResourcePtr m_blueNoise;
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& config);
+	ANKI_USE_RESULT Error initInternal();
 
 	void run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 };

+ 0 - 6
AnKi/Renderer/ForwardShading.cpp

@@ -19,12 +19,6 @@ ForwardShading::~ForwardShading()
 {
 }
 
-Error ForwardShading::init(const ConfigSet& cfg)
-{
-	ANKI_R_LOGI("Initializing forward shading");
-	return Error::NONE;
-}
-
 void ForwardShading::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;

+ 4 - 1
AnKi/Renderer/ForwardShading.h

@@ -23,7 +23,10 @@ public:
 
 	~ForwardShading();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
+	ANKI_USE_RESULT Error init()
+	{
+		return Error::NONE;
+	}
 
 	void setDependencies(const RenderingContext& ctx, GraphicsRenderPassDescription& pass);
 

+ 3 - 6
AnKi/Renderer/GBuffer.cpp

@@ -9,7 +9,6 @@
 #include <AnKi/Renderer/LensFlare.h>
 #include <AnKi/Util/Logger.h>
 #include <AnKi/Util/Tracer.h>
-#include <AnKi/Core/ConfigSet.h>
 
 namespace anki {
 
@@ -17,11 +16,9 @@ GBuffer::~GBuffer()
 {
 }
 
-Error GBuffer::init(const ConfigSet& initializer)
+Error GBuffer::init()
 {
-	ANKI_R_LOGI("Initializing g-buffer pass");
-
-	const Error err = initInternal(initializer);
+	const Error err = initInternal();
 	if(err)
 	{
 		ANKI_R_LOGE("Failed to initialize g-buffer pass");
@@ -30,7 +27,7 @@ Error GBuffer::init(const ConfigSet& initializer)
 	return err;
 }
 
-Error GBuffer::initInternal(const ConfigSet& initializer)
+Error GBuffer::initInternal()
 {
 	// RTs
 	static const Array<const char*, 2> depthRtNames = {{"GBuffer depth #0", "GBuffer depth #1"}};

+ 2 - 2
AnKi/Renderer/GBuffer.h

@@ -27,7 +27,7 @@ public:
 
 	~GBuffer();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
+	ANKI_USE_RESULT Error init();
 
 	/// Populate the rendergraph.
 	void populateRenderGraph(RenderingContext& ctx);
@@ -81,7 +81,7 @@ private:
 		RenderTargetHandle m_prevFrameDepthRt;
 	} m_runCtx;
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
+	ANKI_USE_RESULT Error initInternal();
 
 	void runInThread(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx) const;
 };

+ 3 - 4
AnKi/Renderer/GBufferPost.cpp

@@ -7,7 +7,6 @@
 #include <AnKi/Renderer/Renderer.h>
 #include <AnKi/Renderer/GBuffer.h>
 #include <AnKi/Renderer/LightShading.h>
-#include <AnKi/Core/ConfigSet.h>
 
 namespace anki {
 
@@ -15,9 +14,9 @@ GBufferPost::~GBufferPost()
 {
 }
 
-Error GBufferPost::init(const ConfigSet& cfg)
+Error GBufferPost::init()
 {
-	const Error err = initInternal(cfg);
+	const Error err = initInternal();
 	if(err)
 	{
 		ANKI_R_LOGE("Failed to initialize GBufferPost pass");
@@ -25,7 +24,7 @@ Error GBufferPost::init(const ConfigSet& cfg)
 	return err;
 }
 
-Error GBufferPost::initInternal(const ConfigSet& cfg)
+Error GBufferPost::initInternal()
 {
 	ANKI_R_LOGI("Initializing GBufferPost pass");
 

+ 2 - 2
AnKi/Renderer/GBufferPost.h

@@ -23,7 +23,7 @@ public:
 
 	~GBufferPost();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error init();
 
 	/// Populate the rendergraph.
 	void populateRenderGraph(RenderingContext& ctx);
@@ -34,7 +34,7 @@ private:
 
 	FramebufferDescription m_fbDescr;
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initInternal();
 
 	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 };

+ 1 - 1
AnKi/Renderer/GenericCompute.h

@@ -24,7 +24,7 @@ public:
 
 	~GenericCompute();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg)
+	ANKI_USE_RESULT Error init()
 	{
 		return Error::NONE;
 	}

+ 10 - 15
AnKi/Renderer/IndirectDiffuse.cpp

@@ -19,9 +19,9 @@ IndirectDiffuse::~IndirectDiffuse()
 {
 }
 
-Error IndirectDiffuse::init(const ConfigSet& cfg)
+Error IndirectDiffuse::init()
 {
-	const Error err = initInternal(cfg);
+	const Error err = initInternal();
 	if(err)
 	{
 		ANKI_R_LOGE("Failed to initialize indirect diffuse pass");
@@ -29,7 +29,7 @@ Error IndirectDiffuse::init(const ConfigSet& cfg)
 	return err;
 }
 
-Error IndirectDiffuse::initInternal(const ConfigSet& cfg)
+Error IndirectDiffuse::initInternal()
 {
 	const UVec2 size = m_r->getInternalResolution() / 2;
 	ANKI_ASSERT((m_r->getInternalResolution() % 2) == UVec2(0u) && "Needs to be dividable for proper upscaling");
@@ -45,9 +45,6 @@ Error IndirectDiffuse::initInternal(const ConfigSet& cfg)
 
 	// Init SSGI+probes pass
 	{
-		m_main.m_radius = cfg.getNumberF32("r_indirectDiffuseSsgiRadius");
-		m_main.m_sampleCount = cfg.getNumberU32("r_indirectDiffuseSsgiSamples");
-
 		ANKI_CHECK(getResourceManager().loadResource("Shaders/IndirectDiffuse.ankiprog", m_main.m_prog));
 
 		const ShaderProgramResourceVariant* variant;
@@ -57,9 +54,6 @@ Error IndirectDiffuse::initInternal(const ConfigSet& cfg)
 
 	// Init denoise
 	{
-		m_denoise.m_sampleCount = F32(cfg.getNumberU32("r_indirectDiffuseDenoiseSampleCount"));
-		m_denoise.m_sampleCount = max(1.0f, std::round(m_denoise.m_sampleCount / 2.0f));
-
 		ANKI_CHECK(getResourceManager().loadResource("Shaders/IndirectDiffuseDenoise.ankiprog", m_denoise.m_prog));
 
 		ShaderProgramResourceVariantInitInfo variantInit(m_denoise.m_prog);
@@ -143,11 +137,11 @@ 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 = m_main.m_radius;
-			unis.m_sampleCount = m_main.m_sampleCount;
-			unis.m_sampleCountf = F32(m_main.m_sampleCount);
-			unis.m_ssaoBias = m_main.m_ssaoBias;
-			unis.m_ssaoStrength = m_main.m_ssaoStrength;
+			unis.m_radius = getConfig().getRIndirectDiffuseSsgiRadius();
+			unis.m_sampleCount = getConfig().getRIndirectDiffuseSsgiSampleCount();
+			unis.m_sampleCountf = F32(unis.m_sampleCount);
+			unis.m_ssaoBias = getConfig().getRIndirectDiffuseSsaoBias();
+			unis.m_ssaoStrength = getConfig().getRIndirectDiffuseSsaoStrength();
 			cmdb->setPushConstants(&unis, sizeof(unis));
 
 			// Dispatch
@@ -191,7 +185,8 @@ 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 = m_denoise.m_sampleCount;
+			unis.m_sampleCountDiv2 = F32(getConfig().getRIndirectDiffuseDenoiseSampleCount());
+			unis.m_sampleCountDiv2 = max(1.0f, std::round(unis.m_sampleCountDiv2 / 2.0f));
 
 			cmdb->setPushConstants(&unis, sizeof(unis));
 

+ 2 - 7
AnKi/Renderer/IndirectDiffuse.h

@@ -26,7 +26,7 @@ public:
 
 	~IndirectDiffuse();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error init();
 
 	void populateRenderGraph(RenderingContext& ctx);
 
@@ -54,10 +54,6 @@ private:
 	public:
 		ShaderProgramResourcePtr m_prog;
 		ShaderProgramPtr m_grProg;
-		F32 m_radius;
-		U32 m_sampleCount = 8;
-		F32 m_ssaoStrength = 2.5f;
-		F32 m_ssaoBias = -0.1f;
 	} m_main;
 
 	class
@@ -65,7 +61,6 @@ private:
 	public:
 		ShaderProgramResourcePtr m_prog;
 		Array<ShaderProgramPtr, 2> m_grProgs;
-		F32 m_sampleCount = 1.0f;
 	} m_denoise;
 
 	class
@@ -74,7 +69,7 @@ private:
 		Array<RenderTargetHandle, 2> m_mainRtHandles;
 	} m_runCtx;
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initInternal();
 };
 /// @}
 

+ 15 - 17
AnKi/Renderer/IndirectDiffuseProbes.cpp

@@ -95,11 +95,9 @@ void IndirectDiffuseProbes::bindVolumeTextures(const RenderingContext& ctx, Rend
 	}
 }
 
-Error IndirectDiffuseProbes::init(const ConfigSet& cfg)
+Error IndirectDiffuseProbes::init()
 {
-	ANKI_R_LOGI("Initializing global illumination");
-
-	const Error err = initInternal(cfg);
+	const Error err = initInternal();
 	if(err)
 	{
 		ANKI_R_LOGE("Failed to initialize global illumination");
@@ -108,23 +106,23 @@ Error IndirectDiffuseProbes::init(const ConfigSet& cfg)
 	return err;
 }
 
-Error IndirectDiffuseProbes::initInternal(const ConfigSet& cfg)
+Error IndirectDiffuseProbes::initInternal()
 {
-	m_tileSize = cfg.getNumberU32("r_giTileResolution");
-	m_cacheEntries.create(getAllocator(), cfg.getNumberU32("r_giMaxCachedProbes"));
-	m_maxVisibleProbes = cfg.getNumberU32("r_giMaxVisibleProbes");
+	m_tileSize = getConfig().getRGiTileResolution();
+	m_cacheEntries.create(getAllocator(), getConfig().getRGiMaxCachedProbes());
+	m_maxVisibleProbes = getConfig().getRGiMaxVisibleProbes();
 	ANKI_ASSERT(m_maxVisibleProbes <= MAX_VISIBLE_GLOBAL_ILLUMINATION_PROBES);
 	ANKI_ASSERT(m_cacheEntries.getSize() >= m_maxVisibleProbes);
 
-	ANKI_CHECK(initGBuffer(cfg));
-	ANKI_CHECK(initLightShading(cfg));
-	ANKI_CHECK(initShadowMapping(cfg));
-	ANKI_CHECK(initIrradiance(cfg));
+	ANKI_CHECK(initGBuffer());
+	ANKI_CHECK(initLightShading());
+	ANKI_CHECK(initShadowMapping());
+	ANKI_CHECK(initIrradiance());
 
 	return Error::NONE;
 }
 
-Error IndirectDiffuseProbes::initGBuffer(const ConfigSet& cfg)
+Error IndirectDiffuseProbes::initGBuffer()
 {
 	// Create RT descriptions
 	{
@@ -166,9 +164,9 @@ Error IndirectDiffuseProbes::initGBuffer(const ConfigSet& cfg)
 	return Error::NONE;
 }
 
-Error IndirectDiffuseProbes::initShadowMapping(const ConfigSet& cfg)
+Error IndirectDiffuseProbes::initShadowMapping()
 {
-	const U32 resolution = cfg.getNumberU32("r_giShadowMapResolution");
+	const U32 resolution = getConfig().getRGiShadowMapResolution();
 	ANKI_ASSERT(resolution > 8);
 
 	// RT descr
@@ -196,7 +194,7 @@ Error IndirectDiffuseProbes::initShadowMapping(const ConfigSet& cfg)
 	return Error::NONE;
 }
 
-Error IndirectDiffuseProbes::initLightShading(const ConfigSet& cfg)
+Error IndirectDiffuseProbes::initLightShading()
 {
 	// Init RT descr
 	{
@@ -218,7 +216,7 @@ Error IndirectDiffuseProbes::initLightShading(const ConfigSet& cfg)
 	return Error::NONE;
 }
 
-Error IndirectDiffuseProbes::initIrradiance(const ConfigSet& cfg)
+Error IndirectDiffuseProbes::initIrradiance()
 {
 	ANKI_CHECK(m_r->getResourceManager().loadResource("Shaders/IrradianceDice.ankiprog", m_irradiance.m_prog));
 

+ 6 - 6
AnKi/Renderer/IndirectDiffuseProbes.h

@@ -29,7 +29,7 @@ public:
 
 	~IndirectDiffuseProbes();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error init();
 
 	/// Populate the rendergraph.
 	void populateRenderGraph(RenderingContext& ctx);
@@ -101,11 +101,11 @@ private:
 	U32 m_tileSize = 0;
 	U32 m_maxVisibleProbes = 0;
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
-	ANKI_USE_RESULT Error initGBuffer(const ConfigSet& cfg);
-	ANKI_USE_RESULT Error initShadowMapping(const ConfigSet& cfg);
-	ANKI_USE_RESULT Error initLightShading(const ConfigSet& cfg);
-	ANKI_USE_RESULT Error initIrradiance(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initInternal();
+	ANKI_USE_RESULT Error initGBuffer();
+	ANKI_USE_RESULT Error initShadowMapping();
+	ANKI_USE_RESULT Error initLightShading();
+	ANKI_USE_RESULT Error initIrradiance();
 
 	void runGBufferInThread(RenderPassWorkContext& rgraphCtx, InternalContext& giCtx) const;
 	void runShadowmappingInThread(RenderPassWorkContext& rgraphCtx, InternalContext& giCtx) const;

+ 9 - 11
AnKi/Renderer/LensFlare.cpp

@@ -17,11 +17,9 @@ LensFlare::~LensFlare()
 {
 }
 
-Error LensFlare::init(const ConfigSet& config)
+Error LensFlare::init()
 {
-	ANKI_R_LOGI("Initializing lens flare pass");
-
-	Error err = initInternal(config);
+	const Error err = initInternal();
 	if(err)
 	{
 		ANKI_R_LOGE("Failed to initialize lens flare pass");
@@ -30,18 +28,18 @@ Error LensFlare::init(const ConfigSet& config)
 	return err;
 }
 
-Error LensFlare::initInternal(const ConfigSet& config)
+Error LensFlare::initInternal()
 {
-	ANKI_CHECK(initSprite(config));
-	ANKI_CHECK(initOcclusion(config));
+	ANKI_CHECK(initSprite());
+	ANKI_CHECK(initOcclusion());
 
 	return Error::NONE;
 }
 
-Error LensFlare::initSprite(const ConfigSet& config)
+Error LensFlare::initSprite()
 {
-	m_maxSpritesPerFlare = config.getNumberU8("r_lensFlareMaxSpritesPerFlare");
-	m_maxFlares = config.getNumberU8("r_lensFlareMaxFlares");
+	m_maxSpritesPerFlare = getConfig().getRLensFlareMaxSpritesPerFlare();
+	m_maxFlares = getConfig().getRLensFlareMaxFlares();
 
 	if(m_maxSpritesPerFlare < 1 || m_maxFlares < 1)
 	{
@@ -60,7 +58,7 @@ Error LensFlare::initSprite(const ConfigSet& config)
 	return Error::NONE;
 }
 
-Error LensFlare::initOcclusion(const ConfigSet& config)
+Error LensFlare::initOcclusion()
 {
 	GrManager& gr = getGrManager();
 

+ 4 - 4
AnKi/Renderer/LensFlare.h

@@ -25,7 +25,7 @@ public:
 
 	~LensFlare();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& config);
+	ANKI_USE_RESULT Error init();
 
 	void runDrawFlares(const RenderingContext& ctx, CommandBufferPtr& cmdb);
 
@@ -56,10 +56,10 @@ private:
 		BufferHandle m_indirectBuffHandle;
 	} m_runCtx;
 
-	ANKI_USE_RESULT Error initSprite(const ConfigSet& config);
-	ANKI_USE_RESULT Error initOcclusion(const ConfigSet& config);
+	ANKI_USE_RESULT Error initSprite();
+	ANKI_USE_RESULT Error initOcclusion();
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
+	ANKI_USE_RESULT Error initInternal();
 
 	void updateIndirectInfo(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 };

+ 7 - 10
AnKi/Renderer/LightShading.cpp

@@ -16,8 +16,6 @@
 #include <AnKi/Renderer/ShadowmapsResolve.h>
 #include <AnKi/Renderer/RtShadows.h>
 #include <AnKi/Renderer/IndirectDiffuse.h>
-#include <AnKi/Core/ConfigSet.h>
-#include <AnKi/Util/HighRezTimer.h>
 
 namespace anki {
 
@@ -30,19 +28,18 @@ LightShading::~LightShading()
 {
 }
 
-Error LightShading::init(const ConfigSet& config)
+Error LightShading::init()
 {
-	ANKI_R_LOGI("Initializing light stage");
-	Error err = initLightShading(config);
+	Error err = initLightShading();
 
 	if(!err)
 	{
-		err = initApplyFog(config);
+		err = initApplyFog();
 	}
 
 	if(!err)
 	{
-		err = initApplyIndirect(config);
+		err = initApplyIndirect();
 	}
 
 	if(err)
@@ -53,7 +50,7 @@ Error LightShading::init(const ConfigSet& config)
 	return err;
 }
 
-Error LightShading::initLightShading(const ConfigSet& config)
+Error LightShading::initLightShading()
 {
 	// Load shaders and programs
 	ANKI_CHECK(getResourceManager().loadResource("Shaders/LightShading.ankiprog", m_lightShading.m_prog));
@@ -90,7 +87,7 @@ Error LightShading::initLightShading(const ConfigSet& config)
 	return Error::NONE;
 }
 
-Error LightShading::initApplyFog(const ConfigSet& config)
+Error LightShading::initApplyFog()
 {
 	// Load shaders and programs
 	ANKI_CHECK(getResourceManager().loadResource("Shaders/LightShadingApplyFog.ankiprog", m_applyFog.m_prog));
@@ -106,7 +103,7 @@ Error LightShading::initApplyFog(const ConfigSet& config)
 	return Error::NONE;
 }
 
-Error LightShading::initApplyIndirect(const ConfigSet& config)
+Error LightShading::initApplyIndirect()
 {
 	ANKI_CHECK(getResourceManager().loadResource("Shaders/LightShadingApplyIndirect.ankiprog", m_applyIndirect.m_prog));
 	const ShaderProgramResourceVariant* variant;

+ 4 - 4
AnKi/Renderer/LightShading.h

@@ -21,7 +21,7 @@ public:
 
 	~LightShading();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
+	ANKI_USE_RESULT Error init();
 
 	void populateRenderGraph(RenderingContext& ctx);
 
@@ -62,9 +62,9 @@ private:
 		RenderTargetHandle m_rt;
 	} m_runCtx; ///< Run context.
 
-	ANKI_USE_RESULT Error initLightShading(const ConfigSet& config);
-	ANKI_USE_RESULT Error initApplyFog(const ConfigSet& config);
-	ANKI_USE_RESULT Error initApplyIndirect(const ConfigSet& config);
+	ANKI_USE_RESULT Error initLightShading();
+	ANKI_USE_RESULT Error initApplyFog();
+	ANKI_USE_RESULT Error initApplyIndirect();
 
 	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 };

+ 10 - 12
AnKi/Renderer/MainRenderer.cpp

@@ -28,35 +28,33 @@ MainRenderer::~MainRenderer()
 	ANKI_R_LOGI("Destroying main renderer");
 }
 
-Error MainRenderer::init(ThreadHive* hive, ResourceManager* resources, GrManager* gr, StagingGpuMemoryPool* stagingMem,
-						 UiManager* ui, AllocAlignedCallback allocCb, void* allocCbUserData, const ConfigSet& config,
-						 Timestamp* globTimestamp)
+Error MainRenderer::init(const MainRendererInitInfo& inf)
 {
 	ANKI_R_LOGI("Initializing main renderer");
 
-	m_alloc = HeapAllocator<U8>(allocCb, allocCbUserData, "MainRenderer");
-	m_frameAlloc = StackAllocator<U8>(allocCb, allocCbUserData, 1024 * 1024 * 10, 1.0f);
+	m_alloc = HeapAllocator<U8>(inf.m_allocCallback, inf.m_allocCallbackUserData, "MainRenderer");
+	m_frameAlloc = StackAllocator<U8>(inf.m_allocCallback, inf.m_allocCallbackUserData, 10_MB, 1.0f);
 
 	// Init renderer and manipulate the width/height
-	m_swapchainResolution.x() = config.getNumberU32("width");
-	m_swapchainResolution.y() = config.getNumberU32("height");
-	m_renderScaling = config.getNumberF32("r_renderScaling");
+	m_swapchainResolution = inf.m_swapchainSize;
+	m_renderScaling = inf.m_config->getRRenderScaling();
 
 	m_rDrawToDefaultFb = m_renderScaling == 1.0f;
 
 	m_r.reset(m_alloc.newInstance<Renderer>());
-	ANKI_CHECK(m_r->init(hive, resources, gr, stagingMem, ui, m_alloc, config, globTimestamp));
+	ANKI_CHECK(m_r->init(inf.m_threadHive, inf.m_resourceManager, inf.m_gr, inf.m_stagingMemory, inf.m_ui, m_alloc,
+						 inf.m_config, inf.m_globTimestamp, m_swapchainResolution));
 
 	// Init other
 	if(!m_rDrawToDefaultFb)
 	{
-		ANKI_CHECK(resources->loadResource("Shaders/BlitGraphics.ankiprog", m_blitProg));
+		ANKI_CHECK(inf.m_resourceManager->loadResource("Shaders/BlitGraphics.ankiprog", m_blitProg));
 		const ShaderProgramResourceVariant* variant;
 		m_blitProg->getOrCreateVariant(variant);
 		m_blitGrProg = variant->getProgram();
 
 		// The RT desc
-		const Vec2 fresolution = Vec2(F32(config.getNumberU32("width")), F32(config.getNumberU32("height")));
+		const Vec2 fresolution = Vec2(m_swapchainResolution);
 		UVec2 resolution = UVec2(fresolution * m_renderScaling);
 		alignRoundDown(2, resolution.x());
 		alignRoundDown(2, resolution.y());
@@ -72,7 +70,7 @@ Error MainRenderer::init(ThreadHive* hive, ResourceManager* resources, GrManager
 		ANKI_R_LOGI("The main renderer will have to blit the offscreen renderer's result");
 	}
 
-	m_rgraph = gr->newRenderGraph();
+	m_rgraph = inf.m_gr->newRenderGraph();
 
 	ANKI_R_LOGI("Main renderer initialized. Rendering size %ux%u", m_swapchainResolution.x(),
 				m_swapchainResolution.x());

+ 18 - 3
AnKi/Renderer/MainRenderer.h

@@ -29,6 +29,23 @@ public:
 	Second m_renderingGpuSubmitTimestamp ANKI_DEBUG_CODE(= -1.0);
 };
 
+class MainRendererInitInfo
+{
+public:
+	UVec2 m_swapchainSize = UVec2(0u);
+
+	AllocAlignedCallback m_allocCallback = nullptr;
+	void* m_allocCallbackUserData = nullptr;
+
+	ThreadHive* m_threadHive = nullptr;
+	ResourceManager* m_resourceManager = nullptr;
+	GrManager* m_gr = nullptr;
+	StagingGpuMemoryPool* m_stagingMemory = nullptr;
+	UiManager* m_ui = nullptr;
+	ConfigSet* m_config = nullptr;
+	Timestamp* m_globTimestamp = nullptr;
+};
+
 /// Main onscreen renderer
 class MainRenderer
 {
@@ -37,9 +54,7 @@ public:
 
 	~MainRenderer();
 
-	ANKI_USE_RESULT Error init(ThreadHive* hive, ResourceManager* resources, GrManager* gl,
-							   StagingGpuMemoryPool* stagingMem, UiManager* ui, AllocAlignedCallback allocCb,
-							   void* allocCbUserData, const ConfigSet& config, Timestamp* globTimestamp);
+	ANKI_USE_RESULT Error init(const MainRendererInitInfo& inf);
 
 	ANKI_USE_RESULT Error render(RenderQueue& rqueue, TexturePtr presentTex);
 

+ 1 - 3
AnKi/Renderer/MotionVectors.cpp

@@ -14,10 +14,8 @@ MotionVectors::~MotionVectors()
 {
 }
 
-Error MotionVectors::init(const ConfigSet& config)
+Error MotionVectors::init()
 {
-	ANKI_R_LOGI("Initializing motion vectors");
-
 	// Prog
 	ANKI_CHECK(getResourceManager().loadResource("Shaders/MotionVectors.ankiprog", m_prog));
 	ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);

+ 1 - 1
AnKi/Renderer/MotionVectors.h

@@ -26,7 +26,7 @@ public:
 
 	~MotionVectors();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& config);
+	ANKI_USE_RESULT Error init();
 
 	void populateRenderGraph(RenderingContext& ctx);
 

+ 18 - 20
AnKi/Renderer/ProbeReflections.cpp

@@ -27,11 +27,9 @@ ProbeReflections::~ProbeReflections()
 	m_probeUuidToCacheEntryIdx.destroy(getAllocator());
 }
 
-Error ProbeReflections::init(const ConfigSet& config)
+Error ProbeReflections::init()
 {
-	ANKI_R_LOGI("Initializing image reflections");
-
-	const Error err = initInternal(config);
+	const Error err = initInternal();
 	if(err)
 	{
 		ANKI_R_LOGE("Failed to initialize image reflections");
@@ -40,16 +38,16 @@ Error ProbeReflections::init(const ConfigSet& config)
 	return err;
 }
 
-Error ProbeReflections::initInternal(const ConfigSet& config)
+Error ProbeReflections::initInternal()
 {
 	// Init cache entries
-	m_cacheEntries.create(getAllocator(), config.getNumberU32("r_probeRefectionlMaxSimultaneousProbeCount"));
+	m_cacheEntries.create(getAllocator(), getConfig().getRProbeRefectionMaxCachedProbes());
 
-	ANKI_CHECK(initGBuffer(config));
-	ANKI_CHECK(initLightShading(config));
-	ANKI_CHECK(initIrradiance(config));
-	ANKI_CHECK(initIrradianceToRefl(config));
-	ANKI_CHECK(initShadowMapping(config));
+	ANKI_CHECK(initGBuffer());
+	ANKI_CHECK(initLightShading());
+	ANKI_CHECK(initIrradiance());
+	ANKI_CHECK(initIrradianceToRefl());
+	ANKI_CHECK(initShadowMapping());
 
 	// Load split sum integration LUT
 	ANKI_CHECK(getResourceManager().loadResource("EngineAssets/SplitSumIntegration.png", m_integrationLut));
@@ -65,9 +63,9 @@ Error ProbeReflections::initInternal(const ConfigSet& config)
 	return Error::NONE;
 }
 
-Error ProbeReflections::initGBuffer(const ConfigSet& config)
+Error ProbeReflections::initGBuffer()
 {
-	m_gbuffer.m_tileSize = config.getNumberU32("r_probeReflectionResolution");
+	m_gbuffer.m_tileSize = getConfig().getRProbeReflectionResolution();
 
 	// Create RT descriptions
 	{
@@ -111,9 +109,9 @@ Error ProbeReflections::initGBuffer(const ConfigSet& config)
 	return Error::NONE;
 }
 
-Error ProbeReflections::initLightShading(const ConfigSet& config)
+Error ProbeReflections::initLightShading()
 {
-	m_lightShading.m_tileSize = config.getNumberU32("r_probeReflectionResolution");
+	m_lightShading.m_tileSize = getConfig().getRProbeReflectionResolution();
 	m_lightShading.m_mipCount = computeMaxMipmapCount2d(m_lightShading.m_tileSize, m_lightShading.m_tileSize, 8);
 
 	// Init cube arr
@@ -138,9 +136,9 @@ Error ProbeReflections::initLightShading(const ConfigSet& config)
 	return Error::NONE;
 }
 
-Error ProbeReflections::initIrradiance(const ConfigSet& config)
+Error ProbeReflections::initIrradiance()
 {
-	m_irradiance.m_workgroupSize = config.getNumberU32("r_probeReflectionIrradianceResolution");
+	m_irradiance.m_workgroupSize = getConfig().getRProbeReflectionIrradianceResolution();
 
 	// Create prog
 	{
@@ -169,7 +167,7 @@ Error ProbeReflections::initIrradiance(const ConfigSet& config)
 	return Error::NONE;
 }
 
-Error ProbeReflections::initIrradianceToRefl(const ConfigSet& cfg)
+Error ProbeReflections::initIrradianceToRefl()
 {
 	// Create program
 	ANKI_CHECK(m_r->getResourceManager().loadResource("Shaders/ApplyIrradianceToReflection.ankiprog",
@@ -183,9 +181,9 @@ Error ProbeReflections::initIrradianceToRefl(const ConfigSet& cfg)
 	return Error::NONE;
 }
 
-Error ProbeReflections::initShadowMapping(const ConfigSet& cfg)
+Error ProbeReflections::initShadowMapping()
 {
-	const U32 resolution = cfg.getNumberU32("r_probeReflectionShadowMapResolution");
+	const U32 resolution = getConfig().getRProbeReflectionShadowMapResolution();
 	ANKI_ASSERT(resolution > 8);
 
 	// RT descr

+ 7 - 7
AnKi/Renderer/ProbeReflections.h

@@ -25,7 +25,7 @@ public:
 
 	~ProbeReflections();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error init();
 
 	/// Populate the rendergraph.
 	void populateRenderGraph(RenderingContext& ctx);
@@ -131,12 +131,12 @@ private:
 		U32 m_shadowRenderableCount = 0;
 	} m_ctx; ///< Runtime context.
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
-	ANKI_USE_RESULT Error initGBuffer(const ConfigSet& cfg);
-	ANKI_USE_RESULT Error initLightShading(const ConfigSet& cfg);
-	ANKI_USE_RESULT Error initIrradiance(const ConfigSet& cfg);
-	ANKI_USE_RESULT Error initIrradianceToRefl(const ConfigSet& cfg);
-	ANKI_USE_RESULT Error initShadowMapping(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initInternal();
+	ANKI_USE_RESULT Error initGBuffer();
+	ANKI_USE_RESULT Error initLightShading();
+	ANKI_USE_RESULT Error initIrradiance();
+	ANKI_USE_RESULT Error initIrradianceToRefl();
+	ANKI_USE_RESULT Error initShadowMapping();
 
 	/// Lazily init the cache entry
 	void initCacheEntry(U32 cacheEntryIdx);

+ 40 - 42
AnKi/Renderer/Renderer.cpp

@@ -60,7 +60,8 @@ Renderer::~Renderer()
 }
 
 Error Renderer::init(ThreadHive* hive, ResourceManager* resources, GrManager* gl, StagingGpuMemoryPool* stagingMem,
-					 UiManager* ui, HeapAllocator<U8> alloc, const ConfigSet& config, Timestamp* globTimestamp)
+					 UiManager* ui, HeapAllocator<U8> alloc, ConfigSet* config, Timestamp* globTimestamp,
+					 UVec2 swapchainSize)
 {
 	ANKI_TRACE_SCOPED_EVENT(R_INIT);
 
@@ -71,8 +72,9 @@ Error Renderer::init(ThreadHive* hive, ResourceManager* resources, GrManager* gl
 	m_stagingMem = stagingMem;
 	m_ui = ui;
 	m_alloc = alloc;
+	m_config = config;
 
-	Error err = initInternal(config);
+	const Error err = initInternal(swapchainSize);
 	if(err)
 	{
 		ANKI_R_LOGE("Failed to initialize the renderer");
@@ -81,15 +83,15 @@ Error Renderer::init(ThreadHive* hive, ResourceManager* resources, GrManager* gl
 	return err;
 }
 
-Error Renderer::initInternal(const ConfigSet& config)
+Error Renderer::initInternal(UVec2 swapchainSize)
 {
 	m_frameCount = 0;
 
 	// Set from the config
-	const F32 renderScaling = config.getNumberF32("r_renderScaling");
-	const F32 internalRenderScaling = min(config.getNumberF32("r_internalRenderScaling"), renderScaling);
+	const F32 renderScaling = m_config->getRRenderScaling();
+	const F32 internalRenderScaling = min(m_config->getRInternalRenderScaling(), renderScaling);
 
-	const Vec2 fresolution = Vec2(F32(config.getNumberU32("width")), F32(config.getNumberU32("height")));
+	const Vec2 fresolution = Vec2(swapchainSize);
 	m_postProcessResolution = UVec2(fresolution * renderScaling);
 	alignRoundDown(2, m_postProcessResolution.x());
 	alignRoundDown(2, m_postProcessResolution.y());
@@ -101,10 +103,10 @@ Error Renderer::initInternal(const ConfigSet& config)
 	ANKI_R_LOGI("Initializing offscreen renderer. Size %ux%u. Internal size %ux%u", m_postProcessResolution.x(),
 				m_postProcessResolution.y(), m_internalResolution.x(), m_internalResolution.y());
 
-	m_tileSize = config.getNumberU32("r_tileSize");
+	m_tileSize = m_config->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 = config.getNumberU32("r_zSplitCount");
+	m_zSplitCount = m_config->getRZSplitCount();
 
 	// A few sanity checks
 	if(m_internalResolution.x() < 64 || m_internalResolution.y() < 64)
@@ -138,90 +140,90 @@ Error Renderer::initInternal(const ConfigSet& config)
 
 	// Init the stages. Careful with the order!!!!!!!!!!
 	m_genericCompute.reset(m_alloc.newInstance<GenericCompute>(this));
-	ANKI_CHECK(m_genericCompute->init(config));
+	ANKI_CHECK(m_genericCompute->init());
 
 	m_volumetricLightingAccumulation.reset(m_alloc.newInstance<VolumetricLightingAccumulation>(this));
-	ANKI_CHECK(m_volumetricLightingAccumulation->init(config));
+	ANKI_CHECK(m_volumetricLightingAccumulation->init());
 
 	m_indirectDiffuseProbes.reset(m_alloc.newInstance<IndirectDiffuseProbes>(this));
-	ANKI_CHECK(m_indirectDiffuseProbes->init(config));
+	ANKI_CHECK(m_indirectDiffuseProbes->init());
 
 	m_probeReflections.reset(m_alloc.newInstance<ProbeReflections>(this));
-	ANKI_CHECK(m_probeReflections->init(config));
+	ANKI_CHECK(m_probeReflections->init());
 
 	m_gbuffer.reset(m_alloc.newInstance<GBuffer>(this));
-	ANKI_CHECK(m_gbuffer->init(config));
+	ANKI_CHECK(m_gbuffer->init());
 
 	m_gbufferPost.reset(m_alloc.newInstance<GBufferPost>(this));
-	ANKI_CHECK(m_gbufferPost->init(config));
+	ANKI_CHECK(m_gbufferPost->init());
 
 	m_shadowMapping.reset(m_alloc.newInstance<ShadowMapping>(this));
-	ANKI_CHECK(m_shadowMapping->init(config));
+	ANKI_CHECK(m_shadowMapping->init());
 
 	m_volumetricFog.reset(m_alloc.newInstance<VolumetricFog>(this));
-	ANKI_CHECK(m_volumetricFog->init(config));
+	ANKI_CHECK(m_volumetricFog->init());
 
 	m_lightShading.reset(m_alloc.newInstance<LightShading>(this));
-	ANKI_CHECK(m_lightShading->init(config));
+	ANKI_CHECK(m_lightShading->init());
 
 	m_depthDownscale.reset(m_alloc.newInstance<DepthDownscale>(this));
-	ANKI_CHECK(m_depthDownscale->init(config));
+	ANKI_CHECK(m_depthDownscale->init());
 
 	m_forwardShading.reset(m_alloc.newInstance<ForwardShading>(this));
-	ANKI_CHECK(m_forwardShading->init(config));
+	ANKI_CHECK(m_forwardShading->init());
 
 	m_lensFlare.reset(m_alloc.newInstance<LensFlare>(this));
-	ANKI_CHECK(m_lensFlare->init(config));
+	ANKI_CHECK(m_lensFlare->init());
 
 	m_downscaleBlur.reset(getAllocator().newInstance<DownscaleBlur>(this));
-	ANKI_CHECK(m_downscaleBlur->init(config));
+	ANKI_CHECK(m_downscaleBlur->init());
 
 	m_ssr.reset(m_alloc.newInstance<Ssr>(this));
-	ANKI_CHECK(m_ssr->init(config));
+	ANKI_CHECK(m_ssr->init());
 
 	m_tonemapping.reset(getAllocator().newInstance<Tonemapping>(this));
-	ANKI_CHECK(m_tonemapping->init(config));
+	ANKI_CHECK(m_tonemapping->init());
 
 	m_temporalAA.reset(getAllocator().newInstance<TemporalAA>(this));
-	ANKI_CHECK(m_temporalAA->init(config));
+	ANKI_CHECK(m_temporalAA->init());
 
 	m_bloom.reset(m_alloc.newInstance<Bloom>(this));
-	ANKI_CHECK(m_bloom->init(config));
+	ANKI_CHECK(m_bloom->init());
 
 	m_finalComposite.reset(m_alloc.newInstance<FinalComposite>(this));
-	ANKI_CHECK(m_finalComposite->init(config));
+	ANKI_CHECK(m_finalComposite->init());
 
 	m_dbg.reset(m_alloc.newInstance<Dbg>(this));
-	ANKI_CHECK(m_dbg->init(config));
+	ANKI_CHECK(m_dbg->init());
 
 	m_uiStage.reset(m_alloc.newInstance<UiStage>(this));
-	ANKI_CHECK(m_uiStage->init(config));
+	ANKI_CHECK(m_uiStage->init());
 
 	m_scale.reset(m_alloc.newInstance<Scale>(this));
-	ANKI_CHECK(m_scale->init(config));
+	ANKI_CHECK(m_scale->init());
 
 	m_indirectDiffuse.reset(m_alloc.newInstance<IndirectDiffuse>(this));
-	ANKI_CHECK(m_indirectDiffuse->init(config));
+	ANKI_CHECK(m_indirectDiffuse->init());
 
-	if(getGrManager().getDeviceCapabilities().m_rayTracingEnabled && config.getBool("scene_rayTracedShadows"))
+	if(getGrManager().getDeviceCapabilities().m_rayTracingEnabled && getConfig().getSceneRayTracedShadows())
 	{
 		m_accelerationStructureBuilder.reset(m_alloc.newInstance<AccelerationStructureBuilder>(this));
-		ANKI_CHECK(m_accelerationStructureBuilder->init(config));
+		ANKI_CHECK(m_accelerationStructureBuilder->init());
 
 		m_rtShadows.reset(m_alloc.newInstance<RtShadows>(this));
-		ANKI_CHECK(m_rtShadows->init(config));
+		ANKI_CHECK(m_rtShadows->init());
 	}
 	else
 	{
 		m_shadowmapsResolve.reset(m_alloc.newInstance<ShadowmapsResolve>(this));
-		ANKI_CHECK(m_shadowmapsResolve->init(config));
+		ANKI_CHECK(m_shadowmapsResolve->init());
 	}
 
 	m_motionVectors.reset(m_alloc.newInstance<MotionVectors>(this));
-	ANKI_CHECK(m_motionVectors->init(config));
+	ANKI_CHECK(m_motionVectors->init());
 
 	m_clusterBinning.reset(m_alloc.newInstance<ClusterBinning>(this));
-	ANKI_CHECK(m_clusterBinning->init(config));
+	ANKI_CHECK(m_clusterBinning->init());
 
 	// Init samplers
 	{
@@ -238,7 +240,7 @@ Error Renderer::initInternal(const ConfigSet& config)
 		sinit.m_addressing = SamplingAddressing::REPEAT;
 		m_samplers.m_trilinearRepeat = m_gr->newSampler(sinit);
 
-		sinit.m_anisotropyLevel = U8(config.getNumberU32("r_textureAnisotropy"));
+		sinit.m_anisotropyLevel = m_config->getRTextureAnisotropy();
 		m_samplers.m_trilinearRepeatAniso = m_gr->newSampler(sinit);
 
 		const F32 scalingMipBias = log2(F32(m_internalResolution.x()) / F32(m_postProcessResolution.x()));
@@ -364,11 +366,7 @@ Error Renderer::populateRenderGraph(RenderingContext& ctx)
 	m_downscaleBlur->populateRenderGraph(ctx);
 	m_tonemapping->populateRenderGraph(ctx);
 	m_bloom->populateRenderGraph(ctx);
-
-	if(m_dbg->getEnabled())
-	{
-		m_dbg->populateRenderGraph(ctx);
-	}
+	m_dbg->populateRenderGraph(ctx);
 
 	m_finalComposite->populateRenderGraph(ctx);
 

+ 12 - 5
AnKi/Renderer/Renderer.h

@@ -48,7 +48,7 @@ public:
 	{ \
 		return *m_##b; \
 	}
-#include <AnKi/Renderer/RendererObjectDefs.h>
+#include <AnKi/Renderer/RendererObject.defs.h>
 #undef ANKI_RENDERER_OBJECT_DEF
 
 	Bool getRtShadowsEnabled() const
@@ -74,7 +74,7 @@ public:
 	/// Init the renderer.
 	ANKI_USE_RESULT Error init(ThreadHive* hive, ResourceManager* resources, GrManager* gr,
 							   StagingGpuMemoryPool* stagingMem, UiManager* ui, HeapAllocator<U8> alloc,
-							   const ConfigSet& config, Timestamp* globTimestamp);
+							   ConfigSet* config, Timestamp* globTimestamp, UVec2 swapchainSize);
 
 	/// This function does all the rendering stages and produces a final result.
 	ANKI_USE_RESULT Error populateRenderGraph(RenderingContext& ctx);
@@ -128,6 +128,12 @@ public:
 		return *m_resources;
 	}
 
+	const ConfigSet& getConfig() const
+	{
+		ANKI_ASSERT(m_config);
+		return *m_config;
+	}
+
 	Timestamp getGlobalTimestamp() const
 	{
 		return *m_globTimestamp;
@@ -223,13 +229,14 @@ private:
 	StagingGpuMemoryPool* m_stagingMem = nullptr;
 	GrManager* m_gr = nullptr;
 	UiManager* m_ui = nullptr;
-	Timestamp* m_globTimestamp;
+	Timestamp* m_globTimestamp = nullptr;
+	ConfigSet* m_config = nullptr;
 	HeapAllocator<U8> m_alloc;
 
 	/// @name Rendering stages
 	/// @{
 #define ANKI_RENDERER_OBJECT_DEF(a, b) UniquePtr<a> m_##b;
-#include <AnKi/Renderer/RendererObjectDefs.h>
+#include <AnKi/Renderer/RendererObject.defs.h>
 #undef ANKI_RENDERER_OBJECT_DEF
 	/// @}
 
@@ -270,7 +277,7 @@ private:
 	DynamicArray<DebugRtInfo> m_debugRts;
 	String m_currentDebugRtName;
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
+	ANKI_USE_RESULT Error initInternal(UVec2 swapchainSize);
 
 	void initJitteredMats();
 }; // namespace anki

+ 5 - 0
AnKi/Renderer/RendererObject.cpp

@@ -81,4 +81,9 @@ void RendererObject::registerDebugRenderTarget(CString rtName)
 	m_r->registerDebugRenderTarget(this, rtName);
 }
 
+const ConfigSet& RendererObject::getConfig() const
+{
+	return m_r->getConfig();
+}
+
 } // end namespace anki

+ 0 - 0
AnKi/Renderer/RendererObjectDefs.h → AnKi/Renderer/RendererObject.defs.h


+ 2 - 0
AnKi/Renderer/RendererObject.h

@@ -114,6 +114,8 @@ protected:
 	}
 
 	void registerDebugRenderTarget(CString rtName);
+
+	const ConfigSet& getConfig() const;
 };
 /// @}
 

+ 6 - 6
AnKi/Renderer/RtShadows.cpp

@@ -20,9 +20,9 @@ RtShadows::~RtShadows()
 {
 }
 
-Error RtShadows::init(const ConfigSet& cfg)
+Error RtShadows::init()
 {
-	const Error err = initInternal(cfg);
+	const Error err = initInternal();
 	if(err)
 	{
 		ANKI_R_LOGE("Failed to initialize ray traced shadows");
@@ -31,10 +31,10 @@ Error RtShadows::init(const ConfigSet& cfg)
 	return err;
 }
 
-Error RtShadows::initInternal(const ConfigSet& cfg)
+Error RtShadows::initInternal()
 {
-	m_useSvgf = cfg.getNumberU8("r_rtShadowsSvgf") != 0;
-	m_atrousPassCount = cfg.getNumberU8("r_rtShadowsSvgfAtrousPassCount");
+	m_useSvgf = getConfig().getRRtShadowsSvgf();
+	m_atrousPassCount = getConfig().getRRtShadowsSvgfAtrousPassCount();
 
 	ANKI_CHECK(getResourceManager().loadResource("EngineAssets/BlueNoise_Rgba8_64x64.png", m_blueNoiseImage));
 
@@ -43,7 +43,7 @@ Error RtShadows::initInternal(const ConfigSet& cfg)
 		ANKI_CHECK(getResourceManager().loadResource("Shaders/RtShadowsRayGen.ankiprog", m_rayGenProg));
 
 		ShaderProgramResourceVariantInitInfo variantInitInfo(m_rayGenProg);
-		variantInitInfo.addMutation("RAYS_PER_PIXEL", cfg.getNumberU8("r_rtShadowsRaysPerPixel"));
+		variantInitInfo.addMutation("RAYS_PER_PIXEL", getConfig().getRRtShadowsRaysPerPixel());
 
 		const ShaderProgramResourceVariant* variant;
 		m_rayGenProg->getOrCreateVariant(variantInitInfo, variant);

+ 2 - 2
AnKi/Renderer/RtShadows.h

@@ -30,7 +30,7 @@ public:
 
 	~RtShadows();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error init();
 
 	void populateRenderGraph(RenderingContext& ctx);
 
@@ -123,7 +123,7 @@ public:
 		U8 m_denoiseOrientation = 0;
 	} m_runCtx;
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initInternal();
 
 	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 	void runDenoise(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);

+ 3 - 3
AnKi/Renderer/Scale.cpp

@@ -26,10 +26,10 @@ Scale::~Scale()
 {
 }
 
-Error Scale::init(const ConfigSet& cfg)
+Error Scale::init()
 {
 	const Bool needsScaling = m_r->getPostProcessResolution() != m_r->getInternalResolution();
-	const Bool needsSharpening = cfg.getBool("r_sharpen");
+	const Bool needsSharpening = getConfig().getRSharpen();
 	if(!needsScaling && !needsSharpening)
 	{
 		return Error::NONE;
@@ -37,7 +37,7 @@ Error Scale::init(const ConfigSet& cfg)
 
 	ANKI_R_LOGI("Initializing (up|down)scale pass");
 
-	const U32 fsrQuality = cfg.getNumberU8("r_fsr");
+	const U32 fsrQuality = getConfig().getRFsr();
 	m_fsr = fsrQuality != 0;
 
 	// Program

+ 1 - 1
AnKi/Renderer/Scale.h

@@ -23,7 +23,7 @@ public:
 
 	~Scale();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error init();
 
 	void populateRenderGraph(RenderingContext& ctx);
 

+ 22 - 26
AnKi/Renderer/ShadowMapping.cpp

@@ -46,31 +46,31 @@ ShadowMapping::~ShadowMapping()
 {
 }
 
-Error ShadowMapping::init(const ConfigSet& config)
+Error ShadowMapping::init()
 {
-	ANKI_R_LOGI("Initializing shadowmapping");
-
-	const Error err = initInternal(config);
+	const Error err = initInternal();
 	if(err)
 	{
 		ANKI_R_LOGE("Failed to initialize shadowmapping");
 	}
-
-	ANKI_R_LOGI("\tScratch size %ux%u. atlas size %ux%u", m_scratch.m_tileCountX * m_scratch.m_tileResolution,
-				m_scratch.m_tileCountY * m_scratch.m_tileResolution,
-				m_atlas.m_tileCountBothAxis * m_atlas.m_tileResolution,
-				m_atlas.m_tileCountBothAxis * m_atlas.m_tileResolution);
+	else
+	{
+		ANKI_R_LOGI(
+			"Shadowmapping scratch size %ux%u. atlas size %ux%u", m_scratch.m_tileCountX * m_scratch.m_tileResolution,
+			m_scratch.m_tileCountY * m_scratch.m_tileResolution, m_atlas.m_tileCountBothAxis * m_atlas.m_tileResolution,
+			m_atlas.m_tileCountBothAxis * m_atlas.m_tileResolution);
+	}
 
 	return err;
 }
 
-Error ShadowMapping::initScratch(const ConfigSet& cfg)
+Error ShadowMapping::initScratch()
 {
 	// Init the shadowmaps and FBs
 	{
-		m_scratch.m_tileCountX = cfg.getNumberU32("r_shadowMappingScratchTileCountX");
-		m_scratch.m_tileCountY = cfg.getNumberU32("r_shadowMappingScratchTileCountY");
-		m_scratch.m_tileResolution = cfg.getNumberU32("r_shadowMappingTileResolution");
+		m_scratch.m_tileCountX = getConfig().getRShadowMappingScratchTileCountX();
+		m_scratch.m_tileCountY = getConfig().getRShadowMappingScratchTileCountY();
+		m_scratch.m_tileResolution = getConfig().getRShadowMappingTileResolution();
 
 		// RT
 		m_scratch.m_rtDescr = m_r->create2DRenderTargetDescription(m_scratch.m_tileResolution * m_scratch.m_tileCountX,
@@ -90,12 +90,12 @@ Error ShadowMapping::initScratch(const ConfigSet& cfg)
 	return Error::NONE;
 }
 
-Error ShadowMapping::initAtlas(const ConfigSet& cfg)
+Error ShadowMapping::initAtlas()
 {
 	// Init RT
 	{
-		m_atlas.m_tileResolution = cfg.getNumberU32("r_shadowMappingTileResolution");
-		m_atlas.m_tileCountBothAxis = cfg.getNumberU32("r_shadowMappingTileCountPerRowOrColumn");
+		m_atlas.m_tileResolution = getConfig().getRShadowMappingTileResolution();
+		m_atlas.m_tileCountBothAxis = getConfig().getRShadowMappingTileCountPerRowOrColumn();
 
 		// RT
 		TextureInitInfo texinit = m_r->create2DRenderTargetInitInfo(
@@ -130,14 +130,10 @@ Error ShadowMapping::initAtlas(const ConfigSet& cfg)
 	return Error::NONE;
 }
 
-Error ShadowMapping::initInternal(const ConfigSet& cfg)
+Error ShadowMapping::initInternal()
 {
-	ANKI_CHECK(initScratch(cfg));
-	ANKI_CHECK(initAtlas(cfg));
-
-	m_lodDistances[0] = cfg.getNumberF32("lod0MaxDistance");
-	m_lodDistances[1] = cfg.getNumberF32("lod1MaxDistance");
-
+	ANKI_CHECK(initScratch());
+	ANKI_CHECK(initAtlas());
 	return Error::NONE;
 }
 
@@ -292,7 +288,7 @@ void ShadowMapping::chooseLod(const Vec4& cameraOrigin, const PointLightQueueEle
 							  U32& tileBufferLod, U32& renderQueueElementsLod) const
 {
 	const F32 distFromTheCamera = (cameraOrigin - light.m_worldPosition.xyz0()).getLength() - light.m_radius;
-	if(distFromTheCamera < m_lodDistances[0])
+	if(distFromTheCamera < getConfig().getLod0MaxDistance())
 	{
 		ANKI_ASSERT(m_pointLightsMaxLod == 1);
 		blurAtlas = true;
@@ -321,13 +317,13 @@ void ShadowMapping::chooseLod(const Vec4& cameraOrigin, const SpotLightQueueElem
 	const F32 V1len = V.dot(coneDir);
 	const F32 distFromTheCamera = cos(coneAngle) * sqrt(VlenSq - V1len * V1len) - V1len * sin(coneAngle);
 
-	if(distFromTheCamera < m_lodDistances[0])
+	if(distFromTheCamera < getConfig().getLod0MaxDistance())
 	{
 		blurAtlas = true;
 		tileBufferLod = 2;
 		renderQueueElementsLod = 0;
 	}
-	else if(distFromTheCamera < m_lodDistances[1])
+	else if(distFromTheCamera < getConfig().getLod1MaxDistance())
 	{
 		blurAtlas = false;
 		tileBufferLod = 1;

+ 4 - 5
AnKi/Renderer/ShadowMapping.h

@@ -26,7 +26,7 @@ public:
 
 	~ShadowMapping();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
+	ANKI_USE_RESULT Error init();
 
 	/// Populate the rendergraph.
 	void populateRenderGraph(RenderingContext& ctx);
@@ -59,7 +59,7 @@ private:
 		WeakArray<ResolveWorkItem> m_resolveWorkItems;
 	} m_atlas;
 
-	ANKI_USE_RESULT Error initAtlas(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initAtlas();
 
 	inline Mat4 createSpotLightTextureMatrix(const UVec4& viewport) const;
 
@@ -90,7 +90,7 @@ private:
 		U32 m_maxViewportHeight = 0;
 	} m_scratch;
 
-	ANKI_USE_RESULT Error initScratch(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initScratch();
 
 	void runShadowMapping(RenderPassWorkContext& rgraphCtx);
 	/// @}
@@ -99,7 +99,6 @@ private:
 	/// @{
 
 	static constexpr U32 m_pointLightsMaxLod = 1;
-	Array<F32, MAX_LOD_COUNT - 1> m_lodDistances;
 
 	/// Find the lod of the light
 	void chooseLod(const Vec4& cameraOrigin, const PointLightQueueElement& light, Bool& blurAtlas, U32& tileBufferLod,
@@ -123,7 +122,7 @@ private:
 	/// Iterate lights and create work items.
 	void processLights(RenderingContext& ctx, U32& threadCountForScratchPass);
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& config);
+	ANKI_USE_RESULT Error initInternal();
 	/// @}
 };
 /// @}

+ 5 - 5
AnKi/Renderer/ShadowmapsResolve.cpp

@@ -15,9 +15,9 @@ ShadowmapsResolve::~ShadowmapsResolve()
 {
 }
 
-Error ShadowmapsResolve::init(const ConfigSet& cfg)
+Error ShadowmapsResolve::init()
 {
-	const Error err = initInternal(cfg);
+	const Error err = initInternal();
 	if(err)
 	{
 		ANKI_R_LOGE("Failed to initialize shadow resolve pass");
@@ -26,11 +26,11 @@ Error ShadowmapsResolve::init(const ConfigSet& cfg)
 	return Error::NONE;
 }
 
-Error ShadowmapsResolve::initInternal(const ConfigSet& cfg)
+Error ShadowmapsResolve::initInternal()
 {
-	U32 width = U32(cfg.getNumberF32("r_smResolveFactor") * F32(m_r->getInternalResolution().x()));
+	U32 width = U32(getConfig().getRSmResolveFactor() * F32(m_r->getInternalResolution().x()));
 	width = min(m_r->getInternalResolution().x(), getAlignedRoundUp(4, width));
-	U32 height = U32(cfg.getNumberF32("r_smResolveFactor") * F32(m_r->getInternalResolution().y()));
+	U32 height = U32(getConfig().getRSmResolveFactor() * F32(m_r->getInternalResolution().y()));
 	height = min(m_r->getInternalResolution().y(), getAlignedRoundUp(4, height));
 	ANKI_R_LOGI("Initializing shadow resolve pass. Size %ux%u", width, height);
 

+ 2 - 2
AnKi/Renderer/ShadowmapsResolve.h

@@ -26,7 +26,7 @@ public:
 
 	~ShadowmapsResolve();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error init();
 
 	void populateRenderGraph(RenderingContext& ctx);
 
@@ -53,7 +53,7 @@ public:
 		RenderTargetHandle m_rt;
 	} m_runCtx;
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initInternal();
 
 	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 };

+ 6 - 9
AnKi/Renderer/Ssr.cpp

@@ -18,9 +18,9 @@ Ssr::~Ssr()
 {
 }
 
-Error Ssr::init(const ConfigSet& cfg)
+Error Ssr::init()
 {
-	const Error err = initInternal(cfg);
+	const Error err = initInternal();
 	if(err)
 	{
 		ANKI_R_LOGE("Failed to initialize SSR pass");
@@ -28,13 +28,10 @@ Error Ssr::init(const ConfigSet& cfg)
 	return err;
 }
 
-Error Ssr::initInternal(const ConfigSet& cfg)
+Error Ssr::initInternal()
 {
 	const U32 width = m_r->getInternalResolution().x();
 	const U32 height = m_r->getInternalResolution().y();
-	ANKI_R_LOGI("Initializing SSR pass (%ux%u)", width, height);
-	m_maxSteps = cfg.getNumberU32("r_ssrMaxSteps");
-	m_depthLod = cfg.getNumberU32("r_ssrDepthLod");
 	m_firstStepPixels = 32;
 
 	ANKI_CHECK(getResourceManager().loadResource("EngineAssets/BlueNoise_Rgba8_16x16.png", m_noiseImage));
@@ -84,7 +81,7 @@ void Ssr::populateRenderGraph(RenderingContext& ctx)
 	rpass.newDependency({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_COMPUTE});
 
 	TextureSubresourceInfo hizSubresource;
-	hizSubresource.m_firstMipmap = min(m_depthLod, m_r->getDepthDownscale().getMipmapCount() - 1);
+	hizSubresource.m_firstMipmap = min(getConfig().getRSsrDepthLod(), m_r->getDepthDownscale().getMipmapCount() - 1);
 	rpass.newDependency({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_COMPUTE, hizSubresource});
 
 	rpass.newDependency({m_r->getDownscaleBlur().getRt(), TextureUsageBit::SAMPLED_COMPUTE});
@@ -96,7 +93,7 @@ void Ssr::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 	cmdb->bindShaderProgram(m_grProg[m_r->getFrameCount() & 1u]);
 
 	rgraphCtx.bindImage(0, 0, m_runCtx.m_rt, TextureSubresourceInfo());
-	const U32 depthLod = min(m_depthLod, m_r->getDepthDownscale().getMipmapCount() - 1);
+	const U32 depthLod = min(getConfig().getRSsrDepthLod(), m_r->getDepthDownscale().getMipmapCount() - 1);
 
 	// Bind uniforms
 	SsrUniforms* unis = allocateAndBindUniforms<SsrUniforms*>(sizeof(SsrUniforms), cmdb, 0, 1);
@@ -105,7 +102,7 @@ void Ssr::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 	unis->m_framebufferSize = UVec2(m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
 	unis->m_frameCount = m_r->getFrameCount() & MAX_U32;
 	unis->m_depthMipCount = m_r->getDepthDownscale().getMipmapCount();
-	unis->m_maxSteps = m_maxSteps;
+	unis->m_maxSteps = getConfig().getRSsrMaxSteps();
 	unis->m_lightBufferMipCount = m_r->getDownscaleBlur().getMipmapCount();
 	unis->m_firstStepPixels = m_firstStepPixels;
 	unis->m_prevViewProjMatMulInvViewProjMat =

+ 2 - 4
AnKi/Renderer/Ssr.h

@@ -24,7 +24,7 @@ public:
 
 	~Ssr();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error init();
 
 	/// Populate the rendergraph.
 	void populateRenderGraph(RenderingContext& ctx);
@@ -42,8 +42,6 @@ private:
 	ImageResourcePtr m_noiseImage;
 
 	Array<U32, 2> m_workgroupSize = {};
-	U32 m_maxSteps = 32;
-	U32 m_depthLod = 0;
 	U32 m_firstStepPixels = 16;
 
 	class
@@ -52,7 +50,7 @@ private:
 		RenderTargetHandle m_rt;
 	} m_runCtx;
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initInternal();
 
 	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 

+ 3 - 5
AnKi/Renderer/TemporalAA.cpp

@@ -21,11 +21,9 @@ TemporalAA::~TemporalAA()
 {
 }
 
-Error TemporalAA::init(const ConfigSet& config)
+Error TemporalAA::init()
 {
-	ANKI_R_LOGI("Initializing TAA");
-	Error err = initInternal(config);
-
+	const Error err = initInternal();
 	if(err)
 	{
 		ANKI_R_LOGE("Failed to init TAA");
@@ -34,7 +32,7 @@ Error TemporalAA::init(const ConfigSet& config)
 	return Error::NONE;
 }
 
-Error TemporalAA::initInternal(const ConfigSet& config)
+Error TemporalAA::initInternal()
 {
 	ANKI_CHECK(m_r->getResourceManager().loadResource("Shaders/TemporalAAResolve.ankiprog", m_prog));
 

+ 2 - 2
AnKi/Renderer/TemporalAA.h

@@ -20,7 +20,7 @@ public:
 
 	~TemporalAA();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error init();
 
 	void populateRenderGraph(RenderingContext& ctx);
 
@@ -51,7 +51,7 @@ private:
 		RenderTargetHandle m_tonemappedRt;
 	} m_runCtx;
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initInternal();
 };
 /// @}
 

+ 3 - 4
AnKi/Renderer/Tonemapping.cpp

@@ -9,9 +9,9 @@
 
 namespace anki {
 
-Error Tonemapping::init(const ConfigSet& cfg)
+Error Tonemapping::init()
 {
-	const Error err = initInternal(cfg);
+	const Error err = initInternal();
 	if(err)
 	{
 		ANKI_R_LOGE("Failed to initialize tonemapping");
@@ -20,12 +20,11 @@ Error Tonemapping::init(const ConfigSet& cfg)
 	return err;
 }
 
-Error Tonemapping::initInternal(const ConfigSet& initializer)
+Error Tonemapping::initInternal()
 {
 	m_inputTexMip = m_r->getDownscaleBlur().getMipmapCount() - 2;
 	const U32 width = m_r->getDownscaleBlur().getPassWidth(m_inputTexMip);
 	const U32 height = m_r->getDownscaleBlur().getPassHeight(m_inputTexMip);
-	ANKI_R_LOGI("Initializing tonemapping (input %ux%u)", width, height);
 
 	// Create program
 	ANKI_CHECK(getResourceManager().loadResource("Shaders/TonemappingAverageLuminance.ankiprog", m_prog));

+ 2 - 2
AnKi/Renderer/Tonemapping.h

@@ -21,7 +21,7 @@ public:
 	{
 	}
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error init();
 
 	void importRenderTargets(RenderingContext& ctx);
 
@@ -46,7 +46,7 @@ private:
 		BufferHandle m_buffHandle;
 	} m_runCtx;
 
-	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error initInternal();
 };
 /// @}
 

+ 1 - 1
AnKi/Renderer/UiStage.cpp

@@ -21,7 +21,7 @@ UiStage::~UiStage()
 {
 }
 
-Error UiStage::init(const ConfigSet&)
+Error UiStage::init()
 {
 	ANKI_CHECK(m_r->getUiManager().newInstance(m_font, "EngineAssets/UbuntuRegular.ttf", Array<U32, 3>{12, 16, 20}));
 	ANKI_CHECK(m_r->getUiManager().newInstance(m_canvas, m_font, 12, m_r->getPostProcessResolution().x(),

+ 1 - 1
AnKi/Renderer/UiStage.h

@@ -20,7 +20,7 @@ public:
 	UiStage(Renderer* r);
 	~UiStage();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
+	ANKI_USE_RESULT Error init();
 
 	void draw(U32 width, U32 height, RenderingContext& ctx, CommandBufferPtr& cmdb);
 

+ 4 - 5
AnKi/Renderer/VolumetricFog.cpp

@@ -14,17 +14,16 @@
 
 namespace anki {
 
-Error VolumetricFog::init(const ConfigSet& config)
+Error VolumetricFog::init()
 {
 	// Misc
-	const F32 qualityXY = config.getNumberF32("r_volumetricLightingAccumulationQualityXY");
-	const F32 qualityZ = config.getNumberF32("r_volumetricLightingAccumulationQualityZ");
-	m_finalZSplit = min(m_r->getZSplitCount(), config.getNumberU32("r_volumetricLightingAccumulationFinalZSplit"));
+	const F32 qualityXY = getConfig().getRVolumetricLightingAccumulationQualityXY();
+	const F32 qualityZ = getConfig().getRVolumetricLightingAccumulationQualityZ();
+	m_finalZSplit = min(m_r->getZSplitCount() - 1, getConfig().getRVolumetricLightingAccumulationFinalZSplit());
 
 	m_volumeSize[0] = U32(F32(m_r->getTileCounts().x()) * qualityXY);
 	m_volumeSize[1] = U32(F32(m_r->getTileCounts().y()) * qualityXY);
 	m_volumeSize[2] = U32(F32(m_finalZSplit + 1) * qualityZ);
-	ANKI_R_LOGI("Initializing volumetric fog. Size %ux%ux%u", m_volumeSize[0], m_volumeSize[1], m_volumeSize[2]);
 
 	// Shaders
 	ANKI_CHECK(getResourceManager().loadResource("Shaders/VolumetricFogAccumulation.ankiprog", m_prog));

+ 1 - 1
AnKi/Renderer/VolumetricFog.h

@@ -25,7 +25,7 @@ public:
 	{
 	}
 
-	ANKI_USE_RESULT Error init(const ConfigSet& config);
+	ANKI_USE_RESULT Error init();
 
 	void setFogParticleColor(const Vec3& col)
 	{

+ 4 - 4
AnKi/Renderer/VolumetricLightingAccumulation.cpp

@@ -21,12 +21,12 @@ VolumetricLightingAccumulation::~VolumetricLightingAccumulation()
 {
 }
 
-Error VolumetricLightingAccumulation::init(const ConfigSet& config)
+Error VolumetricLightingAccumulation::init()
 {
 	// Misc
-	const F32 qualityXY = config.getNumberF32("r_volumetricLightingAccumulationQualityXY");
-	const F32 qualityZ = config.getNumberF32("r_volumetricLightingAccumulationQualityZ");
-	m_finalZSplit = min(m_r->getZSplitCount(), config.getNumberU32("r_volumetricLightingAccumulationFinalZSplit"));
+	const F32 qualityXY = getConfig().getRVolumetricLightingAccumulationQualityXY();
+	const F32 qualityZ = getConfig().getRVolumetricLightingAccumulationQualityZ();
+	m_finalZSplit = min(m_r->getZSplitCount() - 1, getConfig().getRVolumetricLightingAccumulationFinalZSplit());
 
 	m_volumeSize[0] = U32(F32(m_r->getTileCounts().x()) * qualityXY);
 	m_volumeSize[1] = U32(F32(m_r->getTileCounts().y()) * qualityXY);

+ 1 - 1
AnKi/Renderer/VolumetricLightingAccumulation.h

@@ -19,7 +19,7 @@ public:
 	VolumetricLightingAccumulation(Renderer* r);
 	~VolumetricLightingAccumulation();
 
-	ANKI_USE_RESULT Error init(const ConfigSet& config);
+	ANKI_USE_RESULT Error init();
 
 	/// Populate the rendergraph.
 	void populateRenderGraph(RenderingContext& ctx);

+ 0 - 14
AnKi/Resource/ConfigDefs.h

@@ -1,14 +0,0 @@
-// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-ANKI_CONFIG_OPTION(rsrc_maxImageSize, 1024u * 1024u, 4u, MAX_U32)
-ANKI_CONFIG_OPTION(rsrc_dumpShaderSources, 0, 0, 1)
-ANKI_CONFIG_OPTION(
-	rsrc_dataPaths, ".",
-	"The engine loads assets only in from these paths. Separate them with : (it's smart enough to identify drive "
-	"letters in Windows)")
-ANKI_CONFIG_OPTION(rsrc_dataPathExcludedStrings, "build",
-				   "A list of string separated by : that will be used to exclude paths from rsrc_dataPaths")
-ANKI_CONFIG_OPTION(rsrc_transferScratchMemorySize, 256_MB, 1_MB, 4_GB)

+ 16 - 0
AnKi/Resource/ConfigVars.defs.h

@@ -0,0 +1,16 @@
+// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+ANKI_CONFIG_VAR_GROUP(RSRC)
+
+ANKI_CONFIG_VAR_U32(RsrcMaxImageSize, 1024u * 1024u, 4u, MAX_U32, "Max image size to load")
+ANKI_CONFIG_VAR_STRING(
+	RsrcDataPaths, ".",
+	"The engine loads assets only in from these paths. Separate them with : (it's smart enough to identify drive "
+	"letters in Windows)")
+ANKI_CONFIG_VAR_STRING(RsrcDataPathExcludedStrings, "build",
+					   "A list of string separated by : that will be used to exclude paths from rsrc_dataPaths")
+ANKI_CONFIG_VAR_PTR_SIZE(RsrcTransferScratchMemorySize, 256_MB, 1_MB, 4_GB,
+						 "Memory that is used fot texture and buffer uploads")

+ 2 - 1
AnKi/Resource/ImageResource.cpp

@@ -7,6 +7,7 @@
 #include <AnKi/Resource/ImageLoader.h>
 #include <AnKi/Resource/ResourceManager.h>
 #include <AnKi/Resource/AsyncLoader.h>
+#include <AnKi/Core/ConfigSet.h>
 #include <AnKi/Util/Filesystem.h>
 
 namespace anki {
@@ -78,7 +79,7 @@ Error ImageResource::load(const ResourceFilename& filename, Bool async)
 	ResourceFilePtr file;
 	ANKI_CHECK(openFile(filename, file));
 
-	ANKI_CHECK(loader.load(file, filename, getManager().getMaxImageSize()));
+	ANKI_CHECK(loader.load(file, filename, getConfig().getRsrcMaxImageSize()));
 
 	// Various sizes
 	init.m_width = loader.getWidth();

+ 4 - 4
AnKi/Resource/MaterialResource.cpp

@@ -95,7 +95,7 @@ public:
 	public: \
 		static constexpr Bool VALUE = rowCount * columnCount > 1; \
 	};
-#include <AnKi/Gr/ShaderVariableDataTypeDefs.h>
+#include <AnKi/Gr/ShaderVariableDataType.defs.h>
 #undef ANKI_SVDT_MACRO
 
 template<typename T, Bool isArray = IsShaderVarDataTypeAnArray<T>::VALUE>
@@ -804,7 +804,7 @@ Error MaterialResource::parseInputs(XmlElement inputsEl, Bool async)
 	case ShaderVariableDataType::capital: \
 		ANKI_CHECK(GetAttribute<type>()(inputEl, foundVar->ANKI_CONCATENATE(m_, type))); \
 		break;
-#include <AnKi/Gr/ShaderVariableDataTypeDefs.h>
+#include <AnKi/Gr/ShaderVariableDataType.defs.h>
 #undef ANKI_SVDT_MACRO
 
 			default:
@@ -828,7 +828,7 @@ Error MaterialResource::parseInputs(XmlElement inputsEl, Bool async)
 	case ShaderVariableDataType::capital: \
 		ANKI_CHECK(GetAttribute<type>()(inputEl, foundVar->ANKI_CONCATENATE(m_, type))); \
 		break;
-#include <AnKi/Gr/ShaderVariableDataTypeDefs.h>
+#include <AnKi/Gr/ShaderVariableDataType.defs.h>
 #undef ANKI_SVDT_MACRO
 
 			case ShaderVariableDataType::TEXTURE_2D:
@@ -937,7 +937,7 @@ const MaterialVariant& MaterialResource::getOrCreateVariant(const RenderingKey&
 	case ShaderVariableDataType::capital: \
 		initInfo.addConstant(var.getName(), var.getValue<type>()); \
 		break;
-#include <AnKi/Gr/ShaderVariableDataTypeDefs.h>
+#include <AnKi/Gr/ShaderVariableDataType.defs.h>
 #undef ANKI_SVDT_MACRO
 
 		default:

+ 2 - 2
AnKi/Resource/MaterialResource.h

@@ -170,7 +170,7 @@ protected:
 	union
 	{
 #define ANKI_SVDT_MACRO(capital, type, baseType, rowCount, columnCount) type ANKI_CONCATENATE(m_, type);
-#include <AnKi/Gr/ShaderVariableDataTypeDefs.h>
+#include <AnKi/Gr/ShaderVariableDataType.defs.h>
 #undef ANKI_SVDT_MACRO
 	};
 
@@ -195,7 +195,7 @@ protected:
 
 #define ANKI_SVDT_MACRO(capital, type, baseType, rowCount, columnCount) \
 	ANKI_SPECIALIZE_GET_VALUE(type, ANKI_CONCATENATE(m_, type), capital)
-#include <AnKi/Gr/ShaderVariableDataTypeDefs.h>
+#include <AnKi/Gr/ShaderVariableDataType.defs.h>
 #undef ANKI_SVDT_MACRO
 
 #undef ANKI_SPECIALIZE_GET_VALUE

+ 2 - 2
AnKi/Resource/ResourceFilesystem.cpp

@@ -207,10 +207,10 @@ ResourceFilesystem::~ResourceFilesystem()
 Error ResourceFilesystem::init(const ConfigSet& config, const CString& cacheDir)
 {
 	StringListAuto paths(m_alloc);
-	paths.splitString(config.getString("rsrc_dataPaths"), ':');
+	paths.splitString(config.getRsrcDataPaths(), ':');
 
 	StringListAuto excludedStrings(m_alloc);
-	excludedStrings.splitString(config.getString("rsrc_dataPathExcludedStrings"), ':');
+	excludedStrings.splitString(config.getRsrcDataPathExcludedStrings(), ':');
 
 	// Workaround the fact that : is used in drives in Windows
 #if ANKI_OS_WINDOWS

+ 2 - 5
AnKi/Resource/ResourceManager.cpp

@@ -42,6 +42,7 @@ Error ResourceManager::init(ResourceManagerInitInfo& init)
 	m_gr = init.m_gr;
 	m_physics = init.m_physics;
 	m_fs = init.m_resourceFs;
+	m_config = init.m_config;
 	m_vertexMem = init.m_vertexMemory;
 	m_alloc = ResourceAllocator<U8>(init.m_allocCallback, init.m_allocCallbackData);
 
@@ -49,10 +50,6 @@ Error ResourceManager::init(ResourceManagerInitInfo& init)
 
 	m_cacheDir.create(m_alloc, init.m_cacheDir);
 
-	// Init some constants
-	m_maxImageSize = init.m_config->getNumberU32("rsrc_maxImageSize");
-	m_dumpShaderSource = init.m_config->getBool("rsrc_dumpShaderSources");
-
 	// Init type resource managers
 #define ANKI_INSTANTIATE_RESOURCE(rsrc_, ptr_) TypeResourceManager<rsrc_>::init(m_alloc);
 #define ANKI_INSTANSIATE_RESOURCE_DELIMITER()
@@ -65,7 +62,7 @@ Error ResourceManager::init(ResourceManagerInitInfo& init)
 	m_asyncLoader->init(m_alloc);
 
 	m_transferGpuAlloc = m_alloc.newInstance<TransferGpuAllocator>();
-	ANKI_CHECK(m_transferGpuAlloc->init(init.m_config->getNumberU32("rsrc_transferScratchMemorySize"), m_gr, m_alloc));
+	ANKI_CHECK(m_transferGpuAlloc->init(m_config->getRsrcTransferScratchMemorySize(), m_gr, m_alloc));
 
 	// Init the programs
 	m_shaderProgramSystem = m_alloc.newInstance<ShaderProgramResourceSystem>(m_cacheDir, m_gr, m_fs, m_alloc);

+ 8 - 13
AnKi/Resource/ResourceManager.h

@@ -93,7 +93,7 @@ public:
 	GrManager* m_gr = nullptr;
 	PhysicsWorld* m_physics = nullptr;
 	ResourceFilesystem* m_resourceFs = nullptr;
-	const ConfigSet* m_config = nullptr;
+	ConfigSet* m_config = nullptr;
 	CString m_cacheDir;
 	VertexGpuMemoryPool* m_vertexMemory = nullptr;
 	AllocAlignedCallback m_allocCallback = 0;
@@ -130,16 +130,6 @@ public:
 
 	// Internals:
 
-	ANKI_INTERNAL U32 getMaxImageSize() const
-	{
-		return m_maxImageSize;
-	}
-
-	ANKI_INTERNAL Bool getDumpShaderSource() const
-	{
-		return m_dumpShaderSource;
-	}
-
 	ANKI_INTERNAL ResourceAllocator<U8>& getAllocator()
 	{
 		return m_alloc;
@@ -222,21 +212,26 @@ public:
 		return *m_vertexMem;
 	}
 
+	const ConfigSet& getConfig() const
+	{
+		ANKI_ASSERT(m_config);
+		return *m_config;
+	}
+
 private:
 	GrManager* m_gr = nullptr;
 	PhysicsWorld* m_physics = nullptr;
 	ResourceFilesystem* m_fs = nullptr;
+	ConfigSet* m_config = nullptr;
 	ResourceAllocator<U8> m_alloc;
 	TempResourceAllocator<U8> m_tmpAlloc;
 	String m_cacheDir;
-	U32 m_maxImageSize;
 	AsyncLoader* m_asyncLoader = nullptr; ///< Async loading thread
 	ShaderProgramResourceSystem* m_shaderProgramSystem = nullptr;
 	VertexGpuMemoryPool* m_vertexMem = nullptr;
 	U64 m_uuid = 0;
 	U64 m_loadRequestCount = 0;
 	TransferGpuAllocator* m_transferGpuAlloc = nullptr;
-	Bool m_dumpShaderSource = false;
 };
 /// @}
 

+ 5 - 0
AnKi/Resource/ResourceObject.cpp

@@ -58,4 +58,9 @@ Error ResourceObject::openFileParseXml(const CString& filename, XmlDocument& xml
 	return Error::NONE;
 }
 
+const ConfigSet& ResourceObject::getConfig() const
+{
+	return m_manager->getConfig();
+}
+
 } // end namespace anki

+ 2 - 0
AnKi/Resource/ResourceObject.h

@@ -55,6 +55,8 @@ public:
 
 	// Internals:
 
+	ANKI_INTERNAL const ConfigSet& getConfig() const;
+
 	ANKI_INTERNAL void setFilename(const CString& fname)
 	{
 		ANKI_ASSERT(m_fname.isEmpty());

+ 3 - 1
AnKi/Resource/ShaderProgramResourceSystem.cpp

@@ -12,6 +12,7 @@
 #include <AnKi/Util/ThreadHive.h>
 #include <AnKi/Util/System.h>
 #include <AnKi/Util/BitSet.h>
+#include <AnKi/Core/ConfigSet.h>
 
 namespace anki {
 
@@ -66,7 +67,8 @@ Error ShaderProgramResourceSystem::compileAllShaders(CString cacheDir, GrManager
 
 	// Compute hash for both
 	ShaderCompilerOptions compilerOptions;
-	compilerOptions.m_bindlessLimits = gr.getBindlessLimits();
+	compilerOptions.m_bindlessLimits.m_bindlessTextureCount = gr.getConfig().getGrMaxBindlessTextures();
+	compilerOptions.m_bindlessLimits.m_bindlessImageCount = gr.getConfig().getGrMaxBindlessImages();
 	U64 gpuHash = computeHash(&compilerOptions, sizeof(compilerOptions));
 	gpuHash = appendHash(&SHADER_BINARY_VERSION, sizeof(SHADER_BINARY_VERSION), gpuHash);
 

+ 7 - 7
AnKi/Scene/CameraNode.cpp

@@ -7,7 +7,7 @@
 #include <AnKi/Scene/Components/FrustumComponent.h>
 #include <AnKi/Scene/Components/MoveComponent.h>
 #include <AnKi/Scene/Components/SpatialComponent.h>
-#include <AnKi/Scene/SceneGraph.h>
+#include <AnKi/Core/ConfigSet.h>
 
 namespace anki {
 
@@ -70,21 +70,21 @@ void CameraNode::initCommon(FrustumType frustumType)
 		| FrustumComponentVisibilityTestFlag::GENERIC_COMPUTE_JOB_COMPONENTS
 		| FrustumComponentVisibilityTestFlag::UI_COMPONENTS;
 	frc->setEnabledVisibilityTests(visibilityFlags);
-	frc->setLodDistance(0, getSceneGraph().getConfig().m_maxLodDistances[0]);
-	frc->setLodDistance(1, getSceneGraph().getConfig().m_maxLodDistances[1]);
+	frc->setLodDistance(0, getConfig().getLod0MaxDistance());
+	frc->setLodDistance(1, getConfig().getLod1MaxDistance());
 
 	// Extended frustum for RT
-	if(getSceneGraph().getConfig().m_rayTracedShadows)
+	if(getConfig().getSceneRayTracedShadows())
 	{
 		FrustumComponent* rtFrustumComponent = newComponent<FrustumComponent>();
 		rtFrustumComponent->setFrustumType(FrustumType::ORTHOGRAPHIC);
 		rtFrustumComponent->setEnabledVisibilityTests(FrustumComponentVisibilityTestFlag::RAY_TRACING_SHADOWS);
 
-		const F32 dist = getSceneGraph().getConfig().m_rayTracingExtendedFrustumDistance;
+		const F32 dist = getConfig().getSceneRayTracingExtendedFrustumDistance();
 
 		rtFrustumComponent->setOrthographic(0.1f, dist * 2.0f, dist, -dist, dist, -dist);
-		rtFrustumComponent->setLodDistance(0, getSceneGraph().getConfig().m_maxLodDistances[0]);
-		rtFrustumComponent->setLodDistance(1, getSceneGraph().getConfig().m_maxLodDistances[1]);
+		rtFrustumComponent->setLodDistance(0, getConfig().getLod0MaxDistance());
+		rtFrustumComponent->setLodDistance(1, getConfig().getLod1MaxDistance());
 	}
 }
 

+ 0 - 19
AnKi/Scene/ConfigDefs.h

@@ -1,19 +0,0 @@
-// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-ANKI_CONFIG_OPTION(lod0MaxDistance, 20.0, 1.0, MAX_F64, "Distance that will be used to calculate the LOD 0")
-ANKI_CONFIG_OPTION(lod1MaxDistance, 40.0, 2.0, MAX_F64, "Distance that will be used to calculate the LOD 1")
-
-ANKI_CONFIG_OPTION(scene_octreeMaxDepth, 5, 2, 10, "The max depth of the octree")
-ANKI_CONFIG_OPTION(scene_earlyZDistance, 10.0, 0.0, MAX_F64,
-				   "Objects with distance lower than that will be used in early Z")
-
-ANKI_CONFIG_OPTION(scene_reflectionProbeEffectiveDistance, 256.0, 1.0, MAX_F64, "How far reflection probes can look")
-ANKI_CONFIG_OPTION(scene_reflectionProbeShadowEffectiveDistance, 32.0, 1.0, MAX_F64,
-				   "How far to render shadows for reflection probes")
-
-ANKI_CONFIG_OPTION(scene_rayTracedShadows, 0, 0, 1, "Enable or not ray traced shadows. Ignored if RT is not supported")
-ANKI_CONFIG_OPTION(scene_rayTracingExtendedFrustumDistance, 100.0, 10.0, 10000.0,
-				   "Every object that its distance from the camera is bellow that value will take part in ray tracing")

+ 21 - 0
AnKi/Scene/ConfigVars.defs.h

@@ -0,0 +1,21 @@
+// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+ANKI_CONFIG_VAR_GROUP(SCENE)
+
+ANKI_CONFIG_VAR_F32(Lod0MaxDistance, 20.0f, 1.0f, MAX_F32, "Distance that will be used to calculate the LOD 0")
+ANKI_CONFIG_VAR_F32(Lod1MaxDistance, 40.0f, 2.0f, MAX_F32, "Distance that will be used to calculate the LOD 1")
+
+ANKI_CONFIG_VAR_U32(SceneOctreeMaxDepth, 5, 2, 10, "The max depth of the octree")
+ANKI_CONFIG_VAR_F32(SceneEarlyZDistance, 10.0f, 0.0f, MAX_F32,
+					"Objects with distance lower than that will be used in early Z")
+
+ANKI_CONFIG_VAR_F32(SceneReflectionProbeEffectiveDistance, 256.0f, 1.0f, MAX_F32, "How far reflection probes can look")
+ANKI_CONFIG_VAR_F32(SceneReflectionProbeShadowEffectiveDistance, 32.0f, 1.0f, MAX_F32,
+					"How far to render shadows for reflection probes")
+
+ANKI_CONFIG_VAR_BOOL(SceneRayTracedShadows, false, "Enable or not ray traced shadows. Ignored if RT is not supported")
+ANKI_CONFIG_VAR_F32(SceneRayTracingExtendedFrustumDistance, 100.0f, 10.0f, 10000.0f,
+					"Every object that its distance from the camera is bellow that value will take part in ray tracing")

+ 3 - 3
AnKi/Scene/GlobalIlluminationProbeNode.cpp

@@ -4,11 +4,11 @@
 // http://www.anki3d.org/LICENSE
 
 #include <AnKi/Scene/GlobalIlluminationProbeNode.h>
-#include <AnKi/Scene/SceneGraph.h>
 #include <AnKi/Scene/Components/FrustumComponent.h>
 #include <AnKi/Scene/Components/MoveComponent.h>
 #include <AnKi/Scene/Components/SpatialComponent.h>
 #include <AnKi/Scene/Components/GlobalIlluminationProbeComponent.h>
+#include <AnKi/Core/ConfigSet.h>
 
 namespace anki {
 
@@ -120,7 +120,7 @@ GlobalIlluminationProbeNode::GlobalIlluminationProbeNode(SceneGraph* scene, CStr
 		frc->setPerspective(zNear, tempEffectiveDistance, ang, ang);
 		frc->setWorldTransform(m_cubeFaceTransforms[i]);
 		frc->setEnabledVisibilityTests(FrustumComponentVisibilityTestFlag::NONE);
-		frc->setEffectiveShadowDistance(getSceneGraph().getConfig().m_reflectionProbeShadowEffectiveDistance);
+		frc->setEffectiveShadowDistance(getConfig().getSceneReflectionProbeShadowEffectiveDistance());
 	}
 
 	// Spatial component
@@ -151,7 +151,7 @@ void GlobalIlluminationProbeNode::onShapeUpdateOrProbeNeedsRendering()
 		// Compute effective distance
 		F32 effectiveDistance = max(gic.getBoxVolumeSize().x(), gic.getBoxVolumeSize().y());
 		effectiveDistance = max(effectiveDistance, gic.getBoxVolumeSize().z());
-		effectiveDistance = max(effectiveDistance, getSceneGraph().getConfig().m_reflectionProbeEffectiveDistance);
+		effectiveDistance = max(effectiveDistance, getConfig().getSceneReflectionProbeEffectiveDistance());
 
 		// Update frustum components
 		U count = 0;

+ 3 - 4
AnKi/Scene/ReflectionProbeNode.cpp

@@ -8,8 +8,7 @@
 #include <AnKi/Scene/Components/MoveComponent.h>
 #include <AnKi/Scene/Components/FrustumComponent.h>
 #include <AnKi/Scene/Components/SpatialComponent.h>
-#include <AnKi/Scene/SceneGraph.h>
-#include <AnKi/Renderer/LightShading.h>
+#include <AnKi/Core/ConfigSet.h>
 #include <AnKi/Shaders/Include/ClusteredShadingTypes.h>
 
 namespace anki {
@@ -112,7 +111,7 @@ ReflectionProbeNode::ReflectionProbeNode(SceneGraph* scene, CString name)
 		frc->setPerspective(CLUSTER_OBJECT_FRUSTUM_NEAR_PLANE, 10.0f, ang, ang);
 		frc->setWorldTransform(m_frustumTransforms[i]);
 		frc->setEnabledVisibilityTests(FrustumComponentVisibilityTestFlag::NONE);
-		frc->setEffectiveShadowDistance(getSceneGraph().getConfig().m_reflectionProbeShadowEffectiveDistance);
+		frc->setEffectiveShadowDistance(getConfig().getSceneReflectionProbeShadowEffectiveDistance());
 	}
 
 	// Reflection probe comp
@@ -158,7 +157,7 @@ void ReflectionProbeNode::onShapeUpdate(ReflectionProbeComponent& reflc)
 	const Vec3 halfProbeSize = reflc.getBoxVolumeSize() / 2.0f;
 	F32 effectiveDistance = max(halfProbeSize.x(), halfProbeSize.y());
 	effectiveDistance = max(effectiveDistance, halfProbeSize.z());
-	effectiveDistance = max(effectiveDistance, getSceneGraph().getConfig().m_reflectionProbeEffectiveDistance);
+	effectiveDistance = max(effectiveDistance, getConfig().getSceneReflectionProbeEffectiveDistance());
 
 	// Update frustum components
 	iterateComponentsOfType<FrustumComponent>([&](FrustumComponent& frc) {

Some files were not shown because too many files changed in this diff