Browse Source

Move tonemapping to the new system

Panagiotis Christopoulos Charitos 8 years ago
parent
commit
63713742ef

+ 17 - 4
shaders/TmAverageLuminance.comp.glsl → programs/TonemappingAverageLuminance.ankiprog

@@ -1,8 +1,17 @@
-// 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="comp">
+			<inputs>
+				<input name="INPUT_TEX_SIZE" type="uvec2" const="1"/>
+			</inputs>
 
+			<source><![CDATA[
 #include "shaders/Common.glsl"
 #include "shaders/Tonemapping.glsl"
 
@@ -78,3 +87,7 @@ void main()
 #endif
 	}
 }
+			]]></source>
+		</shader>
+	</shaders>
+</shaderProgram>

+ 10 - 9
src/anki/renderer/Tonemapping.cpp

@@ -24,15 +24,16 @@ Error Tonemapping::init(const ConfigSet& cfg)
 
 Error Tonemapping::initInternal(const ConfigSet& initializer)
 {
-	// Create shader
-	ANKI_CHECK(m_r->createShaderf("shaders/TmAverageLuminance.comp.glsl",
-		m_luminanceShader,
-		"#define INPUT_TEX_SIZE uvec2(%uu, %uu)\n",
-		m_r->getDownscaleBlur().getSmallPassWidth(),
-		m_r->getDownscaleBlur().getSmallPassHeight()));
+	// Create program
+	ANKI_CHECK(getResourceManager().loadResource("programs/TonemappingAverageLuminance.ankiprog", m_prog));
 
-	// Create prog
-	m_prog = getGrManager().newInstance<ShaderProgram>(m_luminanceShader->getGrShader());
+	ShaderProgramResourceConstantValueInitList<1> consts(m_prog);
+	consts.add("INPUT_TEX_SIZE",
+		UVec2(m_r->getDownscaleBlur().getSmallPassWidth(), m_r->getDownscaleBlur().getSmallPassHeight()));
+
+	const ShaderProgramResourceVariant* variant;
+	m_prog->getOrCreateVariant(consts.get(), variant);
+	m_grProg = variant->getProgram();
 
 	// Create buffer
 	m_luminanceBuff = getGrManager().newInstance<Buffer>(sizeof(Vec4),
@@ -61,7 +62,7 @@ Error Tonemapping::initInternal(const ConfigSet& initializer)
 void Tonemapping::run(RenderingContext& ctx)
 {
 	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
-	cmdb->bindShaderProgram(m_prog);
+	cmdb->bindShaderProgram(m_grProg);
 	cmdb->bindStorageBuffer(0, 0, m_luminanceBuff, 0, MAX_PTR_SIZE);
 	cmdb->bindTexture(0, 0, m_r->getDownscaleBlur().getSmallPassTexture());
 

+ 2 - 2
src/anki/renderer/Tonemapping.h

@@ -29,8 +29,8 @@ anki_internal:
 	void run(RenderingContext& ctx);
 
 private:
-	ShaderResourcePtr m_luminanceShader;
-	ShaderProgramPtr m_prog;
+	ShaderProgramResourcePtr m_prog;
+	ShaderProgramPtr m_grProg;
 
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& cfg);
 };

+ 52 - 16
src/anki/resource/ShaderProgramResource.cpp

@@ -127,6 +127,12 @@ static ANKI_USE_RESULT Error getShaderInfo(const CString& str, ShaderType& type,
 		bit = ShaderTypeBit::FRAGMENT;
 		idx = 4;
 	}
+	else if(str == "comp")
+	{
+		type = ShaderType::COMPUTE;
+		bit = ShaderTypeBit::COMPUTE;
+		idx = 5;
+	}
 	else
 	{
 		ANKI_RESOURCE_LOGE("Incorrect type %s", (str) ? &str[0] : "<empty string>");
@@ -324,7 +330,7 @@ Error ShaderProgramResource::load(const ResourceFilename& filename)
 	StringListAuto globalsSrcList(getTempAllocator());
 	StringListAuto definesSrcList(getTempAllocator());
 	ShaderTypeBit presentShaders = ShaderTypeBit::NONE;
-	Array<CString, 5> shaderSources;
+	Array<CString, U(ShaderType::COUNT)> shaderSources;
 	ANKI_CHECK(shadersEl.getChildElement("shader", shaderEl));
 	do
 	{
@@ -348,6 +354,11 @@ Error ShaderProgramResource::load(const ResourceFilename& filename)
 			m_tessellation = true;
 		}
 
+		if(!!(presentShaders & ShaderTypeBit::COMPUTE))
+		{
+			m_compute = true;
+		}
+
 		// <inputs>
 		XmlElement inputsEl;
 		ANKI_CHECK(shaderEl.getChildElementOptional("inputs", inputsEl));
@@ -375,16 +386,27 @@ Error ShaderProgramResource::load(const ResourceFilename& filename)
 	ANKI_ASSERT(inputVarCount == m_inputVars.getSize());
 
 	// Sanity checks
-	if(!(presentShaders & ShaderTypeBit::VERTEX))
+	if(!!(presentShaders & ShaderTypeBit::COMPUTE))
 	{
-		ANKI_RESOURCE_LOGE("Missing vertex shader");
-		return ErrorCode::USER_DATA;
+		if(presentShaders != ShaderTypeBit::COMPUTE)
+		{
+			ANKI_RESOURCE_LOGE("Can't combine compute shader with other types of shaders");
+			return ErrorCode::USER_DATA;
+		}
 	}
-
-	if(!(presentShaders & ShaderTypeBit::FRAGMENT))
+	else
 	{
-		ANKI_RESOURCE_LOGE("Missing fragment shader");
-		return ErrorCode::USER_DATA;
+		if(!(presentShaders & ShaderTypeBit::VERTEX))
+		{
+			ANKI_RESOURCE_LOGE("Missing vertex shader");
+			return ErrorCode::USER_DATA;
+		}
+
+		if(!(presentShaders & ShaderTypeBit::FRAGMENT))
+		{
+			ANKI_RESOURCE_LOGE("Missing fragment shader");
+			return ErrorCode::USER_DATA;
+		}
 	}
 
 	// Create sources
@@ -413,7 +435,7 @@ Error ShaderProgramResource::load(const ResourceFilename& filename)
 		definesSrcList.join("", backedDefinesSrc);
 	}
 
-	for(U s = 0; s < 5; ++s)
+	for(U s = 0; s < U(ShaderType::COUNT); ++s)
 	{
 		if(shaderSources[s])
 		{
@@ -574,6 +596,13 @@ Error ShaderProgramResource::parseInputs(XmlElement& inputsEl,
 			ANKI_RESOURCE_LOGE("Input variable \"%s\" is instanced but there is no instanced mutator", &name[0]);
 			return ErrorCode::USER_DATA;
 		}
+
+		if(instanced && m_compute)
+		{
+			ANKI_RESOURCE_LOGE("Compute program can't be instanced");
+			return ErrorCode::USER_DATA;
+		}
+
 		var.m_instanced = instanced != 0;
 
 		// Sanity checks
@@ -1022,8 +1051,8 @@ void ShaderProgramResource::initVariant(WeakArray<const ShaderProgramResourceMut
 	shaderHeaderSrc.join("", shaderHeader);
 
 	// Create the shaders and the program
-	Array<ShaderPtr, 5> shaders;
-	for(ShaderType i = ShaderType::FIRST_GRAPHICS; i <= ShaderType::LAST_GRAPHICS; ++i)
+	Array<ShaderPtr, U(ShaderType::COUNT)> shaders;
+	for(ShaderType i = ShaderType::FIRST; i < ShaderType::COUNT; ++i)
 	{
 		if(!m_sources[i])
 		{
@@ -1037,11 +1066,18 @@ void ShaderProgramResource::initVariant(WeakArray<const ShaderProgramResourceMut
 		shaders[i] = getManager().getGrManager().newInstance<Shader>(i, src.toCString());
 	}
 
-	variant.m_prog = getManager().getGrManager().newInstance<ShaderProgram>(shaders[ShaderType::VERTEX],
-		shaders[ShaderType::TESSELLATION_CONTROL],
-		shaders[ShaderType::TESSELLATION_EVALUATION],
-		shaders[ShaderType::GEOMETRY],
-		shaders[ShaderType::FRAGMENT]);
+	if(!m_compute)
+	{
+		variant.m_prog = getManager().getGrManager().newInstance<ShaderProgram>(shaders[ShaderType::VERTEX],
+			shaders[ShaderType::TESSELLATION_CONTROL],
+			shaders[ShaderType::TESSELLATION_EVALUATION],
+			shaders[ShaderType::GEOMETRY],
+			shaders[ShaderType::FRAGMENT]);
+	}
+	else
+	{
+		variant.m_prog = getManager().getGrManager().newInstance<ShaderProgram>(shaders[ShaderType::COMPUTE]);
+	}
 }
 
 } // end namespace anki

+ 2 - 1
src/anki/resource/ShaderProgramResource.h

@@ -404,12 +404,13 @@ private:
 	DynamicArray<ShaderProgramResourceInputVariable> m_inputVars;
 	DynamicArray<ShaderProgramResourceMutator> m_mutators;
 
-	Array<String, 5> m_sources;
+	Array<String, U(ShaderType::COUNT)> m_sources;
 
 	mutable IntrusiveHashMap<U64, ShaderProgramResourceVariant> m_variants;
 	mutable Mutex m_mtx;
 
 	Bool8 m_tessellation = false;
+	Bool8 m_compute = false;
 	const ShaderProgramResourceMutator* m_instancingMutator = nullptr;
 
 	/// Parse whatever is inside <inputs>