Browse Source

Some constexpr refactoring

Panagiotis Christopoulos Charitos 3 years ago
parent
commit
bd7db3376d

+ 1 - 1
AnKi/Core/App.cpp

@@ -47,7 +47,7 @@ void* App::MemStats::allocCallback(void* userData, void* ptr, PtrSize size, [[ma
 {
 {
 	ANKI_ASSERT(userData);
 	ANKI_ASSERT(userData);
 
 
-	static const PtrSize MAX_ALIGNMENT = 64;
+	constexpr PtrSize MAX_ALIGNMENT = 64;
 
 
 	struct alignas(MAX_ALIGNMENT) Header
 	struct alignas(MAX_ALIGNMENT) Header
 	{
 	{

+ 1 - 1
AnKi/Core/DeveloperConsole.cpp

@@ -71,7 +71,7 @@ void DeveloperConsole::build(CanvasPtr ctx)
 			ANKI_ASSERT(0);
 			ANKI_ASSERT(0);
 		}
 		}
 
 
-		static const Array<const char*, static_cast<U>(LoggerMessageType::COUNT)> MSG_TEXT = {"I", "E", "W", "F"};
+		static constexpr Array<const char*, static_cast<U>(LoggerMessageType::COUNT)> MSG_TEXT = {"I", "E", "W", "F"};
 		ImGui::TextWrapped("[%s][%s] %s (%s:%d %s)", MSG_TEXT[static_cast<U>(item.m_type)],
 		ImGui::TextWrapped("[%s][%s] %s (%s:%d %s)", MSG_TEXT[static_cast<U>(item.m_type)],
 						   (item.m_subsystem) ? item.m_subsystem : "N/A ", item.m_msg.cstr(), item.m_file, item.m_line,
 						   (item.m_subsystem) ? item.m_subsystem : "N/A ", item.m_msg.cstr(), item.m_file, item.m_line,
 						   item.m_func);
 						   item.m_func);

+ 1 - 1
AnKi/Core/NativeWindow.h

@@ -26,7 +26,7 @@ public:
 	U32 m_depthBits = 0;
 	U32 m_depthBits = 0;
 	U32 m_stencilBits = 0;
 	U32 m_stencilBits = 0;
 	U32 m_samplesCount = 0;
 	U32 m_samplesCount = 0;
-	static const Bool m_doubleBuffer = true;
+	static constexpr Bool m_doubleBuffer = true;
 	/// Create a fullscreen window with the desktop's resolution
 	/// Create a fullscreen window with the desktop's resolution
 	Bool m_fullscreenDesktopRez = false;
 	Bool m_fullscreenDesktopRez = false;
 	Bool m_exclusiveFullscreen = false;
 	Bool m_exclusiveFullscreen = false;

+ 1 - 1
AnKi/Gr/AccelerationStructure.h

@@ -113,7 +113,7 @@ class AccelerationStructure : public GrObject
 	ANKI_GR_OBJECT
 	ANKI_GR_OBJECT
 
 
 public:
 public:
-	static const GrObjectType CLASS_TYPE = GrObjectType::ACCELERATION_STRUCTURE;
+	static constexpr GrObjectType CLASS_TYPE = GrObjectType::ACCELERATION_STRUCTURE;
 
 
 	AccelerationStructureType getType() const
 	AccelerationStructureType getType() const
 	{
 	{

+ 1 - 1
AnKi/Gr/CommandBuffer.h

@@ -124,7 +124,7 @@ class CommandBuffer : public GrObject
 	ANKI_GR_OBJECT
 	ANKI_GR_OBJECT
 
 
 public:
 public:
-	static const GrObjectType CLASS_TYPE = GrObjectType::COMMAND_BUFFER;
+	static constexpr GrObjectType CLASS_TYPE = GrObjectType::COMMAND_BUFFER;
 
 
 	/// Finalize and submit if it's primary command buffer and just finalize if it's second level.
 	/// Finalize and submit if it's primary command buffer and just finalize if it's second level.
 	/// @param[in]  waitFences Optionally wait for some fences.
 	/// @param[in]  waitFences Optionally wait for some fences.

+ 3 - 3
AnKi/Gr/Common.h

@@ -239,11 +239,11 @@ public:
 	U32 m_face = 0;
 	U32 m_face = 0;
 	U32 m_layer = 0;
 	U32 m_layer = 0;
 
 
-	TextureSurfaceInfo() = default;
+	constexpr TextureSurfaceInfo() = default;
 
 
-	TextureSurfaceInfo(const TextureSurfaceInfo&) = default;
+	constexpr TextureSurfaceInfo(const TextureSurfaceInfo&) = default;
 
 
-	TextureSurfaceInfo(U32 level, U32 depth, U32 face, U32 layer)
+	constexpr TextureSurfaceInfo(U32 level, U32 depth, U32 face, U32 layer)
 		: m_level(level)
 		: m_level(level)
 		, m_depth(depth)
 		, m_depth(depth)
 		, m_face(face)
 		, m_face(face)

+ 1 - 1
AnKi/Gr/Fence.h

@@ -18,7 +18,7 @@ class Fence : public GrObject
 	ANKI_GR_OBJECT
 	ANKI_GR_OBJECT
 
 
 public:
 public:
-	static const GrObjectType CLASS_TYPE = GrObjectType::FENCE;
+	static constexpr GrObjectType CLASS_TYPE = GrObjectType::FENCE;
 
 
 	/// Wait for the fence.
 	/// Wait for the fence.
 	/// @param seconds The time to wait in seconds. If it's zero then just return the status.
 	/// @param seconds The time to wait in seconds. If it's zero then just return the status.

+ 1 - 1
AnKi/Gr/Framebuffer.h

@@ -115,7 +115,7 @@ class Framebuffer : public GrObject
 	ANKI_GR_OBJECT
 	ANKI_GR_OBJECT
 
 
 public:
 public:
-	static const GrObjectType CLASS_TYPE = GrObjectType::FRAMEBUFFER;
+	static constexpr GrObjectType CLASS_TYPE = GrObjectType::FRAMEBUFFER;
 
 
 protected:
 protected:
 	/// Construct.
 	/// Construct.

+ 1 - 1
AnKi/Gr/Gl/RenderingThread.h

@@ -52,7 +52,7 @@ public:
 private:
 private:
 	WeakPtr<GrManagerImpl> m_manager;
 	WeakPtr<GrManagerImpl> m_manager;
 
 
-	static const U QUEUE_SIZE = 1024 * 2;
+	static constexpr U QUEUE_SIZE = 1024 * 2;
 	DynamicArray<CommandBufferPtr> m_queue; ///< Command queue
 	DynamicArray<CommandBufferPtr> m_queue; ///< Command queue
 	U64 m_tail; ///< Tail of queue
 	U64 m_tail; ///< Tail of queue
 	U64 m_head; ///< Head of queue. Points to the end
 	U64 m_head; ///< Head of queue. Points to the end

+ 1 - 1
AnKi/Gr/OcclusionQuery.h

@@ -18,7 +18,7 @@ class OcclusionQuery : public GrObject
 	ANKI_GR_OBJECT
 	ANKI_GR_OBJECT
 
 
 public:
 public:
-	static const GrObjectType CLASS_TYPE = GrObjectType::OCCLUSION_QUERY;
+	static constexpr GrObjectType CLASS_TYPE = GrObjectType::OCCLUSION_QUERY;
 
 
 	/// Get the occlusion query result. It won't block.
 	/// Get the occlusion query result. It won't block.
 	OcclusionQueryResult getResult() const;
 	OcclusionQueryResult getResult() const;

+ 1 - 1
AnKi/Gr/RenderGraph.cpp

@@ -1590,7 +1590,7 @@ Error RenderGraph::dumpDependencyDotFile(const RenderGraphDescription& descr, co
 {
 {
 	ANKI_GR_LOGW("Running with debug code");
 	ANKI_GR_LOGW("Running with debug code");
 
 
-	static const Array<const char*, 5> COLORS = {"red", "green", "blue", "magenta", "cyan"};
+	static constexpr Array<const char*, 5> COLORS = {"red", "green", "blue", "magenta", "cyan"};
 	auto alloc = ctx.m_alloc;
 	auto alloc = ctx.m_alloc;
 	StringListAuto slist(alloc);
 	StringListAuto slist(alloc);
 
 

+ 1 - 1
AnKi/Gr/RenderGraph.h

@@ -625,7 +625,7 @@ class RenderGraph final : public GrObject
 	friend class RenderPassWorkContext;
 	friend class RenderPassWorkContext;
 
 
 public:
 public:
-	static const GrObjectType CLASS_TYPE = GrObjectType::RENDER_GRAPH;
+	static constexpr GrObjectType CLASS_TYPE = GrObjectType::RENDER_GRAPH;
 
 
 	/// @name 1st step methods
 	/// @name 1st step methods
 	/// @{
 	/// @{

+ 1 - 1
AnKi/Gr/Sampler.h

@@ -51,7 +51,7 @@ class Sampler : public GrObject
 	ANKI_GR_OBJECT
 	ANKI_GR_OBJECT
 
 
 public:
 public:
-	static const GrObjectType CLASS_TYPE = GrObjectType::SAMPLER;
+	static constexpr GrObjectType CLASS_TYPE = GrObjectType::SAMPLER;
 
 
 protected:
 protected:
 	/// Construct.
 	/// Construct.

+ 1 - 1
AnKi/Gr/Shader.h

@@ -90,7 +90,7 @@ class Shader : public GrObject
 	ANKI_GR_OBJECT
 	ANKI_GR_OBJECT
 
 
 public:
 public:
-	static const GrObjectType CLASS_TYPE = GrObjectType::SHADER;
+	static constexpr GrObjectType CLASS_TYPE = GrObjectType::SHADER;
 
 
 	ShaderType getShaderType() const
 	ShaderType getShaderType() const
 	{
 	{

+ 1 - 1
AnKi/Gr/ShaderProgram.h

@@ -58,7 +58,7 @@ class ShaderProgram : public GrObject
 	ANKI_GR_OBJECT
 	ANKI_GR_OBJECT
 
 
 public:
 public:
-	static const GrObjectType CLASS_TYPE = GrObjectType::SHADER_PROGRAM;
+	static constexpr GrObjectType CLASS_TYPE = GrObjectType::SHADER_PROGRAM;
 
 
 	/// Get the shader group handles that will be used in the SBTs. The size of each handle is
 	/// Get the shader group handles that will be used in the SBTs. The size of each handle is
 	/// GpuDeviceCapabilities::m_shaderGroupHandleSize. To access a handle use:
 	/// GpuDeviceCapabilities::m_shaderGroupHandleSize. To access a handle use:

+ 1 - 1
AnKi/Gr/Texture.h

@@ -100,7 +100,7 @@ class Texture : public GrObject
 	ANKI_GR_OBJECT
 	ANKI_GR_OBJECT
 
 
 public:
 public:
-	static const GrObjectType CLASS_TYPE = GrObjectType::TEXTURE;
+	static constexpr GrObjectType CLASS_TYPE = GrObjectType::TEXTURE;
 
 
 	U32 getWidth() const
 	U32 getWidth() const
 	{
 	{

+ 1 - 1
AnKi/Gr/TextureView.h

@@ -74,7 +74,7 @@ class TextureView : public GrObject
 	ANKI_GR_OBJECT
 	ANKI_GR_OBJECT
 
 
 public:
 public:
-	static const GrObjectType CLASS_TYPE = GrObjectType::TEXTURE_VIEW;
+	static constexpr GrObjectType CLASS_TYPE = GrObjectType::TEXTURE_VIEW;
 
 
 	TextureType getTextureType() const
 	TextureType getTextureType() const
 	{
 	{

+ 1 - 1
AnKi/Gr/TimestampQuery.h

@@ -18,7 +18,7 @@ class TimestampQuery : public GrObject
 	ANKI_GR_OBJECT
 	ANKI_GR_OBJECT
 
 
 public:
 public:
-	static const GrObjectType CLASS_TYPE = GrObjectType::TIMESTAMP_QUERY;
+	static constexpr GrObjectType CLASS_TYPE = GrObjectType::TIMESTAMP_QUERY;
 
 
 	/// Get the result if it's available. It won't block.
 	/// Get the result if it's available. It won't block.
 	TimestampQueryResult getResult(Second& timestamp) const;
 	TimestampQueryResult getResult(Second& timestamp) const;

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

@@ -244,7 +244,7 @@ Error GrManagerImpl::initInstance()
 				ANKI_VK_LOGV("\t%s", layer.layerName);
 				ANKI_VK_LOGV("\t%s", layer.layerName);
 				CString layerName = layer.layerName;
 				CString layerName = layer.layerName;
 
 
-				static const char* validationName = "VK_LAYER_KHRONOS_validation";
+				static constexpr char* validationName = "VK_LAYER_KHRONOS_validation";
 				if((m_config->getGrValidation() || m_config->getGrDebugPrintf()) && layerName == validationName)
 				if((m_config->getGrValidation() || m_config->getGrDebugPrintf()) && layerName == validationName)
 				{
 				{
 					layersToEnable.emplaceBack(validationName);
 					layersToEnable.emplaceBack(validationName);

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

@@ -233,8 +233,8 @@ private:
 
 
 #if ANKI_GR_MANAGER_DEBUG_MEMMORY
 #if ANKI_GR_MANAGER_DEBUG_MEMMORY
 	VkAllocationCallbacks m_debugAllocCbs;
 	VkAllocationCallbacks m_debugAllocCbs;
-	static const U32 MAX_ALLOC_ALIGNMENT = 64;
-	static const PtrSize ALLOC_SIG = 0xF00B00;
+	static constexpr U32 MAX_ALLOC_ALIGNMENT = 64;
+	static constexpr PtrSize ALLOC_SIG = 0xF00B00;
 
 
 	struct alignas(MAX_ALLOC_ALIGNMENT) AllocHeader
 	struct alignas(MAX_ALLOC_ALIGNMENT) AllocHeader
 	{
 	{

+ 1 - 1
AnKi/Gr/Vulkan/Pipeline.cpp

@@ -381,7 +381,7 @@ const VkGraphicsPipelineCreateInfo& PipelineStateTracker::updatePipelineCreateIn
 	dynCi.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
 	dynCi.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
 
 
 	// Almost all state is dynamic. Depth bias is static
 	// Almost all state is dynamic. Depth bias is static
-	static const Array<VkDynamicState, 9> DYN = {
+	static constexpr Array<VkDynamicState, 9> DYN = {
 		{VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_BLEND_CONSTANTS,
 		{VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, VK_DYNAMIC_STATE_BLEND_CONSTANTS,
 		 VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
 		 VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
 		 VK_DYNAMIC_STATE_STENCIL_REFERENCE, VK_DYNAMIC_STATE_LINE_WIDTH, VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR}};
 		 VK_DYNAMIC_STATE_STENCIL_REFERENCE, VK_DYNAMIC_STATE_LINE_WIDTH, VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR}};

+ 19 - 18
AnKi/Math/Mat.h

@@ -50,7 +50,7 @@ public:
 	}
 	}
 
 
 	/// Copy.
 	/// Copy.
-	TMat(const TMat& b)
+	constexpr TMat(const TMat& b)
 	{
 	{
 		for(U i = 0; i < ROW_COUNT; i++)
 		for(U i = 0; i < ROW_COUNT; i++)
 		{
 		{
@@ -58,7 +58,7 @@ public:
 		}
 		}
 	}
 	}
 
 
-	explicit TMat(const T f)
+	explicit constexpr TMat(const T f)
 	{
 	{
 		for(U i = 0; i < ROW_COUNT; i++)
 		for(U i = 0; i < ROW_COUNT; i++)
 		{
 		{
@@ -66,7 +66,7 @@ public:
 		}
 		}
 	}
 	}
 
 
-	explicit TMat(const T arr[])
+	explicit constexpr TMat(const T arr[])
 	{
 	{
 		for(U i = 0; i < N; i++)
 		for(U i = 0; i < N; i++)
 		{
 		{
@@ -77,7 +77,7 @@ public:
 	// 3x3 specific constructors
 	// 3x3 specific constructors
 
 
 	ANKI_ENABLE_METHOD(J == 3 && I == 3)
 	ANKI_ENABLE_METHOD(J == 3 && I == 3)
-	TMat(T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22)
+	constexpr TMat(T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22)
 	{
 	{
 		auto& m = *this;
 		auto& m = *this;
 		m(0, 0) = m00;
 		m(0, 0) = m00;
@@ -92,19 +92,19 @@ public:
 	}
 	}
 
 
 	ANKI_ENABLE_METHOD(J == 3 && I == 3)
 	ANKI_ENABLE_METHOD(J == 3 && I == 3)
-	explicit TMat(const TQuat<T>& q)
+	explicit constexpr TMat(const TQuat<T>& q)
 	{
 	{
 		setRotationPart(q);
 		setRotationPart(q);
 	}
 	}
 
 
 	ANKI_ENABLE_METHOD(J == 3 && I == 3)
 	ANKI_ENABLE_METHOD(J == 3 && I == 3)
-	explicit TMat(const TEuler<T>& e)
+	explicit constexpr TMat(const TEuler<T>& e)
 	{
 	{
 		setRotationPart(e);
 		setRotationPart(e);
 	}
 	}
 
 
 	ANKI_ENABLE_METHOD(J == 3 && I == 3)
 	ANKI_ENABLE_METHOD(J == 3 && I == 3)
-	explicit TMat(const TAxisang<T>& axisang)
+	explicit constexpr TMat(const TAxisang<T>& axisang)
 	{
 	{
 		setRotationPart(axisang);
 		setRotationPart(axisang);
 	}
 	}
@@ -112,7 +112,8 @@ public:
 	// 4x4 specific constructors
 	// 4x4 specific constructors
 
 
 	ANKI_ENABLE_METHOD(J == 4 && I == 4)
 	ANKI_ENABLE_METHOD(J == 4 && I == 4)
-	TMat(T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23, T m30, T m31, T m32, T m33)
+	constexpr TMat(T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23, T m30, T m31,
+				   T m32, T m33)
 	{
 	{
 		auto& m = *this;
 		auto& m = *this;
 		m(0, 0) = m00;
 		m(0, 0) = m00;
@@ -134,7 +135,7 @@ public:
 	}
 	}
 
 
 	ANKI_ENABLE_METHOD(J == 4 && I == 4)
 	ANKI_ENABLE_METHOD(J == 4 && I == 4)
-	TMat(const TVec<T, 4>& translation, const TMat<T, 3, 3>& rotation, const T scale = T(1))
+	constexpr TMat(const TVec<T, 4>& translation, const TMat<T, 3, 3>& rotation, const T scale = T(1))
 	{
 	{
 		if(isZero<T>(scale - T(1)))
 		if(isZero<T>(scale - T(1)))
 		{
 		{
@@ -152,14 +153,14 @@ public:
 	}
 	}
 
 
 	ANKI_ENABLE_METHOD(J == 4 && I == 4)
 	ANKI_ENABLE_METHOD(J == 4 && I == 4)
-	explicit TMat(const TTransform<T>& t)
+	explicit constexpr TMat(const TTransform<T>& t)
 		: TMat(t.getOrigin().xyz1(), t.getRotation().getRotationPart(), t.getScale())
 		: TMat(t.getOrigin().xyz1(), t.getRotation().getRotationPart(), t.getScale())
 	{
 	{
 	}
 	}
 
 
 	/// Set a 4x4 matrix using a 3x4 for the first 3 rows and a vec4 for the 4rth row.
 	/// Set a 4x4 matrix using a 3x4 for the first 3 rows and a vec4 for the 4rth row.
 	ANKI_ENABLE_METHOD(J == 4 && I == 4)
 	ANKI_ENABLE_METHOD(J == 4 && I == 4)
-	explicit TMat(const TMat<T, 3, 4>& m3, const TVec<T, 4>& row3)
+	explicit constexpr TMat(const TMat<T, 3, 4>& m3, const TVec<T, 4>& row3)
 	{
 	{
 		setRow(0, m3.getRow(0));
 		setRow(0, m3.getRow(0));
 		setRow(1, m3.getRow(1));
 		setRow(1, m3.getRow(1));
@@ -170,7 +171,7 @@ public:
 	// 3x4 specific constructors
 	// 3x4 specific constructors
 
 
 	ANKI_ENABLE_METHOD(J == 3 && I == 4)
 	ANKI_ENABLE_METHOD(J == 3 && I == 4)
-	TMat(T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23)
+	constexpr TMat(T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23)
 	{
 	{
 		auto& m = *this;
 		auto& m = *this;
 		m(0, 0) = m00;
 		m(0, 0) = m00;
@@ -188,7 +189,7 @@ public:
 	}
 	}
 
 
 	ANKI_ENABLE_METHOD(J == 3 && I == 4)
 	ANKI_ENABLE_METHOD(J == 3 && I == 4)
-	explicit TMat(const TMat<T, 4, 4>& m4)
+	explicit constexpr TMat(const TMat<T, 4, 4>& m4)
 	{
 	{
 		auto& m = *this;
 		auto& m = *this;
 		m(0, 0) = m4(0, 0);
 		m(0, 0) = m4(0, 0);
@@ -206,7 +207,7 @@ public:
 	}
 	}
 
 
 	ANKI_ENABLE_METHOD(J == 3 && I == 4)
 	ANKI_ENABLE_METHOD(J == 3 && I == 4)
-	explicit TMat(const TVec<T, 3>& translation, const TMat<T, 3, 3>& rotation, const T scale = T(1))
+	explicit constexpr TMat(const TVec<T, 3>& translation, const TMat<T, 3, 3>& rotation, const T scale = T(1))
 	{
 	{
 		if(isZero<T>(scale - T(1)))
 		if(isZero<T>(scale - T(1)))
 		{
 		{
@@ -221,25 +222,25 @@ public:
 	}
 	}
 
 
 	ANKI_ENABLE_METHOD(J == 3 && I == 4)
 	ANKI_ENABLE_METHOD(J == 3 && I == 4)
-	explicit TMat(const TVec<T, 3>& translation, const TQuat<T>& q, const T scale = T(1))
+	explicit constexpr TMat(const TVec<T, 3>& translation, const TQuat<T>& q, const T scale = T(1))
 		: TMat(translation, TMat<T, 3, 3>(q), scale)
 		: TMat(translation, TMat<T, 3, 3>(q), scale)
 	{
 	{
 	}
 	}
 
 
 	ANKI_ENABLE_METHOD(J == 3 && I == 4)
 	ANKI_ENABLE_METHOD(J == 3 && I == 4)
-	explicit TMat(const TVec<T, 3>& translation, const TEuler<T>& b, const T scale = T(1))
+	explicit constexpr TMat(const TVec<T, 3>& translation, const TEuler<T>& b, const T scale = T(1))
 		: TMat(translation, TMat<T, 3, 3>(b), scale)
 		: TMat(translation, TMat<T, 3, 3>(b), scale)
 	{
 	{
 	}
 	}
 
 
 	ANKI_ENABLE_METHOD(J == 3 && I == 4)
 	ANKI_ENABLE_METHOD(J == 3 && I == 4)
-	explicit TMat(const TVec<T, 3>& translation, const TAxisang<T>& b, const T scale = T(1))
+	explicit constexpr TMat(const TVec<T, 3>& translation, const TAxisang<T>& b, const T scale = T(1))
 		: TMat(translation, TMat<T, 3, 3>(b), scale)
 		: TMat(translation, TMat<T, 3, 3>(b), scale)
 	{
 	{
 	}
 	}
 
 
 	ANKI_ENABLE_METHOD(J == 3 && I == 4)
 	ANKI_ENABLE_METHOD(J == 3 && I == 4)
-	explicit TMat(const TTransform<T>& t)
+	explicit constexpr TMat(const TTransform<T>& t)
 		: TMat(t.getOrigin().xyz(), t.getRotation().getRotationPart(), t.getScale())
 		: TMat(t.getOrigin().xyz(), t.getRotation().getRotationPart(), t.getScale())
 	{
 	{
 	}
 	}

+ 2 - 2
AnKi/Renderer/DepthDownscale.cpp

@@ -209,8 +209,8 @@ void DepthDownscale::populateRenderGraph(RenderingContext& ctx)
 
 
 		for(U32 mip = 0; mip < m_mipCount; ++mip)
 		for(U32 mip = 0; mip < m_mipCount; ++mip)
 		{
 		{
-			static const Array<CString, 8> passNames = {"HiZ #1", "HiZ #2", "HiZ #3", "HiZ #4",
-														"HiZ #5", "HiZ #6", "HiZ #7", "HiZ #8"};
+			static constexpr Array<CString, 8> passNames = {"HiZ #1", "HiZ #2", "HiZ #3", "HiZ #4",
+															"HiZ #5", "HiZ #6", "HiZ #7", "HiZ #8"};
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(passNames[mip]);
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(passNames[mip]);
 			pass.setFramebufferInfo(m_fbDescrs[mip], {m_runCtx.m_hizRt});
 			pass.setFramebufferInfo(m_fbDescrs[mip], {m_runCtx.m_hizRt});
 
 

+ 2 - 2
AnKi/Renderer/DownscaleBlur.cpp

@@ -87,8 +87,8 @@ void DownscaleBlur::populateRenderGraph(RenderingContext& ctx)
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 
 	// Create passes
 	// Create passes
-	static const Array<CString, 8> passNames = {"DownBlur #0",  "Down/Blur #1", "Down/Blur #2", "Down/Blur #3",
-												"Down/Blur #4", "Down/Blur #5", "Down/Blur #6", "Down/Blur #7"};
+	static constexpr Array<CString, 8> passNames = {"DownBlur #0",  "Down/Blur #1", "Down/Blur #2", "Down/Blur #3",
+													"Down/Blur #4", "Down/Blur #5", "Down/Blur #6", "Down/Blur #7"};
 	const RenderTargetHandle inRt =
 	const RenderTargetHandle inRt =
 		(m_r->getScale().hasUpscaledHdrRt()) ? m_r->getScale().getUpscaledHdrRt() : m_r->getScale().getTonemappedRt();
 		(m_r->getScale().hasUpscaledHdrRt()) ? m_r->getScale().getUpscaledHdrRt() : m_r->getScale().getTonemappedRt();
 	if(getConfig().getRPreferCompute())
 	if(getConfig().getRPreferCompute())

+ 1 - 1
AnKi/Renderer/FinalComposite.h

@@ -29,7 +29,7 @@ public:
 	Error loadColorGradingTextureImage(CString filename);
 	Error loadColorGradingTextureImage(CString filename);
 
 
 private:
 private:
-	static const U LUT_SIZE = 16;
+	static constexpr U LUT_SIZE = 16;
 
 
 	FramebufferDescription m_fbDescr;
 	FramebufferDescription m_fbDescr;
 
 

+ 2 - 2
AnKi/Renderer/GBuffer.cpp

@@ -35,7 +35,7 @@ Error GBuffer::initInternal()
 				m_r->getInternalResolution().y());
 				m_r->getInternalResolution().y());
 
 
 	// RTs
 	// RTs
-	static const Array<const char*, 2> depthRtNames = {{"GBuffer depth #0", "GBuffer depth #1"}};
+	static constexpr Array<const char*, 2> depthRtNames = {{"GBuffer depth #0", "GBuffer depth #1"}};
 	for(U32 i = 0; i < 2; ++i)
 	for(U32 i = 0; i < 2; ++i)
 	{
 	{
 		const TextureUsageBit usage = TextureUsageBit::ALL_SAMPLED | TextureUsageBit::ALL_FRAMEBUFFER_ATTACHMENT;
 		const TextureUsageBit usage = TextureUsageBit::ALL_SAMPLED | TextureUsageBit::ALL_FRAMEBUFFER_ATTACHMENT;
@@ -46,7 +46,7 @@ Error GBuffer::initInternal()
 		m_depthRts[i] = m_r->createAndClearRenderTarget(texinit, TextureUsageBit::SAMPLED_FRAGMENT);
 		m_depthRts[i] = m_r->createAndClearRenderTarget(texinit, TextureUsageBit::SAMPLED_FRAGMENT);
 	}
 	}
 
 
-	static const Array<const char*, GBUFFER_COLOR_ATTACHMENT_COUNT> rtNames = {
+	static constexpr Array<const char*, GBUFFER_COLOR_ATTACHMENT_COUNT> rtNames = {
 		{"GBuffer rt0", "GBuffer rt1", "GBuffer rt2", "GBuffer rt3"}};
 		{"GBuffer rt0", "GBuffer rt1", "GBuffer rt2", "GBuffer rt3"}};
 	for(U i = 0; i < GBUFFER_COLOR_ATTACHMENT_COUNT; ++i)
 	for(U i = 0; i < GBUFFER_COLOR_ATTACHMENT_COUNT; ++i)
 	{
 	{

+ 5 - 5
AnKi/Renderer/ProbeReflections.cpp

@@ -601,9 +601,9 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 		m_ctx.m_lightShadingRt = rgraph.importRenderTarget(m_lightShading.m_cubeArr, TextureUsageBit::SAMPLED_FRAGMENT);
 		m_ctx.m_lightShadingRt = rgraph.importRenderTarget(m_lightShading.m_cubeArr, TextureUsageBit::SAMPLED_FRAGMENT);
 
 
 		// Passes
 		// Passes
-		static const Array<CString, 6> passNames = {"CubeRefl LightShad #0", "CubeRefl LightShad #1",
-													"CubeRefl LightShad #2", "CubeRefl LightShad #3",
-													"CubeRefl LightShad #4", "CubeRefl LightShad #5"};
+		static constexpr Array<CString, 6> passNames = {"CubeRefl LightShad #0", "CubeRefl LightShad #1",
+														"CubeRefl LightShad #2", "CubeRefl LightShad #3",
+														"CubeRefl LightShad #4", "CubeRefl LightShad #5"};
 		for(U32 faceIdx = 0; faceIdx < 6; ++faceIdx)
 		for(U32 faceIdx = 0; faceIdx < 6; ++faceIdx)
 		{
 		{
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(passNames[faceIdx]);
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(passNames[faceIdx]);
@@ -674,8 +674,8 @@ void ProbeReflections::populateRenderGraph(RenderingContext& rctx)
 
 
 	// Mipmapping "passes"
 	// Mipmapping "passes"
 	{
 	{
-		static const Array<CString, 6> passNames = {"CubeRefl Mip #0", "CubeRefl Mip #1", "CubeRefl Mip #2",
-													"CubeRefl Mip #3", "CubeRefl Mip #4", "CubeRefl Mip #5"};
+		static constexpr Array<CString, 6> passNames = {"CubeRefl Mip #0", "CubeRefl Mip #1", "CubeRefl Mip #2",
+														"CubeRefl Mip #3", "CubeRefl Mip #4", "CubeRefl Mip #5"};
 		for(U32 faceIdx = 0; faceIdx < 6; ++faceIdx)
 		for(U32 faceIdx = 0; faceIdx < 6; ++faceIdx)
 		{
 		{
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(passNames[faceIdx]);
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(passNames[faceIdx]);

+ 3 - 3
AnKi/Renderer/Scale.cpp

@@ -72,9 +72,9 @@ Error Scale::init()
 	m_sharpenMethod = (needsSharpening) ? SharpenMethod::RCAS : SharpenMethod::NONE;
 	m_sharpenMethod = (needsSharpening) ? SharpenMethod::RCAS : SharpenMethod::NONE;
 	m_neeedsTonemapping = (m_upscalingMethod == UpscalingMethod::GR); // Because GR upscaling spits HDR
 	m_neeedsTonemapping = (m_upscalingMethod == UpscalingMethod::GR); // Because GR upscaling spits HDR
 
 
-	static const Array<const Char*, U32(UpscalingMethod::COUNT)> upscalingMethodNames = {"none", "bilinear", "FSR 1.0",
-																						 "DLSS 2"};
-	static const Array<const Char*, U32(SharpenMethod::COUNT)> sharpenMethodNames = {"none", "RCAS"};
+	static constexpr Array<const Char*, U32(UpscalingMethod::COUNT)> upscalingMethodNames = {"none", "bilinear",
+																							 "FSR 1.0", "DLSS 2"};
+	static constexpr Array<const Char*, U32(SharpenMethod::COUNT)> sharpenMethodNames = {"none", "RCAS"};
 
 
 	ANKI_R_LOGV("Initializing upscaling. Upscaling method %s, sharpenning method %s",
 	ANKI_R_LOGV("Initializing upscaling. Upscaling method %s, sharpenning method %s",
 				upscalingMethodNames[U32(m_upscalingMethod)], sharpenMethodNames[U32(m_sharpenMethod)]);
 				upscalingMethodNames[U32(m_upscalingMethod)], sharpenMethodNames[U32(m_sharpenMethod)]);

+ 4 - 4
AnKi/Resource/ImageLoader.cpp

@@ -10,8 +10,8 @@
 
 
 namespace anki {
 namespace anki {
 
 
-static const U8 tgaHeaderUncompressed[12] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-static const U8 tgaHeaderCompressed[12] = {0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+inline constexpr U8 TGA_HEADER_UNCOMPRESSED[12] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+inline constexpr U8 TGA_HEADER_COMPRESSED[12] = {0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
 
 static PtrSize calcRawTexelSize(const ImageBinaryColorFormat cf)
 static PtrSize calcRawTexelSize(const ImageBinaryColorFormat cf)
 {
 {
@@ -365,11 +365,11 @@ Error ImageLoader::loadTga(FileInterface& fs, U32& width, U32& height, U32& bpp,
 
 
 	ANKI_CHECK(fs.read(&myTgaHeader[0], sizeof(myTgaHeader)));
 	ANKI_CHECK(fs.read(&myTgaHeader[0], sizeof(myTgaHeader)));
 
 
-	if(memcmp(tgaHeaderUncompressed, &myTgaHeader[0], sizeof(myTgaHeader)) == 0)
+	if(memcmp(TGA_HEADER_UNCOMPRESSED, &myTgaHeader[0], sizeof(myTgaHeader)) == 0)
 	{
 	{
 		ANKI_CHECK(loadUncompressedTga(fs, width, height, bpp, data, alloc));
 		ANKI_CHECK(loadUncompressedTga(fs, width, height, bpp, data, alloc));
 	}
 	}
-	else if(std::memcmp(tgaHeaderCompressed, &myTgaHeader[0], sizeof(myTgaHeader)) == 0)
+	else if(std::memcmp(TGA_HEADER_COMPRESSED, &myTgaHeader[0], sizeof(myTgaHeader)) == 0)
 	{
 	{
 		ANKI_CHECK(loadCompressedTga(fs, width, height, bpp, data, alloc));
 		ANKI_CHECK(loadCompressedTga(fs, width, height, bpp, data, alloc));
 	}
 	}

+ 2 - 2
AnKi/Resource/MaterialResource.cpp

@@ -10,10 +10,10 @@
 
 
 namespace anki {
 namespace anki {
 
 
-static const Array<CString, U32(BuiltinMutatorId::COUNT)> BUILTIN_MUTATOR_NAMES = {
+inline constexpr Array<CString, U32(BuiltinMutatorId::COUNT)> BUILTIN_MUTATOR_NAMES = {
 	{"NONE", "ANKI_TECHNIQUE", "ANKI_LOD", "ANKI_BONES", "ANKI_VELOCITY"}};
 	{"NONE", "ANKI_TECHNIQUE", "ANKI_LOD", "ANKI_BONES", "ANKI_VELOCITY"}};
 
 
-static const Array<CString, U(RenderingTechnique::COUNT)> TECHNIQUE_NAMES = {
+inline constexpr Array<CString, U(RenderingTechnique::COUNT)> TECHNIQUE_NAMES = {
 	{"GBuffer", "GBufferEarlyZ", "Shadow", "Forward", "RtShadow"}};
 	{"GBuffer", "GBufferEarlyZ", "Shadow", "Forward", "RtShadow"}};
 
 
 // This is some trickery to select calling between XmlElement::getAttributeNumber and XmlElement::getAttributeNumbers
 // This is some trickery to select calling between XmlElement::getAttributeNumber and XmlElement::getAttributeNumbers

+ 1 - 1
AnKi/Resource/ResourceFilesystem.cpp

@@ -264,7 +264,7 @@ Error ResourceFilesystem::addNewPath(const CString& filepath, const StringListAu
 	ANKI_RESOURCE_LOGV("Adding new resource path: %s", filepath.cstr());
 	ANKI_RESOURCE_LOGV("Adding new resource path: %s", filepath.cstr());
 
 
 	U32 fileCount = 0; // Count files manually because it's slower to get that number from the list
 	U32 fileCount = 0; // Count files manually because it's slower to get that number from the list
-	static const CString extension(".ankizip");
+	constexpr CString extension(".ankizip");
 
 
 	auto rejectPath = [&](CString p) -> Bool {
 	auto rejectPath = [&](CString p) -> Bool {
 		for(const String& s : excludedStrings)
 		for(const String& s : excludedStrings)

+ 3 - 3
AnKi/Scene/VisibilityInternal.h

@@ -18,9 +18,9 @@ namespace anki {
 /// @addtogroup scene
 /// @addtogroup scene
 /// @{
 /// @{
 
 
-static const U32 MAX_SPATIALS_PER_VIS_TEST = 48; ///< Num of spatials to test in a single ThreadHive task.
-static const U32 SW_RASTERIZER_WIDTH = 80;
-static const U32 SW_RASTERIZER_HEIGHT = 50;
+constexpr U32 MAX_SPATIALS_PER_VIS_TEST = 48; ///< Num of spatials to test in a single ThreadHive task.
+constexpr U32 SW_RASTERIZER_WIDTH = 80;
+constexpr U32 SW_RASTERIZER_HEIGHT = 50;
 
 
 /// Sort objects on distance
 /// Sort objects on distance
 template<typename T>
 template<typename T>

+ 2 - 2
AnKi/ShaderCompiler/ShaderProgramParser.cpp

@@ -15,11 +15,11 @@ namespace anki {
 	ANKI_SHADER_COMPILER_LOGE("%s: " msg_ ": %s", fname.cstr(), line.cstr()); \
 	ANKI_SHADER_COMPILER_LOGE("%s: " msg_ ": %s", fname.cstr(), line.cstr()); \
 	return Error::USER_DATA
 	return Error::USER_DATA
 
 
-static const Array<CString, U32(ShaderType::COUNT)> SHADER_STAGE_NAMES = {
+inline constexpr Array<CString, U32(ShaderType::COUNT)> SHADER_STAGE_NAMES = {
 	{"VERTEX", "TESSELLATION_CONTROL", "TESSELLATION_EVALUATION", "GEOMETRY", "FRAGMENT", "COMPUTE", "RAY_GEN",
 	{"VERTEX", "TESSELLATION_CONTROL", "TESSELLATION_EVALUATION", "GEOMETRY", "FRAGMENT", "COMPUTE", "RAY_GEN",
 	 "ANY_HIT", "CLOSEST_HIT", "MISS", "INTERSECTION", "CALLABLE"}};
 	 "ANY_HIT", "CLOSEST_HIT", "MISS", "INTERSECTION", "CALLABLE"}};
 
 
-static const char SHADER_HEADER[] = R"(#version 460 core
+inline constexpr char SHADER_HEADER[] = R"(#version 460 core
 #define ANKI_%s_SHADER 1
 #define ANKI_%s_SHADER 1
 #define ANKI_PLATFORM_MOBILE %d
 #define ANKI_PLATFORM_MOBILE %d
 #define ANKI_FORCE_FULL_FP_PRECISION %d
 #define ANKI_FORCE_FULL_FP_PRECISION %d

+ 1 - 1
AnKi/Ui/Font.cpp

@@ -93,7 +93,7 @@ void Font::createTexture(const void* data, U32 width, U32 height)
 	m_imFontAtlas->SetTexID(UiImageId(m_texView));
 	m_imFontAtlas->SetTexID(UiImageId(m_texView));
 
 
 	// Do the copy
 	// Do the copy
-	static const TextureSurfaceInfo surf(0, 0, 0, 0);
+	constexpr TextureSurfaceInfo surf(0, 0, 0, 0);
 	CommandBufferInitInfo cmdbInit;
 	CommandBufferInitInfo cmdbInit;
 	cmdbInit.m_flags = CommandBufferFlag::GENERAL_WORK | CommandBufferFlag::SMALL_BATCH;
 	cmdbInit.m_flags = CommandBufferFlag::GENERAL_WORK | CommandBufferFlag::SMALL_BATCH;
 	CommandBufferPtr cmdb = m_manager->getGrManager().newCommandBuffer(cmdbInit);
 	CommandBufferPtr cmdb = m_manager->getGrManager().newCommandBuffer(cmdbInit);

+ 1 - 1
AnKi/Util/FilesystemWindows.cpp

@@ -10,7 +10,7 @@
 
 
 namespace anki {
 namespace anki {
 
 
-static const U MAX_PATH_LEN = MAX_PATH - 1;
+static constexpr U MAX_PATH_LEN = MAX_PATH - 1;
 
 
 Bool fileExists(const CString& filename)
 Bool fileExists(const CString& filename)
 {
 {

+ 14 - 10
AnKi/Util/Logger.cpp

@@ -19,13 +19,14 @@
 
 
 namespace anki {
 namespace anki {
 
 
-static const Array<const char*, static_cast<U>(LoggerMessageType::COUNT)> MSG_TEXT = {"I", "V", "E", "W", "F"};
+inline constexpr Array<const char*, U(LoggerMessageType::COUNT)> MSG_TEXT = {"I", "V", "E", "W", "F"};
 
 
 Logger::Logger()
 Logger::Logger()
 {
 {
 	addMessageHandler(this, &defaultSystemMessageHandler);
 	addMessageHandler(this, &defaultSystemMessageHandler);
 
 
-	if(getenv("ANKI_LOG_VERBOSE") && getenv("ANKI_LOG_VERBOSE") == CString("1"))
+	const Char* envVar = getenv("ANKI_LOG_VERBOSE");
+	if(envVar && envVar == CString("1"))
 	{
 	{
 		m_verbosityEnabled = true;
 		m_verbosityEnabled = true;
 	}
 	}
@@ -73,7 +74,10 @@ void Logger::write(const char* file, int line, const char* func, const char* sub
 		return;
 		return;
 	}
 	}
 
 
-	LoggerMessageInfo inf = {file, line, func, type, msg, subsystem, tid};
+	const char* baseFile = strrchr(file, (ANKI_OS_WINDOWS) ? '\\' : '/');
+	baseFile = (baseFile) ? baseFile + 1 : file;
+
+	LoggerMessageInfo inf = {baseFile, line, func, type, msg, subsystem, tid};
 
 
 	m_mutex.lock();
 	m_mutex.lock();
 
 
@@ -94,11 +98,11 @@ void Logger::write(const char* file, int line, const char* func, const char* sub
 void Logger::writeFormated(const char* file, int line, const char* func, const char* subsystem, LoggerMessageType type,
 void Logger::writeFormated(const char* file, int line, const char* func, const char* subsystem, LoggerMessageType type,
 						   ThreadId tid, const char* fmt, ...)
 						   ThreadId tid, const char* fmt, ...)
 {
 {
-	char buffer[1024 * 10];
+	Array<Char, 256> buffer;
 	va_list args;
 	va_list args;
 
 
 	va_start(args, fmt);
 	va_start(args, fmt);
-	I len = vsnprintf(buffer, sizeof(buffer), fmt, args);
+	I len = vsnprintf(&buffer[0], sizeof(buffer), fmt, args);
 	if(len < 0)
 	if(len < 0)
 	{
 	{
 		fprintf(stderr, "Logger::writeFormated() failed. Will not recover");
 		fprintf(stderr, "Logger::writeFormated() failed. Will not recover");
@@ -106,7 +110,7 @@ void Logger::writeFormated(const char* file, int line, const char* func, const c
 	}
 	}
 	else if(len < I(sizeof(buffer)))
 	else if(len < I(sizeof(buffer)))
 	{
 	{
-		write(file, line, func, subsystem, type, tid, buffer);
+		write(file, line, func, subsystem, type, tid, &buffer[0]);
 		va_end(args);
 		va_end(args);
 	}
 	}
 	else
 	else
@@ -222,7 +226,7 @@ void Logger::defaultSystemMessageHandler(void*, const LoggerMessageInfo& info)
 		SetConsoleTextAttribute(consoleHandle, attribs);
 		SetConsoleTextAttribute(consoleHandle, attribs);
 
 
 		// Print
 		// Print
-		fprintf(out, "[%s][%s] %s (%s:%d %s)\n", MSG_TEXT[U(info.m_type)], info.m_subsystem ? info.m_subsystem : "N/A ",
+		fprintf(out, "[%s][%s] %s (%s:%d %s)\n", MSG_TEXT[info.m_type], info.m_subsystem ? info.m_subsystem : "N/A ",
 				info.m_msg, info.m_file, info.m_line, info.m_func);
 				info.m_msg, info.m_file, info.m_line, info.m_func);
 
 
 		// Restore state
 		// Restore state
@@ -250,7 +254,7 @@ void Logger::defaultSystemMessageHandler(void*, const LoggerMessageInfo& info)
 		ANKI_ASSERT(0);
 		ANKI_ASSERT(0);
 	}
 	}
 
 
-	__android_log_print(andMsgType, "AnKi", "[%s][%s] %s (%s:%d %s)\n", MSG_TEXT[U(info.m_type)],
+	__android_log_print(andMsgType, "AnKi", "[%s][%s] %s (%s:%d %s)\n", MSG_TEXT[info.m_type],
 						info.m_subsystem ? info.m_subsystem : "N/A ", info.m_msg, info.m_file, info.m_line,
 						info.m_subsystem ? info.m_subsystem : "N/A ", info.m_msg, info.m_file, info.m_line,
 						info.m_func);
 						info.m_func);
 #else
 #else
@@ -275,7 +279,7 @@ void Logger::defaultSystemMessageHandler(void*, const LoggerMessageInfo& info)
 		ANKI_ASSERT(0);
 		ANKI_ASSERT(0);
 	}
 	}
 
 
-	fprintf(out, "[%s][%s][%" PRIx64 "] %s (%s:%d %s)\n", MSG_TEXT[U(info.m_type)],
+	fprintf(out, "[%s][%s][%" PRIx64 "] %s (%s:%d %s)\n", MSG_TEXT[info.m_type],
 			info.m_subsystem ? info.m_subsystem : "N/A ", info.m_tid, info.m_msg, info.m_file, info.m_line,
 			info.m_subsystem ? info.m_subsystem : "N/A ", info.m_tid, info.m_msg, info.m_file, info.m_line,
 			info.m_func);
 			info.m_func);
 
 
@@ -287,7 +291,7 @@ void Logger::fileMessageHandler(void* pfile, const LoggerMessageInfo& info)
 {
 {
 	File* file = reinterpret_cast<File*>(pfile);
 	File* file = reinterpret_cast<File*>(pfile);
 
 
-	Error err = file->writeTextf("[%s] %s (%s:%d %s)\n", MSG_TEXT[U(info.m_type)], info.m_msg, info.m_file, info.m_line,
+	Error err = file->writeTextf("[%s] %s (%s:%d %s)\n", MSG_TEXT[info.m_type], info.m_msg, info.m_file, info.m_line,
 								 info.m_func);
 								 info.m_func);
 
 
 	if(!err)
 	if(!err)

+ 4 - 4
AnKi/Util/String.h

@@ -67,19 +67,19 @@ public:
 
 
 	CString() = default;
 	CString() = default;
 
 
-	CString(const Char* ptr)
+	constexpr CString(const Char* ptr)
 		: m_ptr(ptr)
 		: m_ptr(ptr)
 	{
 	{
 	}
 	}
 
 
 	/// Copy constructor.
 	/// Copy constructor.
-	CString(const CString& b)
+	constexpr CString(const CString& b)
 		: m_ptr(b.m_ptr)
 		: m_ptr(b.m_ptr)
 	{
 	{
 	}
 	}
 
 
 	/// Copy.
 	/// Copy.
-	CString& operator=(const CString& b)
+	constexpr CString& operator=(const CString& b)
 	{
 	{
 		m_ptr = b.m_ptr;
 		m_ptr = b.m_ptr;
 		return *this;
 		return *this;
@@ -286,7 +286,7 @@ public:
 	using ConstIterator = const Char*;
 	using ConstIterator = const Char*;
 	using Allocator = GenericMemoryPoolAllocator<Char>;
 	using Allocator = GenericMemoryPoolAllocator<Char>;
 
 
-	static const PtrSize NPOS = MAX_PTR_SIZE;
+	static constexpr PtrSize NPOS = MAX_PTR_SIZE;
 
 
 	/// Default constructor.
 	/// Default constructor.
 	String()
 	String()

+ 1 - 1
AnKi/Util/ThreadHive.h

@@ -77,7 +77,7 @@ public:
 class ThreadHive
 class ThreadHive
 {
 {
 public:
 public:
-	static const U32 MAX_THREADS = 32;
+	static constexpr U32 MAX_THREADS = 32;
 
 
 	/// Create the hive.
 	/// Create the hive.
 	ThreadHive(U32 threadCount, GenericMemoryPoolAllocator<U8> alloc, Bool pinToCores = false);
 	ThreadHive(U32 threadCount, GenericMemoryPoolAllocator<U8> alloc, Bool pinToCores = false);