Quellcode durchsuchen

Some work on the shader program resource

Panagiotis Christopoulos Charitos vor 5 Jahren
Ursprung
Commit
cedd0f2cd0

+ 167 - 1
src/anki/resource/ShaderProgramResource2.cpp

@@ -53,7 +53,173 @@ Error ShaderProgramResource2::load(const ResourceFilename& filename, Bool async)
 		}
 	}
 
-	// TODO create the inputs
+	// Create the inputs
+	for(const ShaderProgramBinaryBlock& block : binary.m_uniformBlocks)
+	{
+		if(block.m_name.getBegin() != CString("b_ankiMaterial"))
+		{
+			continue;
+		}
+
+		for(const ShaderProgramBinaryVariable& var : block.m_variables)
+		{
+			Bool instanced;
+			U32 idx;
+			CString name;
+			ANKI_CHECK(parseVariable(var.m_name.getBegin(), instanced, idx, name));
+
+			if(idx > 0)
+			{
+				continue;
+			}
+
+			ShaderProgramResourceInputVariable2& in = *m_inputVars.emplaceBack(getAllocator());
+			in.m_name.create(getAllocator(), name);
+			in.m_index = m_inputVars.getSize() - 1;
+			in.m_constant = false;
+			in.m_dataType = var.m_type;
+			in.m_instanced = instanced;
+		}
+	}
+
+	for(const ShaderProgramBinaryConstant& c : binary.m_constants)
+	{
+		U32 componentIdx;
+		U32 componentCount;
+		CString name;
+		ANKI_CHECK(parseConst(c.m_name.getBegin(), componentIdx, componentCount, name));
+
+		if(componentIdx > 0)
+		{
+			continue;
+		}
+
+		ShaderProgramResourceInputVariable2& in = *m_inputVars.emplaceBack(getAllocator());
+		in.m_name.create(getAllocator(), name);
+		in.m_index = m_inputVars.getSize() - 1;
+		in.m_constant = true;
+
+		if(componentCount == 1)
+		{
+			in.m_dataType = c.m_type;
+		}
+		else if(componentCount == 2)
+		{
+			if(c.m_type == ShaderVariableDataType::INT)
+			{
+				in.m_dataType = ShaderVariableDataType::IVEC2;
+			}
+			else
+			{
+				ANKI_ASSERT(c.m_type == ShaderVariableDataType::FLOAT);
+				in.m_dataType = ShaderVariableDataType::VEC2;
+			}
+		}
+		else if(componentCount == 3)
+		{
+			if(c.m_type == ShaderVariableDataType::INT)
+			{
+				in.m_dataType = ShaderVariableDataType::IVEC3;
+			}
+			else
+			{
+				ANKI_ASSERT(c.m_type == ShaderVariableDataType::FLOAT);
+				in.m_dataType = ShaderVariableDataType::VEC3;
+			}
+		}
+		else if(componentCount == 4)
+		{
+			if(c.m_type == ShaderVariableDataType::INT)
+			{
+				in.m_dataType = ShaderVariableDataType::IVEC4;
+			}
+			else
+			{
+				ANKI_ASSERT(c.m_type == ShaderVariableDataType::FLOAT);
+				in.m_dataType = ShaderVariableDataType::VEC4;
+			}
+		}
+		else
+		{
+			ANKI_ASSERT(0);
+		}
+	}
+
+	return Error::NONE;
+}
+
+Error ShaderProgramResource2::parseVariable(CString fullVarName, Bool& instanced, U32& idx, CString& name)
+{
+	if(fullVarName.find("u_ankiPerDraw") == CString::NPOS)
+	{
+		instanced = false;
+	}
+	else if(fullVarName.find("u_ankiPerInstance") == CString::NPOS)
+	{
+		instanced = true;
+	}
+	else
+	{
+		ANKI_RESOURCE_LOGE("Wrong variable name: %s", fullVarName.cstr());
+		return Error::USER_DATA;
+	}
+
+	if(instanced)
+	{
+		const PtrSize leftBracket = fullVarName.find("[");
+		const PtrSize rightBracket = fullVarName.find("]");
+
+		if(leftBracket == CString::NPOS || rightBracket == CString::NPOS || rightBracket <= leftBracket)
+		{
+			ANKI_RESOURCE_LOGE("Wrong variable name: %s", fullVarName.cstr());
+			return Error::USER_DATA;
+		}
+
+		Array<char, 8> idxStr;
+		ANKI_ASSERT(rightBracket - leftBracket < idxStr.getSize() - 1);
+		for(PtrSize i = leftBracket; i <= rightBracket; ++i)
+		{
+			idxStr[i - leftBracket] = fullVarName[i];
+		}
+		idxStr[rightBracket - leftBracket + 1] = '\0';
+
+		ANKI_CHECK(CString(idxStr.getBegin()).toNumber(idx));
+	}
+
+	const PtrSize dot = fullVarName.find(".");
+	if(dot == CString::NPOS)
+	{
+		ANKI_RESOURCE_LOGE("Wrong variable name: %s", fullVarName.cstr());
+		return Error::USER_DATA;
+	}
+
+	name = fullVarName.getBegin() + dot;
+
+	return Error::NONE;
+}
+
+Error ShaderProgramResource2::parseConst(CString constName, U32& componentIdx, U32& componentCount, CString& name)
+{
+	const CString prefixName = "_anki_const_";
+	const PtrSize prefix = constName.find(prefixName);
+	if(prefix != 0)
+	{
+		// Simple name
+		componentIdx = 0;
+		componentCount = 1;
+		name = constName;
+		return Error::NONE;
+	}
+
+	Array<char, 2> number;
+	number[0] = constName[prefixName.getLength() + 1];
+	number[1] = '\0';
+	ANKI_CHECK(CString(number.getBegin()).toNumber(componentIdx));
+
+	number[0] = constName[prefixName.getLength() + 3];
+	ANKI_CHECK(CString(number.getBegin()).toNumber(componentCount));
+
+	name = constName.getBegin() + prefixName.getLength() + 4;
 
 	return Error::NONE;
 }

+ 7 - 2
src/anki/resource/ShaderProgramResource2.h

@@ -37,9 +37,10 @@ class ShaderProgramResourceInputVariable2
 {
 public:
 	String m_name;
-	Bool m_constant = false;
-	ShaderVariableDataType m_dataType = ShaderVariableDataType::NONE;
 	U32 m_index = MAX_U32;
+	ShaderVariableDataType m_dataType = ShaderVariableDataType::NONE;
+	Bool m_constant = false;
+	Bool m_instanced = false;
 
 	Bool isTexture() const
 	{
@@ -160,6 +161,10 @@ private:
 	ShaderTypeBit m_shaderStages = ShaderTypeBit::NONE;
 
 	void initVariant(const ShaderProgramResourceVariantInitInfo2& info, ShaderProgramResourceVariant2& variant) const;
+
+	static ANKI_USE_RESULT Error parseVariable(CString fullVarName, Bool& instanced, U32& idx, CString& name);
+
+	static ANKI_USE_RESULT Error parseConst(CString constName, U32& componentIdx, U32& componentCount, CString& name);
 };
 
 /// The value of a constant.

+ 2 - 2
tests/shader_compiler/ShaderProgramCompiler.cpp

@@ -21,7 +21,7 @@ struct Instanced
 
 layout(set = 0, binding = 0) uniform ankiMaterial
 {
-	Instanced u_ankiInstanced[INSTANCE_COUNT];
+	Instanced u_ankiPerInstance[INSTANCE_COUNT];
 	Vec4 u_color;
 };
 
@@ -33,7 +33,7 @@ out gl_PerVertex
 
 void main()
 {
-	gl_Position = u_ankiInstanced[gl_InstanceID].m_ankiMvp * Vec4(gl_VertexID);
+	gl_Position = u_ankiPerInstance[gl_InstanceID].m_ankiMvp * Vec4(gl_VertexID);
 }
 #pragma anki end