Browse Source

Some refactoring on the shader program resource. Move TAA to new format

Panagiotis Christopoulos Charitos 8 years ago
parent
commit
348ba4f9fc

+ 4 - 4
programs/MsGeneric.ankiprog

@@ -6,7 +6,7 @@ http://www.anki3d.org/LICENSE
 -->
 -->
 <shaderProgram>
 <shaderProgram>
 	<mutators>
 	<mutators>
-		<mutator name="INSTANCE_COUNT" values="1 2 4 8 16 32 64"/>
+		<mutator name="INSTANCE_COUNT" values="1 2 4 8 16 32 64" instanced="1"/>
 		<mutator name="LOD" values="0 1 2"/>
 		<mutator name="LOD" values="0 1 2"/>
 		<mutator name="PASS" values="0 1"/>
 		<mutator name="PASS" values="0 1"/>
 		<mutator name="DIFFUSE_TEX" values="0 1"/>
 		<mutator name="DIFFUSE_TEX" values="0 1"/>
@@ -21,13 +21,13 @@ http://www.anki3d.org/LICENSE
 	<shaders>
 	<shaders>
 		<shader type="vert">
 		<shader type="vert">
 			<inputs>
 			<inputs>
-				<input name="mvp" type="mat4" instanceCount="INSTANCE_COUNT"/>
-				<input name="normalMat" type="mat3" instanceCount="INSTANCE_COUNT">
+				<input name="mvp" type="mat4" instanced="1"/>
+				<input name="normalMat" type="mat3" instanced="1">
 					<mutators>
 					<mutators>
 						<mutator name="PASS" values="0"/>
 						<mutator name="PASS" values="0"/>
 					</mutators>
 					</mutators>
 				</input>
 				</input>
-				<input name="modelViewMat" type="mat4" instanceCount="INSTANCE_COUNT">
+				<input name="modelViewMat" type="mat4" instanced="1">
 					<mutators>
 					<mutators>
 						<mutator name="PASS" values="0"/>
 						<mutator name="PASS" values="0"/>
 						<mutator name="PARALLAX" values="1"/>
 						<mutator name="PARALLAX" values="1"/>

+ 22 - 7
shaders/Taa.frag.glsl → programs/TemporalAAResolve.ankiprog

@@ -1,8 +1,19 @@
-// Copyright (C) 2009-2017, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
+<!-- 
+Copyright (C) 2009-2017, Panagiotis Christopoulos Charitos and contributors.
+All rights reserved.
+Code licensed under the BSD License.
+http://www.anki3d.org/LICENSE
+-->
+<shaderProgram>
+	<shaders>
+		<shader type="vert">
+			<source><![CDATA[
+#include "shaders/Quad.vert.glsl"
+			]]></source>
+		</shader>
+
+		<shader type="frag">
+			<source><![CDATA[
 #include "shaders/Functions.glsl"
 #include "shaders/Functions.glsl"
 #include "shaders/Pack.glsl"
 #include "shaders/Pack.glsl"
 #include "shaders/Tonemapping.glsl"
 #include "shaders/Tonemapping.glsl"
@@ -54,7 +65,7 @@ void main()
 
 
 	historyCol = clamp(historyCol, boxMin, boxMax);
 	historyCol = clamp(historyCol, boxMin, boxMax);
 
 
-// Remove jitter (T. Lottes)
+	// Remove jitter (T. Lottes)
 #if YCBCR
 #if YCBCR
 	float lum0 = crntCol.r;
 	float lum0 = crntCol.r;
 	float lum1 = historyCol.r;
 	float lum1 = historyCol.r;
@@ -70,10 +81,14 @@ void main()
 	diff = diff * diff;
 	diff = diff * diff;
 	float feedback = mix(0.0, BLEND_FACTOR, diff);
 	float feedback = mix(0.0, BLEND_FACTOR, diff);
 
 
-// Write result
+	// Write result
 #if YCBCR
 #if YCBCR
 	out_color = yCbCrToRgb(mix(historyCol, crntCol, feedback));
 	out_color = yCbCrToRgb(mix(historyCol, crntCol, feedback));
 #else
 #else
 	out_color = mix(historyCol, crntCol, feedback);
 	out_color = mix(historyCol, crntCol, feedback);
 #endif
 #endif
 }
 }
+			]]></source>
+		</shader>
+	</shaders>
+</shaderProgram>	

+ 1 - 1
src/anki/renderer/Drawer.cpp

@@ -438,7 +438,7 @@ Error RenderableDrawer::drawSingle(DrawContext& ctx)
 
 
 	// Fill the crntBuild
 	// Fill the crntBuild
 	F32 flod = m_r->calculateLod(sqrt(ctx.m_visibleNode->m_frustumDistanceSquared));
 	F32 flod = m_r->calculateLod(sqrt(ctx.m_visibleNode->m_frustumDistanceSquared));
-	flod = min<F32>(flod, MAX_LOD - 1);
+	flod = min<F32>(flod, MAX_LOD_COUNT - 1);
 
 
 	crntBuild.m_rc = &renderable;
 	crntBuild.m_rc = &renderable;
 	crntBuild.m_flod = flod;
 	crntBuild.m_flod = flod;

+ 12 - 5
src/anki/renderer/Taa.cpp

@@ -11,6 +11,11 @@
 namespace anki
 namespace anki
 {
 {
 
 
+Taa::Taa(Renderer* r)
+	: RenderingPass(r)
+{
+}
+
 Taa::~Taa()
 Taa::~Taa()
 {
 {
 }
 }
@@ -30,8 +35,10 @@ Error Taa::init(const ConfigSet& config)
 
 
 Error Taa::initInternal(const ConfigSet& config)
 Error Taa::initInternal(const ConfigSet& config)
 {
 {
-	ANKI_CHECK(m_r->getResourceManager().loadResource("shaders/Taa.frag.glsl", m_frag));
-	m_r->createDrawQuadShaderProgram(m_frag->getGrShader(), m_prog);
+	ANKI_CHECK(m_r->getResourceManager().loadResource("programs/TemporalAAResolve.ankiprog", m_prog));
+	const ShaderProgramResourceVariant* variant;
+	m_prog->getOrCreateVariant(variant);
+	m_grProg = variant->getProgram();
 
 
 	for(U i = 0; i < 2; ++i)
 	for(U i = 0; i < 2; ++i)
 	{
 	{
@@ -68,9 +75,9 @@ void Taa::run(RenderingContext& ctx)
 	cmdb->beginRenderPass(m_fbs[m_r->getFrameCount() & 1]);
 	cmdb->beginRenderPass(m_fbs[m_r->getFrameCount() & 1]);
 	cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
 	cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
 
 
-	cmdb->bindShaderProgram(m_prog);
-	cmdb->bindTextureAndSampler(0, 0, m_r->getMs().m_depthRt, m_r->getNearestSampler());
-	cmdb->bindTextureAndSampler(0, 1, m_r->getIs().getRt(), m_r->getNearestSampler());
+	cmdb->bindShaderProgram(m_grProg);
+	cmdb->bindTextureAndSampler(0, 0, m_r->getMs().m_depthRt, m_r->getLinearSampler());
+	cmdb->bindTextureAndSampler(0, 1, m_r->getIs().getRt(), m_r->getLinearSampler());
 	cmdb->informTextureCurrentUsage(m_rts[(m_r->getFrameCount() + 1) & 1], TextureUsageBit::SAMPLED_FRAGMENT);
 	cmdb->informTextureCurrentUsage(m_rts[(m_r->getFrameCount() + 1) & 1], TextureUsageBit::SAMPLED_FRAGMENT);
 	cmdb->bindTextureAndSampler(0, 2, m_rts[(m_r->getFrameCount() + 1) & 1], m_r->getLinearSampler());
 	cmdb->bindTextureAndSampler(0, 2, m_rts[(m_r->getFrameCount() + 1) & 1], m_r->getLinearSampler());
 
 

+ 3 - 6
src/anki/renderer/Taa.h

@@ -17,10 +17,7 @@ namespace anki
 class Taa : public RenderingPass
 class Taa : public RenderingPass
 {
 {
 public:
 public:
-	Taa(Renderer* r)
-		: RenderingPass(r)
-	{
-	}
+	Taa(Renderer* r);
 
 
 	~Taa();
 	~Taa();
 
 
@@ -36,8 +33,8 @@ private:
 	Array<TexturePtr, 2> m_rts;
 	Array<TexturePtr, 2> m_rts;
 	Array<FramebufferPtr, 2> m_fbs;
 	Array<FramebufferPtr, 2> m_fbs;
 
 
-	ShaderResourcePtr m_frag;
-	ShaderProgramPtr m_prog;
+	ShaderProgramResourcePtr m_prog;
+	ShaderProgramPtr m_grProg;
 
 
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
 };
 };

+ 1 - 1
src/anki/resource/Common.h

@@ -31,7 +31,7 @@ class ResourcePointer;
 
 
 /// @name Constants
 /// @name Constants
 /// @{
 /// @{
-const U MAX_LOD = 3;
+const U MAX_LOD_COUNT = 3;
 const U MAX_INSTANCES = 64;
 const U MAX_INSTANCES = 64;
 const U MAX_SUB_DRAWCALLS = 64;
 const U MAX_SUB_DRAWCALLS = 64;
 
 

+ 52 - 58
src/anki/resource/Material.cpp

@@ -144,81 +144,53 @@ Error Material::parseMutators(XmlElement mutatorsEl)
 
 
 	// Find the builtin mutators
 	// Find the builtin mutators
 	U builtinMutatorCount = 0;
 	U builtinMutatorCount = 0;
-	for(const ShaderProgramResourceMutator& m : m_prog->getMutators())
+
+	m_instanceMutator = m_prog->getInstancingMutator();
+	if(m_instanceMutator)
 	{
 	{
-		if(m.getName() == "INSTANCE_COUNT")
+		if(m_instanceMutator->getName() != "INSTANCE_COUNT")
 		{
 		{
-			if(!m_prog->isInstanced())
-			{
-				ANKI_RESOURCE_LOGE("Program is not instanced but has the INSTANCE_COUNT mutator");
-				return ErrorCode::USER_DATA;
-			}
-
-			if(m.getValues().getSize() != MAX_INSTANCE_GROUPS)
-			{
-				ANKI_RESOURCE_LOGE("Mutator INSTANCE_COUNT should have %u values in the program", MAX_INSTANCE_GROUPS);
-				return ErrorCode::USER_DATA;
-			}
-
-			for(U i = 0; i < MAX_INSTANCE_GROUPS; ++i)
-			{
-				if(m.getValues()[i] != (1 << i))
-				{
-					ANKI_RESOURCE_LOGE("Values of the INSTANCE_COUNT mutator in the program are not the expected");
-					return ErrorCode::USER_DATA;
-				}
-			}
+			ANKI_RESOURCE_LOGE("If program is instanced then the instance mutator should be the INSTANCE_COUNT");
+			return ErrorCode::USER_DATA;
+		}
 
 
-			m_instanceMutator = &m;
-			++builtinMutatorCount;
+		if(m_instanceMutator->getValues().getSize() != MAX_INSTANCE_GROUPS)
+		{
+			ANKI_RESOURCE_LOGE("Mutator INSTANCE_COUNT should have %u values in the program", MAX_INSTANCE_GROUPS);
+			return ErrorCode::USER_DATA;
 		}
 		}
-		else if(m.getName() == "PASS")
+
+		for(U i = 0; i < MAX_INSTANCE_GROUPS; ++i)
 		{
 		{
-			if(m.getValues().getSize() != U(Pass::COUNT))
+			if(m_instanceMutator->getValues()[i] != (1 << i))
 			{
 			{
-				ANKI_RESOURCE_LOGE("Mutator PASS should have %u values in the program", U(Pass::COUNT));
+				ANKI_RESOURCE_LOGE("Values of the INSTANCE_COUNT mutator in the program are not the expected");
 				return ErrorCode::USER_DATA;
 				return ErrorCode::USER_DATA;
 			}
 			}
+		}
 
 
-			for(U i = 0; i < U(Pass::COUNT); ++i)
-			{
-				if(m.getValues()[i] != I(i))
-				{
-					ANKI_RESOURCE_LOGE("Values of the PASS mutator in the program are not the expected");
-					return ErrorCode::USER_DATA;
-				}
-			}
+		++builtinMutatorCount;
+	}
 
 
-			m_passMutator = &m;
-			++builtinMutatorCount;
+	m_passMutator = m_prog->tryFindMutator("PASS");
+	if(m_passMutator)
+	{
+		if(m_passMutator->getValues().getSize() != U(Pass::COUNT))
+		{
+			ANKI_RESOURCE_LOGE("Mutator PASS should have %u values in the program", U(Pass::COUNT));
+			return ErrorCode::USER_DATA;
 		}
 		}
-		else if(m.getName() == "LOD")
+
+		for(U i = 0; i < U(Pass::COUNT); ++i)
 		{
 		{
-			if(m.getValues().getSize() > MAX_LOD)
+			if(m_passMutator->getValues()[i] != I(i))
 			{
 			{
-				ANKI_RESOURCE_LOGE("Mutator LOD should have at least %u values in the program", U(MAX_LOD));
+				ANKI_RESOURCE_LOGE("Values of the PASS mutator in the program are not the expected");
 				return ErrorCode::USER_DATA;
 				return ErrorCode::USER_DATA;
 			}
 			}
-
-			for(U i = 0; i < m.getValues().getSize(); ++i)
-			{
-				if(m.getValues()[i] != I(i))
-				{
-					ANKI_RESOURCE_LOGE("Values of the LOD mutator in the program are not the expected");
-					return ErrorCode::USER_DATA;
-				}
-			}
-
-			m_lodMutator = &m;
-			m_lodCount = m.getValues().getSize();
-			++builtinMutatorCount;
 		}
 		}
-	}
 
 
-	if(m_prog->isInstanced() && !m_instanceMutator)
-	{
-		ANKI_RESOURCE_LOGE("If program is instanced then the instance mutator sHould be the INSTANCE_COUNT");
-		return ErrorCode::USER_DATA;
+		++builtinMutatorCount;
 	}
 	}
 
 
 	if(!m_forwardShading && !m_passMutator)
 	if(!m_forwardShading && !m_passMutator)
@@ -227,6 +199,28 @@ Error Material::parseMutators(XmlElement mutatorsEl)
 		return ErrorCode::USER_DATA;
 		return ErrorCode::USER_DATA;
 	}
 	}
 
 
+	m_lodMutator = m_prog->tryFindMutator("LOD");
+	if(m_lodMutator)
+	{
+		if(m_lodMutator->getValues().getSize() > MAX_LOD_COUNT)
+		{
+			ANKI_RESOURCE_LOGE("Mutator LOD should have at least %u values in the program", U(MAX_LOD_COUNT));
+			return ErrorCode::USER_DATA;
+		}
+
+		for(U i = 0; i < m_lodMutator->getValues().getSize(); ++i)
+		{
+			if(m_lodMutator->getValues()[i] != I(i))
+			{
+				ANKI_RESOURCE_LOGE("Values of the LOD mutator in the program are not the expected");
+				return ErrorCode::USER_DATA;
+			}
+		}
+
+		m_lodCount = m_lodMutator->getValues().getSize();
+		++builtinMutatorCount;
+	}
+
 	if(m_mutations.getSize() + builtinMutatorCount != m_prog->getMutators().getSize())
 	if(m_mutations.getSize() + builtinMutatorCount != m_prog->getMutators().getSize())
 	{
 	{
 		ANKI_RESOURCE_LOGE("Some mutatators are unacounted for");
 		ANKI_RESOURCE_LOGE("Some mutatators are unacounted for");

+ 1 - 1
src/anki/resource/Material.h

@@ -254,7 +254,7 @@ private:
 	DynamicArray<ShaderProgramResourceMutation> m_mutations;
 	DynamicArray<ShaderProgramResourceMutation> m_mutations;
 
 
 	/// Matrix of variants.
 	/// Matrix of variants.
-	mutable Array3d<MaterialVariant, U(Pass::COUNT), MAX_LOD, MAX_INSTANCE_GROUPS> m_variantMatrix;
+	mutable Array3d<MaterialVariant, U(Pass::COUNT), MAX_LOD_COUNT, MAX_INSTANCE_GROUPS> m_variantMatrix;
 	mutable SpinLock m_variantMatrixMtx;
 	mutable SpinLock m_variantMatrixMtx;
 
 
 	DynamicArray<MaterialVariable> m_vars; ///< Non-const vars.
 	DynamicArray<MaterialVariable> m_vars; ///< Non-const vars.

+ 1 - 1
src/anki/resource/Model.h

@@ -124,7 +124,7 @@ public:
 private:
 private:
 	Model* m_model ANKI_DBG_NULLIFY;
 	Model* m_model ANKI_DBG_NULLIFY;
 
 
-	Array<MeshResourcePtr, MAX_LOD> m_meshes; ///< One for each LOD
+	Array<MeshResourcePtr, MAX_LOD_COUNT> m_meshes; ///< One for each LOD
 	U8 m_meshCount = 0;
 	U8 m_meshCount = 0;
 	MaterialResourcePtr m_mtl;
 	MaterialResourcePtr m_mtl;
 
 

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

@@ -32,7 +32,7 @@ public:
 		, m_instanceCount(instanceCount)
 		, m_instanceCount(instanceCount)
 	{
 	{
 		ANKI_ASSERT(m_instanceCount <= MAX_INSTANCES && m_instanceCount != 0);
 		ANKI_ASSERT(m_instanceCount <= MAX_INSTANCES && m_instanceCount != 0);
-		ANKI_ASSERT(m_lod <= MAX_LOD);
+		ANKI_ASSERT(m_lod <= MAX_LOD_COUNT);
 	}
 	}
 
 
 	RenderingKey()
 	RenderingKey()

+ 22 - 29
src/anki/resource/ShaderProgramResource.cpp

@@ -244,6 +244,21 @@ Error ShaderProgramResource::load(const ResourceFilename& filename)
 				}
 				}
 			}
 			}
 
 
+			// instanced
+			Bool instancedPresent;
+			U32 instanced = 0;
+			ANKI_CHECK(mutatorEl.getAttributeNumberOptional("instanced", instanced, instancedPresent));
+			if(instanced)
+			{
+				if(m_instancingMutator)
+				{
+					ANKI_RESOURCE_LOGE("Cannot have more than one instancing mutator");
+					return ErrorCode::USER_DATA;
+				}
+
+				m_instancingMutator = &m_mutators[count];
+			}
+
 			// Init mutator
 			// Init mutator
 			m_mutators[count].m_name.create(getAllocator(), name);
 			m_mutators[count].m_name.create(getAllocator(), name);
 			m_mutators[count].m_values.create(getAllocator(), values.getSize());
 			m_mutators[count].m_values.create(getAllocator(), values.getSize());
@@ -550,38 +565,16 @@ Error ShaderProgramResource::parseInputs(XmlElement& inputsEl,
 			ANKI_ASSERT(mutatorCount == var.m_mutators.getSize());
 			ANKI_ASSERT(mutatorCount == var.m_mutators.getSize());
 		} // if(mutatorsEl)
 		} // if(mutatorsEl)
 
 
-		// instanceCount
-		CString instanceCountTxt;
+		// instanced
+		U32 instanced = false;
 		Bool found;
 		Bool found;
-		ANKI_CHECK(inputEl.getAttributeTextOptional("instanceCount", instanceCountTxt, found));
-		if(found)
+		ANKI_CHECK(inputEl.getAttributeNumberOptional("instanced", instanced, found));
+		if(instanced && !m_instancingMutator)
 		{
 		{
-			if(instanceCountTxt.isEmpty())
-			{
-				ANKI_RESOURCE_LOGE("instanceCount tag is empty for input variable %s", &name[0]);
-				return ErrorCode::USER_DATA;
-			}
-
-			var.m_instanced = true;
-			const ShaderProgramResourceMutator* instancingMutator = tryFindMutator(instanceCountTxt);
-			if(!instancingMutator)
-			{
-				ANKI_RESOURCE_LOGE("Failed to find mutator %s, used as instanceCount attribute for input variable %s",
-					&instanceCountTxt[0],
-					&name[0]);
-				return ErrorCode::USER_DATA;
-			}
-
-			if(!m_instancingMutator)
-			{
-				m_instancingMutator = instancingMutator;
-			}
-			else if(instancingMutator != m_instancingMutator)
-			{
-				ANKI_RESOURCE_LOGE("All input variables should have the same instancing mutator");
-				return ErrorCode::USER_DATA;
-			}
+			ANKI_RESOURCE_LOGE("Input variable \"%s\" is instanced but there is no instanced mutator", &name[0]);
+			return ErrorCode::USER_DATA;
 		}
 		}
+		var.m_instanced = instanced != 0;
 
 
 		// Sanity checks
 		// Sanity checks
 		if(var.isTexture() && var.m_const)
 		if(var.isTexture() && var.m_const)

+ 17 - 3
src/anki/resource/ShaderProgramResource.h

@@ -275,12 +275,12 @@ static_assert(sizeof(ShaderProgramResourceConstantValue) == sizeof(Vec4) * 2, "N
 /// @code
 /// @code
 /// <shaderProgram>
 /// <shaderProgram>
 /// 	[<mutators> (1)
 /// 	[<mutators> (1)
-/// 		<mutator name="str" values="array of ints"/>
+/// 		<mutator name="str" values="array of ints" [instanced="0 | 1"]/>
 /// 	</mutators>]
 /// 	</mutators>]
 ///
 ///
 ///		[<inputs> (3)
 ///		[<inputs> (3)
 ///			<input name="str" type="uint | int | float | vec2 | vec3 | vec4 | mat3 | mat4 | samplerXXX"
 ///			<input name="str" type="uint | int | float | vec2 | vec3 | vec4 | mat3 | mat4 | samplerXXX"
-///				[instanceCount="mutator name"] [const="0 | 1"]>
+///				[instanced="0 | 1"] [const="0 | 1"]>
 ///				[<mutators> (2)
 ///				[<mutators> (2)
 ///					<mutator name="variant_name" values="array of ints"/>
 ///					<mutator name="variant_name" values="array of ints"/>
 ///				</mutators>]
 ///				</mutators>]
@@ -292,7 +292,7 @@ static_assert(sizeof(ShaderProgramResourceConstantValue) == sizeof(Vec4) * 2, "N
 ///
 ///
 ///				[<inputs>
 ///				[<inputs>
 ///					<input name="str" type="uint | int | float | vec2 | vec3 | vec4 | mat3 | mat4 | samplerXXX"
 ///					<input name="str" type="uint | int | float | vec2 | vec3 | vec4 | mat3 | mat4 | samplerXXX"
-/// 					[instanceCount="mutator name"] [const="0 | 1"]>
+/// 					[instanced="0 | 1"] [const="0 | 1"]>
 /// 					[<mutators> (2)
 /// 					[<mutators> (2)
 /// 						<mutator name="variant_name" values="array of ints"/>
 /// 						<mutator name="variant_name" values="array of ints"/>
 /// 					</mutators>]
 /// 					</mutators>]
@@ -368,6 +368,15 @@ public:
 		getOrCreateVariant(WeakArray<const ShaderProgramResourceMutation>(), constants, variant);
 		getOrCreateVariant(WeakArray<const ShaderProgramResourceMutation>(), constants, variant);
 	}
 	}
 
 
+	/// Get or create a graphics shader program variant.
+	/// @note It's thread-safe.
+	void getOrCreateVariant(const ShaderProgramResourceVariant*& variant) const
+	{
+		getOrCreateVariant(WeakArray<const ShaderProgramResourceMutation>(),
+			WeakArray<const ShaderProgramResourceConstantValue>(),
+			variant);
+	}
+
 	Bool hasTessellation() const
 	Bool hasTessellation() const
 	{
 	{
 		return m_tessellation;
 		return m_tessellation;
@@ -378,6 +387,11 @@ public:
 		return m_instancingMutator != nullptr;
 		return m_instancingMutator != nullptr;
 	}
 	}
 
 
+	const ShaderProgramResourceMutator* getInstancingMutator() const
+	{
+		return m_instancingMutator;
+	}
+
 private:
 private:
 	DynamicArray<ShaderProgramResourceInputVariable> m_inputVars;
 	DynamicArray<ShaderProgramResourceInputVariable> m_inputVars;
 	DynamicArray<ShaderProgramResourceMutator> m_mutators;
 	DynamicArray<ShaderProgramResourceMutator> m_mutators;