Browse Source

Add the skeleton of the new shader program resource

Panagiotis Christopoulos Charitos 5 years ago
parent
commit
71b82afd82

+ 1 - 0
src/anki/Resource.h

@@ -18,6 +18,7 @@
 #include <anki/resource/DummyResource.h>
 #include <anki/resource/DummyResource.h>
 #include <anki/resource/ModelResource.h>
 #include <anki/resource/ModelResource.h>
 #include <anki/resource/ShaderProgramResource.h>
 #include <anki/resource/ShaderProgramResource.h>
+#include <anki/resource/ShaderProgramResource2.h>
 #include <anki/resource/CollisionResource.h>
 #include <anki/resource/CollisionResource.h>
 
 
 #include <anki/resource/MeshLoader.h>
 #include <anki/resource/MeshLoader.h>

+ 3 - 1
src/anki/resource/InstantiationMacros.h

@@ -29,4 +29,6 @@ ANKI_INSTANTIATE_RESOURCE(GenericResource, GenericResourcePtr)
 ANKI_INSTANSIATE_RESOURCE_DELIMITER()
 ANKI_INSTANSIATE_RESOURCE_DELIMITER()
 ANKI_INSTANTIATE_RESOURCE(TextureAtlasResource, TextureAtlasResourcePtr)
 ANKI_INSTANTIATE_RESOURCE(TextureAtlasResource, TextureAtlasResourcePtr)
 ANKI_INSTANSIATE_RESOURCE_DELIMITER()
 ANKI_INSTANSIATE_RESOURCE_DELIMITER()
-ANKI_INSTANTIATE_RESOURCE(ShaderProgramResource, ShaderProgramResourcePtr)
+ANKI_INSTANTIATE_RESOURCE(ShaderProgramResource, ShaderProgramResourcePtr)
+ANKI_INSTANSIATE_RESOURCE_DELIMITER()
+ANKI_INSTANTIATE_RESOURCE(ShaderProgramResource2, ShaderProgramResource2Ptr)

+ 1 - 0
src/anki/resource/ResourceManager.cpp

@@ -20,6 +20,7 @@
 #include <anki/resource/GenericResource.h>
 #include <anki/resource/GenericResource.h>
 #include <anki/resource/TextureAtlasResource.h>
 #include <anki/resource/TextureAtlasResource.h>
 #include <anki/resource/ShaderProgramResource.h>
 #include <anki/resource/ShaderProgramResource.h>
+#include <anki/resource/ShaderProgramResource2.h>
 #include <anki/resource/CollisionResource.h>
 #include <anki/resource/CollisionResource.h>
 
 
 namespace anki
 namespace anki

+ 25 - 0
src/anki/resource/ShaderProgramResource2.cpp

@@ -0,0 +1,25 @@
+// Copyright (C) 2009-2020, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <anki/resource/ShaderProgramResource2.h>
+
+namespace anki
+{
+
+ShaderProgramResource2::ShaderProgramResource2(ResourceManager* manager)
+	: ResourceObject(manager)
+{
+}
+
+ShaderProgramResource2::~ShaderProgramResource2()
+{
+}
+
+Error ShaderProgramResource2::load(const ResourceFilename& filename, Bool async)
+{
+	return Error::NONE;
+}
+
+} // end namespace anki

+ 250 - 0
src/anki/resource/ShaderProgramResource2.h

@@ -0,0 +1,250 @@
+// Copyright (C) 2009-2020, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <anki/resource/ResourceObject.h>
+#include <anki/shader_compiler/Common.h>
+#include <anki/gr/utils/Functions.h>
+#include <anki/util/BitSet.h>
+#include <anki/util/String.h>
+#include <anki/util/HashMap.h>
+#include <anki/util/WeakArray.h>
+#include <anki/Math.h>
+
+namespace anki
+{
+
+/// @addtogroup resource
+/// @{
+
+/// The means to mutate a shader program.
+/// @memberof ShaderProgramResource2
+class ShaderProgramResourceMutator2 : public NonCopyable
+{
+public:
+	String m_name;
+	DynamicArray<MutatorValue> m_values;
+};
+
+/// @memberof ShaderProgramResource2
+class ShaderProgramResourcePartialMutation2 : public NonCopyable
+{
+public:
+	const ShaderProgramResourceMutator2* m_mutator = nullptr;
+	MutatorValue m_value = 0;
+	U64 m_hash = 0;
+};
+
+/// Shader program resource variant.
+class ShaderProgramResourceInputVariable2
+{
+public:
+	String m_name;
+	Bool m_constant = false;
+	ShaderVariableDataType m_dataType = ShaderVariableDataType::NONE;
+
+	Bool isTexture() const
+	{
+		return m_dataType >= ShaderVariableDataType::TEXTURE_FIRST
+			   && m_dataType <= ShaderVariableDataType::TEXTURE_LAST;
+	}
+
+	Bool isSampler() const
+	{
+		return m_dataType == ShaderVariableDataType::SAMPLER;
+	}
+
+	Bool inBlock() const
+	{
+		return !m_constant && !isTexture() && !isSampler();
+	}
+};
+
+/// Shader program resource variant.
+class ShaderProgramResourceVariant2
+{
+public:
+	// TODO
+};
+
+/// The value of a constant.
+class ShaderProgramResourceConstantValue2
+{
+public:
+	union
+	{
+		I32 m_int;
+		IVec2 m_ivec2;
+		IVec3 m_ivec3;
+		IVec4 m_ivec4;
+
+		U32 m_uint;
+		UVec2 m_uvec2;
+		UVec3 m_uvec3;
+		UVec4 m_uvec4;
+
+		F32 m_float;
+		Vec2 m_vec2;
+		Vec3 m_vec3;
+		Vec4 m_vec4;
+	};
+
+	U32 m_inputVariableIndex;
+	U8 _m_padding[sizeof(Vec4) - sizeof(m_inputVariableIndex)];
+
+	ShaderProgramResourceConstantValue2()
+	{
+		zeroMemory(*this);
+	}
+};
+
+static_assert(sizeof(ShaderProgramResourceConstantValue2) == sizeof(Vec4) * 2, "Need it to be packed");
+
+/// Shader program resource. It loads special AnKi programs.
+class ShaderProgramResource2 : public ResourceObject
+{
+public:
+	ShaderProgramResource2(ResourceManager* manager);
+
+	~ShaderProgramResource2();
+
+	/// Load the resource.
+	ANKI_USE_RESULT Error load(const ResourceFilename& filename, Bool async);
+
+	/// Get the array of input variables.
+	const DynamicArray<ShaderProgramResourceInputVariable2>& getInputVariables() const
+	{
+		return m_inputVars;
+	}
+
+	/// Try to find an input variable.
+	const ShaderProgramResourceInputVariable2* tryFindInputVariable(CString name) const
+	{
+		for(const ShaderProgramResourceInputVariable2& m : m_inputVars)
+		{
+			if(m.m_name == name)
+			{
+				return &m;
+			}
+		}
+		return nullptr;
+	}
+
+	/// Get the array of mutators.
+	const DynamicArray<ShaderProgramResourceMutator2>& getMutators() const
+	{
+		return m_mutators;
+	}
+
+	/// Try to find a mutator.
+	const ShaderProgramResourceMutator2* tryFindMutator(CString name) const
+	{
+		for(const ShaderProgramResourceMutator2& m : m_mutators)
+		{
+			if(m.m_name == name)
+			{
+				return &m;
+			}
+		}
+		return nullptr;
+	}
+
+	/// Has tessellation shaders.
+	Bool hasTessellation() const
+	{
+		return !!(m_shaderStages & ShaderTypeBit::TESSELLATION_EVALUATION);
+	}
+
+private:
+	using Mutator = ShaderProgramResourceMutator2;
+	using Input = ShaderProgramResourceInputVariable2;
+
+	DynamicArray<Input> m_inputVars;
+	DynamicArray<Mutator> m_mutators;
+
+	mutable HashMap<U64, ShaderProgramResourceVariant2*> m_variants;
+	mutable Mutex m_mtx;
+
+	ShaderTypeBit m_shaderStages = ShaderTypeBit::NONE;
+};
+
+/// Smart initializer of multiple ShaderProgramResourceConstantValue.
+class ShaderProgramResourceConstantValueInitList2
+{
+public:
+	ShaderProgramResourceConstantValueInitList2(ShaderProgramResource2Ptr ptr)
+		: m_ptr(ptr)
+	{
+	}
+
+	~ShaderProgramResourceConstantValueInitList2()
+	{
+	}
+
+	template<typename T>
+	ShaderProgramResourceConstantValueInitList2& add(CString name, const T& t)
+	{
+		const ShaderProgramResourceInputVariable2* in = m_ptr->tryFindInputVariable(name);
+		ANKI_ASSERT(in);
+		ANKI_ASSERT(in->m_constant);
+		ANKI_ASSERT(in->m_dataType == getShaderVariableTypeFromTypename<T>());
+		m_constantValues[m_count].m_inputVariableIndex = U32(in - m_ptr->getInputVariables().getBegin());
+		memcpy(&m_constantValues[m_count].m_int, &t, sizeof(T));
+		++m_count;
+		return *this;
+	}
+
+	ConstWeakArray<ShaderProgramResourceConstantValue2> get() const
+	{
+		// TODO check if all are set
+		return ConstWeakArray<ShaderProgramResourceConstantValue2>(&m_constantValues[0], m_count);
+	}
+
+	ShaderProgramResourceConstantValue2& operator[](U32 idx)
+	{
+		return m_constantValues[idx];
+	}
+
+private:
+	ShaderProgramResource2Ptr m_ptr;
+	U32 m_count = 0;
+	Array<ShaderProgramResourceConstantValue2, 64> m_constantValues;
+};
+
+/// Smart initializer of multiple ShaderProgramResourceMutation2.
+class ShaderProgramResourceMutationInitList2
+{
+public:
+	ShaderProgramResourceMutationInitList2(ShaderProgramResource2Ptr ptr)
+		: m_ptr(ptr)
+	{
+	}
+
+	~ShaderProgramResourceMutationInitList2()
+	{
+	}
+
+	ShaderProgramResourceMutationInitList2& add(CString name, MutatorValue t)
+	{
+		const ShaderProgramResourceMutator2* m = m_ptr->tryFindMutator(name);
+		ANKI_ASSERT(m);
+		m_mutation[m_count] = t;
+		m_setMutators.set(m - m_ptr->getMutators().getBegin());
+		++m_count;
+		return *this;
+	}
+
+private:
+	static constexpr U32 MAX_MUTATORS = 64;
+
+	ShaderProgramResource2Ptr m_ptr;
+	U32 m_count = 0;
+	Array<MutatorValue, MAX_MUTATORS> m_mutation;
+	BitSet<MAX_MUTATORS> m_setMutators = {false};
+};
+/// @}
+
+} // end namespace anki

+ 7 - 16
src/anki/shader_compiler/ShaderProgramBinary.h

@@ -26,10 +26,7 @@ public:
 	template<typename TSerializer, typename TClass>
 	template<typename TSerializer, typename TClass>
 	static void serializeCommon(TSerializer& s, TClass self)
 	static void serializeCommon(TSerializer& s, TClass self)
 	{
 	{
-		s.doArray("m_name",
-			offsetof(ShaderProgramBinaryVariable, m_name),
-			&self.m_name[0],
-			MAX_SHADER_BINARY_NAME_LENGTH + 1);
+		s.doArray("m_name", offsetof(ShaderProgramBinaryVariable, m_name), &self.m_name[0], self.m_name.getSize());
 		s.doValue("m_blockInfo", offsetof(ShaderProgramBinaryVariable, m_blockInfo), self.m_blockInfo);
 		s.doValue("m_blockInfo", offsetof(ShaderProgramBinaryVariable, m_blockInfo), self.m_blockInfo);
 		s.doValue("m_type", offsetof(ShaderProgramBinaryVariable, m_type), self.m_type);
 		s.doValue("m_type", offsetof(ShaderProgramBinaryVariable, m_type), self.m_type);
 		s.doValue("m_active", offsetof(ShaderProgramBinaryVariable, m_active), self.m_active);
 		s.doValue("m_active", offsetof(ShaderProgramBinaryVariable, m_active), self.m_active);
@@ -61,8 +58,7 @@ public:
 	template<typename TSerializer, typename TClass>
 	template<typename TSerializer, typename TClass>
 	static void serializeCommon(TSerializer& s, TClass self)
 	static void serializeCommon(TSerializer& s, TClass self)
 	{
 	{
-		s.doArray(
-			"m_name", offsetof(ShaderProgramBinaryBlock, m_name), &self.m_name[0], MAX_SHADER_BINARY_NAME_LENGTH + 1);
+		s.doArray("m_name", offsetof(ShaderProgramBinaryBlock, m_name), &self.m_name[0], self.m_name.getSize());
 		s.doValue("m_variables", offsetof(ShaderProgramBinaryBlock, m_variables), self.m_variables);
 		s.doValue("m_variables", offsetof(ShaderProgramBinaryBlock, m_variables), self.m_variables);
 		s.doValue("m_binding", offsetof(ShaderProgramBinaryBlock, m_binding), self.m_binding);
 		s.doValue("m_binding", offsetof(ShaderProgramBinaryBlock, m_binding), self.m_binding);
 		s.doValue("m_set", offsetof(ShaderProgramBinaryBlock, m_set), self.m_set);
 		s.doValue("m_set", offsetof(ShaderProgramBinaryBlock, m_set), self.m_set);
@@ -95,8 +91,7 @@ public:
 	template<typename TSerializer, typename TClass>
 	template<typename TSerializer, typename TClass>
 	static void serializeCommon(TSerializer& s, TClass self)
 	static void serializeCommon(TSerializer& s, TClass self)
 	{
 	{
-		s.doArray(
-			"m_name", offsetof(ShaderProgramBinaryOpaque, m_name), &self.m_name[0], MAX_SHADER_BINARY_NAME_LENGTH + 1);
+		s.doArray("m_name", offsetof(ShaderProgramBinaryOpaque, m_name), &self.m_name[0], self.m_name.getSize());
 		s.doValue("m_type", offsetof(ShaderProgramBinaryOpaque, m_type), self.m_type);
 		s.doValue("m_type", offsetof(ShaderProgramBinaryOpaque, m_type), self.m_type);
 		s.doValue("m_binding", offsetof(ShaderProgramBinaryOpaque, m_binding), self.m_binding);
 		s.doValue("m_binding", offsetof(ShaderProgramBinaryOpaque, m_binding), self.m_binding);
 		s.doValue("m_set", offsetof(ShaderProgramBinaryOpaque, m_set), self.m_set);
 		s.doValue("m_set", offsetof(ShaderProgramBinaryOpaque, m_set), self.m_set);
@@ -128,10 +123,7 @@ public:
 	template<typename TSerializer, typename TClass>
 	template<typename TSerializer, typename TClass>
 	static void serializeCommon(TSerializer& s, TClass self)
 	static void serializeCommon(TSerializer& s, TClass self)
 	{
 	{
-		s.doArray("m_name",
-			offsetof(ShaderProgramBinaryConstant, m_name),
-			&self.m_name[0],
-			MAX_SHADER_BINARY_NAME_LENGTH + 1);
+		s.doArray("m_name", offsetof(ShaderProgramBinaryConstant, m_name), &self.m_name[0], self.m_name.getSize());
 		s.doValue("m_type", offsetof(ShaderProgramBinaryConstant, m_type), self.m_type);
 		s.doValue("m_type", offsetof(ShaderProgramBinaryConstant, m_type), self.m_type);
 		s.doValue("m_constantId", offsetof(ShaderProgramBinaryConstant, m_constantId), self.m_constantId);
 		s.doValue("m_constantId", offsetof(ShaderProgramBinaryConstant, m_constantId), self.m_constantId);
 		s.doValue("m_shaderStages", offsetof(ShaderProgramBinaryConstant, m_shaderStages), self.m_shaderStages);
 		s.doValue("m_shaderStages", offsetof(ShaderProgramBinaryConstant, m_shaderStages), self.m_shaderStages);
@@ -201,7 +193,7 @@ public:
 		s.doArray("m_codeBlockIndices",
 		s.doArray("m_codeBlockIndices",
 			offsetof(ShaderProgramBinaryVariant, m_codeBlockIndices),
 			offsetof(ShaderProgramBinaryVariant, m_codeBlockIndices),
 			&self.m_codeBlockIndices[0],
 			&self.m_codeBlockIndices[0],
-			U32(ShaderType::COUNT));
+			self.m_codeBlockIndices.getSize());
 	}
 	}
 
 
 	template<typename TDeserializer>
 	template<typename TDeserializer>
@@ -227,8 +219,7 @@ public:
 	template<typename TSerializer, typename TClass>
 	template<typename TSerializer, typename TClass>
 	static void serializeCommon(TSerializer& s, TClass self)
 	static void serializeCommon(TSerializer& s, TClass self)
 	{
 	{
-		s.doArray(
-			"m_name", offsetof(ShaderProgramBinaryMutator, m_name), &self.m_name[0], MAX_SHADER_BINARY_NAME_LENGTH + 1);
+		s.doArray("m_name", offsetof(ShaderProgramBinaryMutator, m_name), &self.m_name[0], self.m_name.getSize());
 		s.doValue("m_values", offsetof(ShaderProgramBinaryMutator, m_values), self.m_values);
 		s.doValue("m_values", offsetof(ShaderProgramBinaryMutator, m_values), self.m_values);
 	}
 	}
 
 
@@ -313,7 +304,7 @@ public:
 	template<typename TSerializer, typename TClass>
 	template<typename TSerializer, typename TClass>
 	static void serializeCommon(TSerializer& s, TClass self)
 	static void serializeCommon(TSerializer& s, TClass self)
 	{
 	{
-		s.doArray("m_magic", offsetof(ShaderProgramBinary, m_magic), &self.m_magic[0], 8);
+		s.doArray("m_magic", offsetof(ShaderProgramBinary, m_magic), &self.m_magic[0], self.m_magic.getSize());
 		s.doValue("m_mutators", offsetof(ShaderProgramBinary, m_mutators), self.m_mutators);
 		s.doValue("m_mutators", offsetof(ShaderProgramBinary, m_mutators), self.m_mutators);
 		s.doValue("m_codeBlocks", offsetof(ShaderProgramBinary, m_codeBlocks), self.m_codeBlocks);
 		s.doValue("m_codeBlocks", offsetof(ShaderProgramBinary, m_codeBlocks), self.m_codeBlocks);
 		s.doValue("m_variants", offsetof(ShaderProgramBinary, m_variants), self.m_variants);
 		s.doValue("m_variants", offsetof(ShaderProgramBinary, m_variants), self.m_variants);

+ 2 - 2
src/anki/util/serializer.py

@@ -163,8 +163,8 @@ def gen_class(root_el):
             writeln("s.doDynamicArray(\"%s\", offsetof(%s, %s), self.%s, self.%s);" % (member.name, name, member.name,
             writeln("s.doDynamicArray(\"%s\", offsetof(%s, %s), self.%s, self.%s);" % (member.name, name, member.name,
                                                                                        member.name, member.array_size))
                                                                                        member.name, member.array_size))
         elif member.array_size != "1":
         elif member.array_size != "1":
-            writeln("s.doArray(\"%s\", offsetof(%s, %s), &self.%s[0], %s);" % (member.name, name, member.name,
-                                                                               member.name, member.array_size))
+            writeln("s.doArray(\"%s\", offsetof(%s, %s), &self.%s[0], self.%s.getSize());" %
+                    (member.name, name, member.name, member.name, member.name))
         else:
         else:
             writeln("s.doValue(\"%s\", offsetof(%s, %s), self.%s);" % (member.name, name, member.name, member.name))
             writeln("s.doValue(\"%s\", offsetof(%s, %s), self.%s);" % (member.name, name, member.name, member.name))