Panagiotis Christopoulos Charitos 5 år sedan
förälder
incheckning
104c6b7ff1

+ 1 - 0
samples/simple_scene/Main.cpp

@@ -16,6 +16,7 @@ public:
 		ScriptResourcePtr script;
 		ANKI_CHECK(getResourceManager().loadResource("assets/scene.lua", script));
 		ANKI_CHECK(getScriptManager().evalString(script->getSource()));
+
 		return Error::NONE;
 	}
 };

+ 4 - 2
shaders/GBufferGeneric.ankiprog

@@ -16,6 +16,8 @@
 #pragma anki mutator PARALLAX 0 1
 #pragma anki mutator EMISSIVE_TEX 0 1
 
+#pragma anki rewrite_mutation ANKI_PASS 1 to ANKI_PASS 0
+
 #pragma anki rewrite_mutation ANKI_PASS 1 DIFFUSE_TEX 1 to ANKI_PASS 1 DIFFUSE_TEX 0
 #pragma anki rewrite_mutation ANKI_PASS 2 DIFFUSE_TEX 1 to ANKI_PASS 2 DIFFUSE_TEX 0
 #pragma anki rewrite_mutation ANKI_PASS 3 DIFFUSE_TEX 1 to ANKI_PASS 2 DIFFUSE_TEX 0
@@ -96,7 +98,7 @@ struct PerDraw
 	Vec3 m_emission;
 #	endif
 #	if REALLY_USING_PARALLAX
-	F32 m_heightMapScale;
+	F32 m_heightmapScale;
 #	endif
 #	if ANKI_PASS == PASS_GB
 	F32 m_subsurface;
@@ -340,7 +342,7 @@ void main()
 #if ANKI_PASS == PASS_GB
 #	if REALLY_USING_PARALLAX
 	const Vec2 uv =
-		computeTextureCoordParallax(u_heightTex, u_ankiGlobalSampler, in_uv, u_ankiPerDraw.m_heightMapScale);
+		computeTextureCoordParallax(u_heightTex, u_ankiGlobalSampler, in_uv, u_ankiPerDraw.m_heightmapScale);
 #	else
 	const Vec2 uv = in_uv;
 #	endif

+ 1 - 0
src/anki/Resource.h

@@ -11,6 +11,7 @@
 #include <anki/resource/ScriptResource.h>
 #include <anki/resource/MeshResource.h>
 #include <anki/resource/MaterialResource.h>
+#include <anki/resource/MaterialResource2.h>
 #include <anki/resource/TextureAtlasResource.h>
 #include <anki/resource/TextureResource.h>
 #include <anki/resource/GenericResource.h>

+ 2 - 1
src/anki/core/App.cpp

@@ -719,6 +719,7 @@ Error App::compileAllShaders()
 	const BindlessLimits limits = m_gr->getBindlessLimits();
 	U64 gpuHash = computeHash(&caps, sizeof(caps));
 	gpuHash = appendHash(&limits, sizeof(limits), gpuHash);
+	gpuHash = appendHash(&SHADER_BINARY_VERSION, sizeof(SHADER_BINARY_VERSION), gpuHash);
 
 	ANKI_CHECK(m_resourceFs->iterateAllFilenames([&](CString fname) -> Error {
 		// Check file extension
@@ -777,7 +778,7 @@ Error App::compileAllShaders()
 				const U64 finalHash = computeHash(hashes.getBegin(), hashes.getSizeInBytes());
 
 				m_newHash = finalHash;
-				return hash == m_metafileHash;
+				return finalHash == m_metafileHash;
 			};
 		} skip;
 		skip.m_metafileHash = metafileHash;

+ 2 - 0
src/anki/resource/InstantiationMacros.h

@@ -32,3 +32,5 @@ ANKI_INSTANSIATE_RESOURCE_DELIMITER()
 ANKI_INSTANTIATE_RESOURCE(ShaderProgramResource, ShaderProgramResourcePtr)
 ANKI_INSTANSIATE_RESOURCE_DELIMITER()
 ANKI_INSTANTIATE_RESOURCE(ShaderProgramResource2, ShaderProgramResource2Ptr)
+ANKI_INSTANSIATE_RESOURCE_DELIMITER()
+ANKI_INSTANTIATE_RESOURCE(MaterialResource2, MaterialResource2Ptr)

+ 196 - 72
src/anki/resource/MaterialResource2.cpp

@@ -22,16 +22,60 @@ public:
 static const Array<BuiltinVarInfo, U(BuiltinMaterialVariableId2::COUNT)> BUILTIN_INFOS = {
 	{{"NONE", ShaderVariableDataType::NONE, false},
 		{"m_ankiMvp", ShaderVariableDataType::MAT4, true},
-		{"m_ankiViewMatrix", ShaderVariableDataType::MAT4, true},
+		{"m_ankiPreviousMvp", ShaderVariableDataType::MAT4, true},
 		{"m_ankiModelMatrix", ShaderVariableDataType::MAT4, true},
-		{"m_ankiProjectionMatrix", ShaderVariableDataType::MAT4, false},
 		{"m_ankiViewMatrix", ShaderVariableDataType::MAT4, false},
+		{"m_ankiProjectionMatrix", ShaderVariableDataType::MAT4, false},
+		{"m_ankiModelViewMatrix", ShaderVariableDataType::MAT4, true},
+		{"m_ankiViewProjectionMatrix", ShaderVariableDataType::MAT4, false},
 		{"m_ankiNormalMatrix", ShaderVariableDataType::MAT3, true},
 		{"m_ankiRotationMatrix", ShaderVariableDataType::MAT3, true},
 		{"m_ankiCameraRotationMatrix", ShaderVariableDataType::MAT3, false},
 		{"m_ankiCameraPosition", ShaderVariableDataType::VEC3, false},
-		{"m_ankiPreviousMvp", ShaderVariableDataType::MAT4, true},
-		{"m_ankiGlobalSampler", ShaderVariableDataType::SAMPLER, false}}};
+		{"u_ankiGlobalSampler", ShaderVariableDataType::SAMPLER, false}}};
+
+static ANKI_USE_RESULT Error checkBuiltin(
+	CString name, ShaderVariableDataType dataType, Bool instanced, BuiltinMaterialVariableId2& outId)
+{
+	outId = BuiltinMaterialVariableId2::NONE;
+
+	for(BuiltinMaterialVariableId2 id : EnumIterable<BuiltinMaterialVariableId2>())
+	{
+		if(id == BuiltinMaterialVariableId2::NONE)
+		{
+			continue;
+		}
+
+		if(BUILTIN_INFOS[id].m_name == name)
+		{
+			outId = id;
+
+			if(BUILTIN_INFOS[id].m_type != dataType)
+			{
+				ANKI_RESOURCE_LOGE("Incorect type for builtin: %s", name.cstr());
+				return Error::USER_DATA;
+			}
+
+			if(BUILTIN_INFOS[id].m_instanced != instanced)
+			{
+				ANKI_RESOURCE_LOGE("Variable %s be instanced: %s",
+					(BUILTIN_INFOS[id].m_instanced) ? "should" : "shouldn't",
+					name.cstr());
+				return Error::USER_DATA;
+			}
+
+			break;
+		}
+	}
+
+	if(outId == BuiltinMaterialVariableId2::NONE && (name.find("m_anki") == 0 || name.find("u_anki") == 0))
+	{
+		ANKI_RESOURCE_LOGE("Unknown builtin var: %s", name.cstr());
+		return Error::USER_DATA;
+	}
+
+	return Error::NONE;
+}
 
 MaterialVariable2::MaterialVariable2()
 {
@@ -50,7 +94,32 @@ MaterialResource2::MaterialResource2(ResourceManager* manager)
 
 MaterialResource2::~MaterialResource2()
 {
-	// TODO
+	for(Pass p : EnumIterable<Pass>())
+	{
+		for(U32 l = 0; l < MAX_LOD_COUNT; ++l)
+		{
+			for(U32 inst = 0; inst < MAX_INSTANCE_GROUPS; ++inst)
+			{
+				for(U32 skinned = 0; skinned <= 1; ++skinned)
+				{
+					for(U32 vel = 0; vel <= 1; ++vel)
+					{
+						MaterialVariant2& variant = m_variantMatrix[p][l][inst][skinned][vel];
+						variant.m_blockInfos.destroy(getAllocator());
+						variant.m_opaqueBindings.destroy(getAllocator());
+					}
+				}
+			}
+		}
+	}
+
+	for(MaterialVariable2& var : m_vars)
+	{
+		var.m_name.destroy(getAllocator());
+	}
+	m_vars.destroy(getAllocator());
+
+	m_nonBuiltinsMutation.destroy(getAllocator());
 }
 
 Error MaterialResource2::load(const ResourceFilename& filename, Bool async)
@@ -80,9 +149,9 @@ Error MaterialResource2::load(const ResourceFilename& filename, Bool async)
 	ANKI_CHECK(rootEl.getAttributeNumberOptional("forwardShading", m_forwardShading, present));
 	m_forwardShading = m_forwardShading != 0;
 
-	// <mutators>
+	// <mutation>
 	XmlElement mutatorsEl;
-	ANKI_CHECK(rootEl.getChildElementOptional("mutators", mutatorsEl));
+	ANKI_CHECK(rootEl.getChildElementOptional("mutation", mutatorsEl));
 	if(mutatorsEl)
 	{
 		ANKI_CHECK(parseMutators(mutatorsEl));
@@ -95,16 +164,6 @@ Error MaterialResource2::load(const ResourceFilename& filename, Bool async)
 		ANKI_CHECK(parseInputs(el, async));
 	}
 
-	// Check that all non-builtin vars have a value
-	for(const MaterialVariable2& var : m_vars)
-	{
-		if(!var.isBuildin() && !var.valueSetByMaterial())
-		{
-			ANKI_RESOURCE_LOGE("Missing value for variable %s", var.m_name.cstr());
-			return Error::USER_DATA;
-		}
-	}
-
 	return Error::NONE;
 }
 
@@ -296,11 +355,13 @@ Error MaterialResource2::parseMutators(XmlElement mutatorsEl)
 
 Error MaterialResource2::parseVariable(CString fullVarName, Bool& instanced, U32& idx, CString& name)
 {
-	if(fullVarName.find("u_ankiPerDraw") == CString::NPOS)
+	idx = 0;
+
+	if(fullVarName.find("u_ankiPerDraw") != CString::NPOS)
 	{
 		instanced = false;
 	}
-	else if(fullVarName.find("u_ankiPerInstance") == CString::NPOS)
+	else if(fullVarName.find("u_ankiPerInstance") != CString::NPOS)
 	{
 		instanced = true;
 	}
@@ -310,26 +371,42 @@ Error MaterialResource2::parseVariable(CString fullVarName, Bool& instanced, U32
 		return Error::USER_DATA;
 	}
 
+	const PtrSize leftBracket = fullVarName.find("[");
+	const PtrSize rightBracket = fullVarName.find("]");
+
 	if(instanced)
 	{
-		const PtrSize leftBracket = fullVarName.find("[");
-		const PtrSize rightBracket = fullVarName.find("]");
-
-		if(leftBracket == CString::NPOS || rightBracket == CString::NPOS || rightBracket <= leftBracket)
+		const Bool correct =
+			(leftBracket == CString::NPOS && rightBracket == CString::NPOS)
+			|| (leftBracket != CString::NPOS && rightBracket != CString::NPOS && rightBracket > leftBracket);
+		if(!correct)
 		{
 			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)
+		if(leftBracket != CString::NPOS)
 		{
-			idxStr[i - leftBracket] = fullVarName[i];
-		}
-		idxStr[rightBracket - leftBracket + 1] = '\0';
+			Array<char, 8> idxStr = {};
+			for(PtrSize i = leftBracket + 1; i < rightBracket; ++i)
+			{
+				idxStr[i - (leftBracket + 1)] = fullVarName[i];
+			}
 
-		ANKI_CHECK(CString(idxStr.getBegin()).toNumber(idx));
+			ANKI_CHECK(CString(idxStr.getBegin()).toNumber(idx));
+		}
+		else
+		{
+			idx = 0;
+		}
+	}
+	else
+	{
+		if(leftBracket != CString::NPOS || rightBracket != CString::NPOS)
+		{
+			ANKI_RESOURCE_LOGE("Can't support non instanced array variables: %s", fullVarName.cstr());
+			return Error::USER_DATA;
+		}
 	}
 
 	const PtrSize dot = fullVarName.find(".");
@@ -339,7 +416,7 @@ Error MaterialResource2::parseVariable(CString fullVarName, Bool& instanced, U32
 		return Error::USER_DATA;
 	}
 
-	name = fullVarName.getBegin() + dot;
+	name = fullVarName.getBegin() + dot + 1;
 
 	return Error::NONE;
 }
@@ -369,12 +446,36 @@ Error MaterialResource2::createVars()
 			U32 idx;
 			CString name;
 			ANKI_CHECK(parseVariable(var.m_name.getBegin(), instanced, idx, name));
+			ANKI_ASSERT(name.getLength() > 0 && (instanced || idx == 0));
 
 			if(idx > 0)
 			{
+				if(idx > MAX_INSTANCES)
+				{
+					ANKI_RESOURCE_LOGE("Array variable exceeds the instance count: %s", var.m_name.getBegin());
+					return Error::USER_DATA;
+				}
+
+				if(idx == 1)
+				{
+					// Find the idx==0
+					MaterialVariable2* other = tryFindVariable(name);
+					ANKI_ASSERT(other);
+					ANKI_ASSERT(other->m_indexInBinary2ndElement == MAX_U32);
+					other->m_indexInBinary2ndElement = U32(&var - block.m_variables.getBegin());
+				}
+
+				// Skip var
 				continue;
 			}
 
+			const MaterialVariable2* other = tryFindVariable(name);
+			if(other)
+			{
+				ANKI_RESOURCE_LOGE("Variable found twice: %s", name.cstr());
+				return Error::USER_DATA;
+			}
+
 			MaterialVariable2& in = *m_vars.emplaceBack(getAllocator());
 			in.m_name.create(getAllocator(), name);
 			in.m_index = m_vars.getSize() - 1;
@@ -384,34 +485,7 @@ Error MaterialResource2::createVars()
 			in.m_dataType = var.m_type;
 
 			// Check if it's builtin
-			for(BuiltinMaterialVariableId2 id : EnumIterable<BuiltinMaterialVariableId2>())
-			{
-				if(id == BuiltinMaterialVariableId2::NONE)
-				{
-					continue;
-				}
-
-				if(BUILTIN_INFOS[id].m_name == name)
-				{
-					in.m_builtin = id;
-
-					if(BUILTIN_INFOS[id].m_type != in.m_dataType)
-					{
-						ANKI_RESOURCE_LOGE("Incorect type for builtin: %s", name.cstr());
-						return Error::USER_DATA;
-					}
-
-					if(BUILTIN_INFOS[id].m_instanced == instanced)
-					{
-						ANKI_RESOURCE_LOGE("Variable %s be instanced: %s",
-							(BUILTIN_INFOS[id].m_instanced) ? "should" : "shouldn't",
-							name.cstr());
-						return Error::USER_DATA;
-					}
-
-					break;
-				}
-			}
+			ANKI_CHECK(checkBuiltin(name, in.m_dataType, instanced, in.m_builtin));
 		}
 	}
 
@@ -438,6 +512,9 @@ Error MaterialResource2::createVars()
 		in.m_constant = false;
 		in.m_instanced = false;
 		in.m_dataType = o.m_type;
+
+		// Check if it's builtin
+		ANKI_CHECK(checkBuiltin(in.m_name, in.m_dataType, false, in.m_builtin));
 	}
 
 	if(descriptorSet != maxDescriptorSet)
@@ -474,15 +551,7 @@ Error MaterialResource2::parseInputs(XmlElement inputsEl, Bool async)
 		ANKI_CHECK(inputEl.getAttributeText("shaderVar", varName));
 
 		// Try find var
-		MaterialVariable2* foundVar = nullptr;
-		for(MaterialVariable2& v : m_vars)
-		{
-			if(v.m_name == varName)
-			{
-				foundVar = &v;
-				break;
-			}
-		}
+		MaterialVariable2* foundVar = tryFindVariable(varName);
 
 		if(foundVar == nullptr)
 		{
@@ -490,12 +559,15 @@ Error MaterialResource2::parseInputs(XmlElement inputsEl, Bool async)
 			return Error::USER_DATA;
 		}
 
-		if(foundVar->m_builtin == BuiltinMaterialVariableId2::NONE)
+		if(foundVar->m_builtin != BuiltinMaterialVariableId2::NONE)
 		{
 			ANKI_RESOURCE_LOGE("Shouldn't list builtin vars: %s", varName.cstr());
 			return Error::USER_DATA;
 		}
 
+		// A value will be set
+		foundVar->m_mat4(3, 3) = 0.0f;
+
 		// Process var
 		if(foundVar->isConstant())
 		{
@@ -697,6 +769,11 @@ const MaterialVariant2& MaterialResource2::getOrCreateVariant(const RenderingKey
 			continue;
 		}
 
+		if(!var.valueSetByMaterial())
+		{
+			continue;
+		}
+
 		switch(var.m_dataType)
 		{
 		case ShaderVariableDataType::INT:
@@ -732,12 +809,13 @@ const MaterialVariant2& MaterialResource2::getOrCreateVariant(const RenderingKey
 	m_prog->getOrCreateVariant(initInfo, progVariant);
 
 	// Init the variant
-	initVariant(*progVariant, variant);
+	initVariant(*progVariant, variant, key.getInstanceCount());
 
 	return variant;
 }
 
-void MaterialResource2::initVariant(const ShaderProgramResourceVariant2& progVariant, MaterialVariant2& variant) const
+void MaterialResource2::initVariant(
+	const ShaderProgramResourceVariant2& progVariant, MaterialVariant2& variant, U32 instanceCount) const
 {
 	// Find the block instance
 	const ShaderProgramBinary& binary = m_prog->getBinary();
@@ -763,6 +841,7 @@ void MaterialResource2::initVariant(const ShaderProgramResourceVariant2& progVar
 	variant.m_blockInfos.create(getAllocator(), m_vars.getSize());
 	variant.m_opaqueBindings.create(getAllocator(), m_vars.getSize(), -1);
 	variant.m_uniBlockSize = binaryBlockInstance->m_size;
+	ANKI_ASSERT(variant.m_uniBlockSize > 0);
 
 	// Initialize the block infos, active vars and bindings
 	for(const MaterialVariable2& var : m_vars)
@@ -774,6 +853,7 @@ void MaterialResource2::initVariant(const ShaderProgramResourceVariant2& progVar
 				if(c.m_name == var.m_name)
 				{
 					variant.m_activeVars.set(var.m_index, progVariant.isConstantActive(c));
+					break;
 				}
 			}
 		}
@@ -785,7 +865,24 @@ void MaterialResource2::initVariant(const ShaderProgramResourceVariant2& progVar
 				{
 					variant.m_activeVars.set(var.m_index, true);
 					variant.m_blockInfos[var.m_index] = instance.m_blockInfo;
-					break;
+
+					if(var.m_instanced)
+					{
+						variant.m_blockInfos[var.m_index].m_arraySize = I16(instanceCount);
+					}
+					else
+					{
+						break;
+					}
+				}
+				else if(instance.m_index == var.m_indexInBinary2ndElement)
+				{
+					// Then we need to update the stride
+					ANKI_ASSERT(variant.m_blockInfos[var.m_index].m_offset >= 0);
+
+					const I16 stride = I16(instance.m_blockInfo.m_offset - variant.m_blockInfos[var.m_index].m_offset);
+					ANKI_ASSERT(stride >= 4);
+					variant.m_blockInfos[var.m_index].m_arrayStride = stride;
 				}
 			}
 		}
@@ -803,6 +900,33 @@ void MaterialResource2::initVariant(const ShaderProgramResourceVariant2& progVar
 			}
 		}
 	}
+
+	// No make sure that the vars that are active
+	for(const MaterialVariable2& var : m_vars)
+	{
+		if(var.m_builtin == BuiltinMaterialVariableId2::NONE && variant.m_activeVars.get(var.m_index)
+			&& !var.valueSetByMaterial())
+		{
+			ANKI_RESOURCE_LOGF("An active variable doesn't have its value set by the material: %s", var.m_name.cstr());
+		}
+
+		ANKI_ASSERT(!(var.m_instanced && var.m_indexInBinary2ndElement == MAX_U32));
+	}
+
+// Debug print
+#if 0
+	printf("binary variant idx %u\n", U32(&binaryVariant - binary.m_variants.getBegin()));
+	for(const MaterialVariable2& var : m_vars)
+	{
+
+		printf("Var %s %s\n", var.m_name.cstr(), variant.m_activeVars.get(var.m_index) ? "active" : "inactive");
+		if(var.inBlock() && variant.m_activeVars.get(var.m_index))
+		{
+			const ShaderVariableBlockInfo& inf = variant.m_blockInfos[var.m_index];
+			printf("\tblockInfo %d,%d,%d,%d\n", inf.m_offset, inf.m_arraySize, inf.m_arrayStride, inf.m_matrixStride);
+		}
+	}
+#endif
 }
 
 U32 MaterialResource2::getInstanceGroupIdx(U32 instanceCount)

+ 33 - 6
src/anki/resource/MaterialResource2.h

@@ -25,15 +25,16 @@ enum class BuiltinMaterialVariableId2 : U8
 {
 	NONE = 0,
 	MODEL_VIEW_PROJECTION_MATRIX,
-	MODEL_VIEW_MATRIX,
+	PREVIOUS_MODEL_VIEW_PROJECTION_MATRIX,
 	MODEL_MATRIX,
-	VIEW_PROJECTION_MATRIX,
 	VIEW_MATRIX,
+	PROJECTION_MATRIX,
+	MODEL_VIEW_MATRIX,
+	VIEW_PROJECTION_MATRIX,
 	NORMAL_MATRIX,
 	ROTATION_MATRIX,
 	CAMERA_ROTATION_MATRIX,
 	CAMERA_POSITION,
-	PREVIOUS_MODEL_VIEW_PROJECTION_MATRIX,
 	GLOBAL_SAMPLER,
 
 	COUNT,
@@ -62,6 +63,7 @@ public:
 		m_name = std::move(b.m_name);
 		m_index = b.m_index;
 		m_indexInBinary = b.m_indexInBinary;
+		m_indexInBinary2ndElement = b.m_indexInBinary2ndElement;
 		m_constant = b.m_constant;
 		m_instanced = b.m_instanced;
 		m_dataType = b.m_dataType;
@@ -128,6 +130,7 @@ protected:
 	String m_name;
 	U32 m_index = MAX_U32;
 	U32 m_indexInBinary = MAX_U32;
+	U32 m_indexInBinary2ndElement = MAX_U32;
 	Bool m_constant = false;
 	Bool m_instanced = false;
 	ShaderVariableDataType m_dataType = ShaderVariableDataType::NONE;
@@ -249,9 +252,9 @@ private:
 ///		[forwardShading="0 | 1"]
 ///		<shaderProgram="path"/>
 ///
-///		[<mutators>
+///		[<mutation>
 ///			<mutator name="str" value="value"/>
-///		</mutators>]
+///		</mutation>]
 ///
 ///		[<inputs>
 ///			<input shaderVar="name to shaderProg var" value="values"/> (1)
@@ -347,7 +350,31 @@ private:
 
 	static U32 getInstanceGroupIdx(U32 instanceCount);
 
-	void initVariant(const ShaderProgramResourceVariant2& progVariant, MaterialVariant2& variant) const;
+	void initVariant(
+		const ShaderProgramResourceVariant2& progVariant, MaterialVariant2& variant, U32 instanceCount) const;
+
+	const MaterialVariable2* tryFindVariableInternal(CString name) const
+	{
+		for(const MaterialVariable2& v : m_vars)
+		{
+			if(v.m_name == name)
+			{
+				return &v;
+			}
+		}
+
+		return nullptr;
+	}
+
+	const MaterialVariable2* tryFindVariable(CString name) const
+	{
+		return tryFindVariableInternal(name);
+	}
+
+	MaterialVariable2* tryFindVariable(CString name)
+	{
+		return const_cast<MaterialVariable2*>(tryFindVariableInternal(name));
+	}
 };
 /// @}
 

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

@@ -18,7 +18,9 @@ enum class Pass : U8
 	FS, ///< Forward shading.
 	SM, ///< Shadow mapping.
 	EZ, ///< Early Z.
-	COUNT
+
+	COUNT,
+	FIRST = 0
 };
 
 /// A key that consistst of the rendering pass and the level of detail

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

@@ -11,6 +11,7 @@
 #include <anki/gr/ShaderCompiler.h>
 
 #include <anki/resource/MaterialResource.h>
+#include <anki/resource/MaterialResource2.h>
 #include <anki/resource/MeshResource.h>
 #include <anki/resource/ModelResource.h>
 #include <anki/resource/ScriptResource.h>

+ 3 - 2
src/anki/shader_compiler/ShaderProgramCompiler.cpp

@@ -14,6 +14,7 @@ namespace anki
 {
 
 static const char* SHADER_BINARY_MAGIC = "ANKISDR1";
+const U32 SHADER_BINARY_VERSION = 1;
 
 Error ShaderProgramBinaryWrapper::serializeToFile(CString fname) const
 {
@@ -23,8 +24,8 @@ Error ShaderProgramBinaryWrapper::serializeToFile(CString fname) const
 	ANKI_CHECK(file.open(fname, FileOpenFlag::WRITE | FileOpenFlag::BINARY));
 
 	BinarySerializer serializer;
-	StackAllocator<U8> tmpAlloc(
-		m_alloc.getMemoryPool().getAllocationCallback(), m_alloc.getMemoryPool().getAllocationCallbackUserData(), 4_KB);
+	HeapAllocator<U8> tmpAlloc(
+		m_alloc.getMemoryPool().getAllocationCallback(), m_alloc.getMemoryPool().getAllocationCallbackUserData());
 	ANKI_CHECK(serializer.serialize(*m_binary, tmpAlloc, file));
 
 	return Error::NONE;

+ 2 - 0
src/anki/shader_compiler/ShaderProgramCompiler.h

@@ -15,6 +15,8 @@ namespace anki
 /// @addtogroup shader_compiler
 /// @{
 
+extern const U32 SHADER_BINARY_VERSION;
+
 /// A wrapper over the POD ShaderProgramBinary class.
 /// @memberof ShaderProgramCompiler
 class ShaderProgramBinaryWrapper : public NonCopyable

+ 4 - 1
src/anki/shader_compiler/ShaderProgramReflection.cpp

@@ -171,6 +171,7 @@ Error SpirvReflector::blockVariableReflection(
 		}
 
 		// Array size
+		Bool isArray = false;
 		{
 			if(!memberType.array.empty())
 			{
@@ -185,10 +186,12 @@ Error SpirvReflector::blockVariableReflection(
 				{
 					// Have a min to acount for unsized arrays of SSBOs
 					var.m_blockInfo.m_arraySize = max<I16>(I16(memberType.array[0]), 1);
+					isArray = true;
 				}
 				else
 				{
 					var.m_blockInfo.m_arraySize = 1;
+					isArray = true;
 				}
 			}
 			else
@@ -227,7 +230,7 @@ Error SpirvReflector::blockVariableReflection(
 
 		if(memberType.basetype == spirv_cross::SPIRType::Struct)
 		{
-			if(var.m_blockInfo.m_arraySize == 1)
+			if(var.m_blockInfo.m_arraySize == 1 && !isArray)
 			{
 				ANKI_CHECK(blockVariableReflection(memberType, var.m_name, var.m_blockInfo.m_offset, vars));
 			}