Browse Source

Finalize the code

Panagiotis Christopoulos Charitos 3 years ago
parent
commit
bf1cbb0968

+ 87 - 69
AnKi/Resource/MaterialResource.cpp

@@ -207,7 +207,93 @@ Error MaterialResource::createVars(Program& prog)
 		prog.m_localUniformsStructIdx = MAX_U32;
 	}
 
-	// Iterate all variants of builtin mutators to gather the vars
+	// Iterate all members of the local uniforms struct to add its members
+	U32 offsetof = 0;
+	for(U32 i = 0; localUniformsStruct && i < localUniformsStruct->m_members.getSize(); ++i)
+	{
+		const ShaderProgramBinaryStructMember& member = localUniformsStruct->m_members[i];
+		const CString memberName = member.m_name.getBegin();
+
+		// Check if it needs to be added
+		Bool addIt = false;
+		if(member.m_dependentMutator == MAX_U32)
+		{
+			addIt = true;
+		}
+		else
+		{
+			Bool found = false;
+			for(const PartialMutation& m : prog.m_partialMutation)
+			{
+				if(m.m_mutator->m_name == binary.m_mutators[member.m_dependentMutator].m_name.getBegin())
+				{
+					if(m.m_value == member.m_dependentMutatorValue)
+					{
+						addIt = true;
+					}
+					found = true;
+					break;
+				}
+			}
+
+			if(!found)
+			{
+				ANKI_RESOURCE_LOGE("Incorrect combination of member variable %s and dependent mutator %s",
+								   memberName.cstr(), binary.m_mutators[member.m_dependentMutator].m_name.getBegin());
+				return Error::USER_DATA;
+			}
+		}
+
+		if(addIt)
+		{
+			MaterialVariable* var = tryFindVariable(memberName);
+			if(var)
+			{
+				if(var->m_dataType != member.m_type || var->m_offsetInLocalUniforms != offsetof)
+				{
+					ANKI_RESOURCE_LOGE("Member variable doesn't match between techniques: %s", memberName.cstr());
+					return Error::USER_DATA;
+				}
+			}
+			else
+			{
+				// Check that there are no other vars that overlap with the current var. This could happen if
+				// different programs have different signature for AnKiLocalUniforms
+				for(const MaterialVariable& otherVar : m_vars)
+				{
+					if(otherVar.isTexture())
+					{
+						continue;
+					}
+
+					const U32 aVarOffset = otherVar.m_offsetInLocalUniforms;
+					const U32 aVarEnd = aVarOffset + getShaderVariableDataTypeInfo(otherVar.m_dataType).m_size;
+					const U32 bVarOffset = offsetof;
+					const U32 bVarEnd = bVarOffset + getShaderVariableDataTypeInfo(member.m_type).m_size;
+
+					if((aVarOffset <= bVarOffset && aVarEnd > bVarOffset)
+					   || (bVarOffset <= aVarOffset && bVarEnd > aVarOffset))
+					{
+						ANKI_RESOURCE_LOGE("Member %s in AnKiLocalUniforms overlaps with %s. Check your shaders",
+										   memberName.cstr(), otherVar.m_name.cstr());
+						return Error::USER_DATA;
+					}
+				}
+
+				// All good, add it
+				var = m_vars.emplaceBack(getAllocator());
+				var->m_name.create(getAllocator(), memberName);
+				var->m_offsetInLocalUniforms = offsetof;
+				var->m_dataType = member.m_type;
+
+				offsetof += getShaderVariableDataTypeInfo(member.m_type).m_size;
+			}
+		}
+	}
+
+	m_localUniformsSize = max(offsetof, m_localUniformsSize);
+
+	// Iterate all variants of builtin mutators to gather the opaques
 	ShaderProgramResourceVariantInitInfo initInfo(prog.m_prog);
 
 	for(const PartialMutation& m : prog.m_partialMutation)
@@ -242,74 +328,6 @@ Error MaterialResource::createVars(Program& prog)
 	{
 		const ShaderProgramResourceVariant* variant;
 		prog.m_prog->getOrCreateVariant(initInfo, variant);
-		for(const ShaderProgramBinaryStructInstance& instance : variant->getBinaryVariant().m_structs)
-		{
-			if(prog.m_localUniformsStructIdx != instance.m_index)
-			{
-				continue;
-			}
-
-			// Update the size
-			m_localUniformsSize = max(instance.m_size, m_localUniformsSize);
-
-			// Update the variables
-			for(const ShaderProgramBinaryStructMemberInstance& mInstance : instance.m_memberInstances)
-			{
-				const ShaderProgramBinaryStructMember& member =
-					binary.m_structs[instance.m_index].m_members[mInstance.m_index];
-
-				const CString memberName = member.m_name.getBegin();
-
-				if(member.m_type == ShaderVariableDataType::NONE)
-				{
-					ANKI_RESOURCE_LOGE("Non fundamental type was found in AnKiLocalUniforms: %s", memberName.cstr());
-					return Error::USER_DATA;
-				}
-
-				MaterialVariable* var = tryFindVariable(memberName);
-				if(var)
-				{
-					if(var->m_dataType != member.m_type || var->m_offsetInLocalUniforms != mInstance.m_offset)
-					{
-						ANKI_RESOURCE_LOGE("Member variable doesn't match between techniques: %s", memberName.cstr());
-						return Error::USER_DATA;
-					}
-				}
-				else
-				{
-					// Check that there are no other vars that overlap with the current var. This could happen if
-					// different programs have different signature for AnKiLocalUniforms
-					for(const MaterialVariable& otherVar : m_vars)
-					{
-						if(otherVar.isTexture())
-						{
-							continue;
-						}
-
-						const U32 aVarOffset = otherVar.m_offsetInLocalUniforms;
-						const U32 aVarEnd = aVarOffset + getShaderVariableDataTypeInfo(otherVar.m_dataType).m_size;
-						const U32 bVarOffset = mInstance.m_offset;
-						const U32 bVarEnd = bVarOffset + getShaderVariableDataTypeInfo(member.m_type).m_size;
-
-						if((aVarOffset <= bVarOffset && aVarEnd > bVarOffset)
-						   || (bVarOffset <= aVarOffset && bVarEnd > aVarOffset))
-						{
-							ANKI_RESOURCE_LOGE("Member %s in AnKiLocalUniforms overlaps with %s. Check your shaders",
-											   memberName.cstr(), otherVar.m_name.cstr());
-							return Error::USER_DATA;
-						}
-					}
-
-					// All good, add it
-					var = m_vars.emplaceBack(getAllocator());
-					var->m_name.create(getAllocator(), memberName);
-					var->m_offsetInLocalUniforms = mInstance.m_offset;
-					var->m_dataType = member.m_type;
-				}
-			}
-
-			break;
-		}
 
 		// Add opaque vars
 		for(const ShaderProgramBinaryOpaqueInstance& instance : variant->getBinaryVariant().m_opaques)

+ 10 - 0
AnKi/ShaderCompiler/ShaderProgramBinary.h

@@ -259,12 +259,22 @@ public:
 	/// If the type is another struct then this points to ShaderProgramBinary::m_structs.
 	U32 m_structIndex = MAX_U32;
 
+	/// It points to a ShaderProgramBinary::m_mutators. This mutator will turn on or off this member.
+	U32 m_dependentMutator = MAX_U32;
+
+	/// The value of the m_dependentMutator.
+	MutatorValue m_dependentMutatorValue = 0;
+
 	template<typename TSerializer, typename TClass>
 	static void serializeCommon(TSerializer& s, TClass self)
 	{
 		s.doArray("m_name", offsetof(ShaderProgramBinaryStructMember, m_name), &self.m_name[0], self.m_name.getSize());
 		s.doValue("m_type", offsetof(ShaderProgramBinaryStructMember, m_type), self.m_type);
 		s.doValue("m_structIndex", offsetof(ShaderProgramBinaryStructMember, m_structIndex), self.m_structIndex);
+		s.doValue("m_dependentMutator", offsetof(ShaderProgramBinaryStructMember, m_dependentMutator),
+				  self.m_dependentMutator);
+		s.doValue("m_dependentMutatorValue", offsetof(ShaderProgramBinaryStructMember, m_dependentMutatorValue),
+				  self.m_dependentMutatorValue);
 	}
 
 	template<typename TDeserializer>

+ 2 - 0
AnKi/ShaderCompiler/ShaderProgramBinary.xml

@@ -72,6 +72,8 @@
 				<member name="m_name" type="char" array_size="MAX_SHADER_BINARY_NAME_LENGTH + 1" constructor="= {}" />
 				<member name="m_type" type="ShaderVariableDataType" constructor="= ShaderVariableDataType::NONE" comment="If the value is ShaderVariableDataType::NONE then it's a struct" />
 				<member name="m_structIndex" type="U32" constructor="= MAX_U32" comment="If the type is another struct then this points to ShaderProgramBinary::m_structs" />
+				<member name="m_dependentMutator" type="U32" constructor="= MAX_U32" comment="It points to a ShaderProgramBinary::m_mutators. This mutator will turn on or off this member" />
+				<member name="m_dependentMutatorValue" type="MutatorValue" constructor="= 0" comment="The value of the m_dependentMutator" />
 			</members>
 		</class>
 

+ 2 - 68
AnKi/ShaderCompiler/ShaderProgramCompiler.cpp

@@ -838,6 +838,8 @@ static Error doGhostStructReflection(const StringList& symbolsToReflect,
 
 			ANKI_CHECK(Refl::setName(inMember.m_name, outMember.m_name));
 			outMember.m_type = inMember.m_type;
+			outMember.m_dependentMutator = inMember.m_dependentMutator;
+			outMember.m_dependentMutatorValue = inMember.m_mutatorValue;
 		}
 
 		members.moveAndReset(out.m_members);
@@ -846,74 +848,6 @@ static Error doGhostStructReflection(const StringList& symbolsToReflect,
 	binaryAlloc.deleteArray(binary.m_structs);
 	structs.moveAndReset(binary.m_structs);
 
-	// For all mutations update the instances
-	DynamicArrayAuto<Bool> variantVisited(tmpAlloc, binary.m_variants.getSize(), false);
-	for(U32 mutationIdx = 0; mutationIdx < binary.m_mutations.getSize(); ++mutationIdx)
-	{
-		const ShaderProgramBinaryMutation& mutation = binary.m_mutations[mutationIdx];
-		if(variantVisited[mutation.m_variantIndex])
-		{
-			continue;
-		}
-		variantVisited[mutation.m_variantIndex] = true;
-
-		ShaderProgramBinaryVariant& variant = binary.m_variants[mutation.m_variantIndex];
-
-		DynamicArrayAuto<ShaderProgramBinaryStructInstance> structInstances(binaryAlloc);
-
-		// Copy the existing struct instances
-		for(U32 i = 0; i < variant.m_structs.getSize(); ++i)
-		{
-			structInstances.emplaceBack(variant.m_structs[i]);
-		}
-
-		// For each ghost struct add member intances
-		for(U32 i = 0; i < ghostStructIndices.getSize(); ++i)
-		{
-			const ShaderProgramParserGhostStruct& inStruct = ghostStructs[ghostStructIndices[i]];
-
-			// Find which members are active in this mutation
-			BitSet<128, U64> activeMembers(false);
-			ANKI_ASSERT(inStruct.m_members.getSize() <= 128);
-			for(U32 j = 0; j < inStruct.m_members.getSize(); ++j)
-			{
-				activeMembers.set(j, ghostMemberActive(inStruct.m_members[j], mutation));
-			}
-
-			if(activeMembers.getEnabledBitCount() == 0)
-			{
-				continue;
-			}
-
-			// Add the active members
-			U32 offsetof = 0;
-			DynamicArrayAuto<ShaderProgramBinaryStructMemberInstance> memberInstances(binaryAlloc);
-			for(U32 j = 0; j < inStruct.m_members.getSize(); ++j)
-			{
-				if(!activeMembers.get(j))
-				{
-					continue;
-				}
-
-				ShaderProgramBinaryStructMemberInstance& outMember = *memberInstances.emplaceBack();
-				outMember.m_arraySize = 1;
-				outMember.m_index = j;
-				outMember.m_offset = offsetof;
-
-				offsetof += getShaderVariableDataTypeInfo(inStruct.m_members[j].m_type).m_size;
-			}
-
-			ShaderProgramBinaryStructInstance& outStructInstance = *structInstances.emplaceBack();
-			outStructInstance.m_index = nonGhostStructCount + i;
-			outStructInstance.m_size = offsetof;
-			memberInstances.moveAndReset(outStructInstance.m_memberInstances);
-		}
-
-		// Replace data
-		binaryAlloc.deleteArray(variant.m_structs);
-		structInstances.moveAndReset(variant.m_structs);
-	}
-
 	return Error::NONE;
 }
 

+ 2 - 2
AnKi/ShaderCompiler/ShaderProgramCompiler.h

@@ -14,8 +14,8 @@ namespace anki {
 /// @addtogroup shader_compiler
 /// @{
 
-constexpr const char* SHADER_BINARY_MAGIC = "ANKISDR7"; ///< WARNING: If changed change SHADER_BINARY_VERSION
-constexpr U32 SHADER_BINARY_VERSION = 7;
+constexpr const char* SHADER_BINARY_MAGIC = "ANKISDR8"; ///< WARNING: If changed change SHADER_BINARY_VERSION
+constexpr U32 SHADER_BINARY_VERSION = 8;
 
 /// A wrapper over the POD ShaderProgramBinary class.
 /// @memberof ShaderProgramCompiler

+ 6 - 1
AnKi/ShaderCompiler/ShaderProgramDump.cpp

@@ -153,7 +153,12 @@ void dumpShaderProgramBinary(const ShaderProgramBinary& binary, StringAuto& huma
 				const CString typeStr = (member.m_type == ShaderVariableDataType::NONE)
 											? &binary.m_structs[member.m_structIndex].m_name[0]
 											: getShaderVariableDataTypeInfo(member.m_type).m_name;
-				lines.pushBackSprintf(ANKI_TAB ANKI_TAB "%-32s type %24s\n", member.m_name.getBegin(), typeStr.cstr());
+				const CString dependentMutator = (member.m_dependentMutator != MAX_U32)
+													 ? binary.m_mutators[member.m_dependentMutator].m_name.getBegin()
+													 : "None";
+				lines.pushBackSprintf(
+					ANKI_TAB ANKI_TAB "%-32s type %24s dependentMutator %-32s dependentMutatorValue %4d\n",
+					member.m_name.getBegin(), typeStr.cstr(), dependentMutator.cstr(), member.m_dependentMutatorValue);
 			}
 		}
 	}

+ 4 - 4
Samples/Sponza/Assets/Fire.ankimtl

@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <material shadow="0">
-	<techniques>
-		<technique name="Forward" shaderProgram="Anki/Shaders/ForwardShadingParticles.ankiprog">
+	<shaderPrograms>
+		<shaderProgram filename="Anki/Shaders/ForwardShadingParticles.ankiprog">
 			<mutation>
 				<mutator name="ANIMATED_TEXTURE" value="0"/>
 				<mutator name="LIGHT" value="0"/>
 			</mutation>
-		</technique>
-	</techniques>
+		</shaderProgram>
+	</shaderPrograms>
 
 	<inputs>
 		<input name="u_diffuseMap" value="Assets/ember_mid.ankitex"/>

+ 4 - 4
Samples/Sponza/Assets/Smoke.ankimtl

@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <material shadow="0">
-	<techniques>
-		<technique name="Forward" shaderProgram="Anki/Shaders/ForwardShadingParticles.ankiprog">
+	<shaderPrograms>
+		<shaderProgram filename="Anki/Shaders/ForwardShadingParticles.ankiprog">
 			<mutation>
 				<mutator name="ANIMATED_TEXTURE" value="0"/>
 				<mutator name="LIGHT" value="1"/>
 			</mutation>
-		</technique>
-	</techniques>
+		</shaderProgram>
+	</shaderPrograms>
 
 	<inputs>
 		<input name="u_diffuseMap" value="Assets/Smoke.ankitex"/>

+ 4 - 4
Tools/Shader/ShaderProgramCompilerMain.cpp

@@ -7,7 +7,7 @@
 #include <AnKi/Util.h>
 using namespace anki;
 
-static const char* USAGE = R"(Usage: %s input_shader_program_file [options]
+static const char* USAGE = R"(Usage: %s [options] input_shader_program_file
 Options:
 -o <name of output>  : The name of the output binary
 -j <thread count>    : Number of threads. Defaults to system's max
@@ -36,9 +36,7 @@ static Error parseCommandLineArgs(int argc, char** argv, CmdLineArgs& info)
 		return Error::USER_DATA;
 	}
 
-	info.m_inputFname.create(argv[1]);
-
-	for(I i = 2; i < argc; i++)
+	for(I i = 1; i < argc - 1; i++)
 	{
 		if(strcmp(argv[i], "-o") == 0)
 		{
@@ -107,6 +105,8 @@ static Error parseCommandLineArgs(int argc, char** argv, CmdLineArgs& info)
 		}
 	}
 
+	info.m_inputFname.create(argv[argc - 1]);
+
 	return Error::NONE;
 }