Browse Source

Tonemapping work

Panagiotis Christopoulos Charitos 10 years ago
parent
commit
869617b168

+ 1 - 1
include/anki/gr/BufferHandle.h

@@ -24,7 +24,7 @@ public:
 	~BufferHandle();
 
 	/// Create the buffer with data
-	ANKI_USE_RESULT Error create(CommandBufferHandle& commands, GLenum target, 
+	ANKI_USE_RESULT Error create(GrManager* manager, GLenum target, 
 		const void* data, PtrSize size, GLbitfield flags);
 
 	/// Get buffer size. It may serialize 

+ 1 - 3
include/anki/gr/PipelineHandle.h

@@ -25,9 +25,7 @@ public:
 	~PipelineHandle();
 
 	/// Create a pipeline
-	ANKI_USE_RESULT Error create(
-		CommandBufferHandle& commands,
-		const Initializer& init);
+	ANKI_USE_RESULT Error create(GrManager* manager, const Initializer& init);
 
 	/// Bind it to the state
 	void bind(CommandBufferHandle& commands);

+ 1 - 1
include/anki/gr/gl/RenderingThread.h

@@ -15,7 +15,7 @@ namespace anki {
 /// @addtogroup opengl
 /// @{
 
-#define ANKI_DISABLE_GL_RENDERING_THREAD 1
+#define ANKI_DISABLE_GL_RENDERING_THREAD 0
 
 /// Command queue. It's essentialy a queue of command buffers waiting for 
 /// execution and a server

+ 1 - 0
include/anki/renderer/Common.h

@@ -12,6 +12,7 @@ namespace anki {
 
 // Forward
 class Fs;
+class Tm;
 
 // Render target formats
 const U MS_COLOR_ATTACHMENTS_COUNT = 2;

+ 2 - 0
include/anki/renderer/Is.h

@@ -42,6 +42,8 @@ class Is: private RenderingPass
 	friend class WriteLightsTask;
 
 public:
+	static const U MIPMAPS_COUNT = 7;
+
 	/// @privatesection
 	/// @{
 	TextureHandle& _getRt()

+ 2 - 4
include/anki/renderer/Lf.h

@@ -77,10 +77,8 @@ private:
 
 	ANKI_USE_RESULT Error initPseudo(
 		const ConfigSet& config, CommandBufferHandle& cmdBuff);
-	ANKI_USE_RESULT Error initSprite(
-		const ConfigSet& config, CommandBufferHandle& cmdBuff);
-	ANKI_USE_RESULT Error initOcclusion(
-		const ConfigSet& config, CommandBufferHandle& cmdBuff);
+	ANKI_USE_RESULT Error initSprite(const ConfigSet& config);
+	ANKI_USE_RESULT Error initOcclusion(const ConfigSet& config);
 
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
 };

+ 1 - 1
include/anki/renderer/Pps.h

@@ -91,6 +91,7 @@ public:
 	/// @}
 
 private:
+	Tm* m_tm = nullptr;
 	Hdr m_hdr;
 	Ssao m_ssao;
 	Bl m_bl;
@@ -112,7 +113,6 @@ private:
 
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& config);
 };
-
 /// @}
 
 } // end namespace anki

+ 1 - 0
include/anki/renderer/RenderingPass.h

@@ -6,6 +6,7 @@
 #ifndef ANKI_RENDERER_RENDERING_PASS_H
 #define ANKI_RENDERER_RENDERING_PASS_H
 
+#include "anki/renderer/Common.h"
 #include "anki/util/StdTypes.h"
 #include "anki/Gr.h"
 #include "anki/core/Timestamp.h"

+ 5 - 2
include/anki/renderer/Tm.h

@@ -21,11 +21,14 @@ public:
 	:	RenderingPass(r)
 	{}
 
-	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
+	ANKI_USE_RESULT Error create(const ConfigSet& initializer);
+
+	ANKI_USE_RESULT Error run(CommandBufferHandle& cmdb);
 
 private:
-	BufferHandle m_luminanceBuff;
 	ShaderResourcePointer m_avgLuminanceShader;
+	PipelineHandle m_avgLuminancePpline;
+	BufferHandle m_luminanceBuff;
 };
 
 } // end namespace anki

+ 0 - 6
shaders/PpsTm.comp.glsl

@@ -1,6 +0,0 @@
-// Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-

+ 80 - 0
shaders/PpsTmAverageLuminance.comp.glsl

@@ -0,0 +1,80 @@
+// Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma anki type comp
+#pragma anki include "shaders/Common.glsl"
+
+#if IS_RT_MIPMAP == 0
+#	error Wrong mipmap
+#endif
+
+const uint WORKGROUP_SIZE_X = 16u;
+const uint WORKGROUP_SIZE_Y = 16u;
+const uint WORKGROUP_SIZE = WORKGROUP_SIZE_X * WORKGROUP_SIZE_Y;
+
+layout(
+	local_size_x = WORKGROUP_SIZE_X, 
+	local_size_y = WORKGROUP_SIZE_Y, 
+	local_size_z = 1) in;
+
+const uint MIPMAP_WIDTH = ANKI_RENDERER_WIDTH / (2u << (IS_RT_MIPMAP - 1u));
+const uint MIPMAP_HEIGHT = ANKI_RENDERER_WIDTH / (2u << (IS_RT_MIPMAP - 1u));
+
+const uint PIXEL_READ_X = MIPMAP_WIDTH / WORKGROUP_SIZE_X;
+const uint PIXEL_READ_Y = MIPMAP_HEIGHT / WORKGROUP_SIZE_Y;
+
+layout(binding = 0) uniform sampler2D u_isRt;
+
+layout(std140, binding = 0) buffer _blk
+{
+	vec4 u_averageLuminancePad3;
+};
+
+shared float g_avgLum[WORKGROUP_SIZE];
+
+void main()
+{
+	// Gather the average luminance of a tile
+	float avgLum = 0.0;
+	uint yStart = gl_LocalInvocationID.y * PIXEL_READ_Y;
+	uint yEnd = yStart + PIXEL_READ_Y;
+	uint xStart = gl_LocalInvocationID.x * PIXEL_READ_X;
+	uint xEnd = xStart + PIXEL_READ_X;
+	for(uint y = yStart; y < yEnd; ++y)
+	{		
+		for(uint x = xStart; x < xEnd; ++x)
+		{
+			vec3 color = texelFetch(u_isRt, ivec2(x, y), IS_RT_MIPMAP).rgb;
+			float lum = dot(vec3(0.30, 0.59, 0.11), color);
+			const float DELTA = 0.000001;
+			avgLum += log(DELTA + lum);
+		}
+	}
+
+	avgLum *= 1.0 / float(PIXEL_READ_X * PIXEL_READ_Y);
+	g_avgLum[gl_LocalInvocationIndex] = avgLum;
+
+	memoryBarrierShared();
+	barrier();
+
+	// Gather the results into one
+	for(uint s = WORKGROUP_SIZE / 2u; s > 0u; s >>= 1u)
+	{
+		if(gl_LocalInvocationIndex < s)
+		{
+			g_avgLum[gl_LocalInvocationIndex] += 
+				g_avgLum[gl_LocalInvocationIndex + s];
+		}
+
+		memoryBarrierShared();
+		barrier();
+	}
+
+	// Write the result
+	if(gl_LocalInvocationIndex == 0)
+	{
+		u_averageLuminancePad3.x = exp(g_avgLum[0]) / float(WORKGROUP_SIZE);
+	}
+}

+ 8 - 6
src/gr/gl/BufferHandle.cpp

@@ -202,32 +202,34 @@ BufferHandle::~BufferHandle()
 {}
 
 //==============================================================================
-Error BufferHandle::create(CommandBufferHandle& commands,
+Error BufferHandle::create(GrManager* manager,
 	GLenum target, const void* data, PtrSize size, GLenum flags)
 {
 	ANKI_ASSERT(!isCreated());
 
 	using DeleteCommand = DeleteObjectCommand<BufferImpl>;
-
 	using Deleter = DeferredDeleter<BufferImpl, DeleteCommand>;
 
-	Base::create(commands.get().getManager(), Deleter());
+	CommandBufferHandle cmdb;
+	ANKI_CHECK(cmdb.create(manager));
+
+	Base::create(cmdb.get().getManager(), Deleter());
 	get().setStateAtomically(GlObject::State::TO_BE_CREATED);
 
 	// Allocate temp memory for the data
 	Bool cleanup = false;
 	if(data)
 	{
-		void* newData = 
-			commands.get().getInternalAllocator().allocate(size);
+		void* newData = cmdb.get().getInternalAllocator().allocate(size);
 		memcpy(newData, data, size);
 		data = newData;
 		cleanup = true;
 	}
 
 	// Fire the command
-	commands.get().pushBackNewCommand<BufferCreateCommand>(
+	cmdb.get().pushBackNewCommand<BufferCreateCommand>(
 		*this, target, data, size, flags, cleanup);
+	cmdb.flush();
 
 	return ErrorCode::NONE;
 }

+ 8 - 5
src/gr/gl/PipelineHandle.cpp

@@ -78,16 +78,19 @@ PipelineHandle::~PipelineHandle()
 {}
 
 //==============================================================================
-Error PipelineHandle::create(
-	CommandBufferHandle& commands,
-	const Initializer& init)
+Error PipelineHandle::create(GrManager* manager, const Initializer& init)
 {
 	using DeleteCommand = DeleteObjectCommand<PipelineImpl>;
 	using Deleter = DeferredDeleter<PipelineImpl, DeleteCommand>;
 
-	Base::create(commands.get().getManager(), Deleter());
+	CommandBufferHandle cmdb;
+	ANKI_CHECK(cmdb.create(manager));
+
+	Base::create(cmdb.get().getManager(), Deleter());
 	get().setStateAtomically(GlObject::State::TO_BE_CREATED);
-	commands.get().pushBackNewCommand<CreatePipelineCommand>(*this, init);
+	cmdb.get().pushBackNewCommand<CreatePipelineCommand>(*this, init);
+
+	cmdb.flush();
 
 	return ErrorCode::NONE;
 }

+ 15 - 39
src/renderer/DebugDrawer.cpp

@@ -29,52 +29,28 @@ DebugDrawer::~DebugDrawer()
 //==============================================================================
 Error DebugDrawer::create(Renderer* r)
 {
-	Error err = ErrorCode::NONE;
-
 	GrManager& gl = r->_getGrManager();
 
-	err = m_vert.load("shaders/Dbg.vert.glsl", &r->_getResourceManager());
-
-	if(!err)
-	{
-		err = m_frag.load("shaders/Dbg.frag.glsl", &r->_getResourceManager());
-	}
-
-	CommandBufferHandle jobs;
-
-	if(!err)
-	{
-		err = jobs.create(&gl);
-	}
-
-	if(!err)
-	{
-		PipelineHandle::Initializer init;
-		init.m_shaders[U(ShaderType::VERTEX)] = m_vert->getGrShader();
-		init.m_shaders[U(ShaderType::FRAGMENT)] = m_frag->getGrShader();
+	ANKI_CHECK(m_vert.load("shaders/Dbg.vert.glsl", &r->_getResourceManager()));
+	ANKI_CHECK(m_frag.load("shaders/Dbg.frag.glsl", &r->_getResourceManager()));
 
-		err = m_ppline.create(jobs, init);
-	}
+	PipelineHandle::Initializer init;
+	init.m_shaders[U(ShaderType::VERTEX)] = m_vert->getGrShader();
+	init.m_shaders[U(ShaderType::FRAGMENT)] = m_frag->getGrShader();
 
-	if(!err)
-	{
-		err = m_vertBuff.create(jobs, GL_ARRAY_BUFFER, nullptr,
-			sizeof(m_clientLineVerts), GL_DYNAMIC_STORAGE_BIT);
-	}
+	ANKI_CHECK(m_ppline.create(&gl, init));
 
-	if(!err)
-	{
-		m_lineVertCount = 0;
-		m_triVertCount = 0;
-		m_mMat.setIdentity();
-		m_vpMat.setIdentity();
-		m_mvpMat.setIdentity();
-		m_crntCol = Vec3(1.0, 0.0, 0.0);
+	ANKI_CHECK(m_vertBuff.create(&gl, GL_ARRAY_BUFFER, nullptr,
+			sizeof(m_clientLineVerts), GL_DYNAMIC_STORAGE_BIT));
 
-		jobs.finish();
-	}
+	m_lineVertCount = 0;
+	m_triVertCount = 0;
+	m_mMat.setIdentity();
+	m_vpMat.setIdentity();
+	m_mvpMat.setIdentity();
+	m_crntCol = Vec3(1.0, 0.0, 0.0);
 
-	return err;
+	return ErrorCode::NONE;
 }
 
 //==============================================================================

+ 2 - 7
src/renderer/Drawer.cpp

@@ -233,15 +233,10 @@ Error RenderableDrawer::create(Renderer* r)
 	m_r = r;
 
 	// Create the uniform buffer
-	CommandBufferHandle cmdBuff;
-	ANKI_CHECK(cmdBuff.create(&m_r->_getGrManager()));
-
-	ANKI_CHECK(m_uniformBuff.create(cmdBuff, GL_UNIFORM_BUFFER, nullptr,
-		MAX_UNIFORM_BUFFER_SIZE,
+	ANKI_CHECK(m_uniformBuff.create(&m_r->_getGrManager(), GL_UNIFORM_BUFFER, 
+		nullptr, MAX_UNIFORM_BUFFER_SIZE,
 		GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT));
 
-	cmdBuff.flush();
-
 	m_uniformPtr = static_cast<U8*>(
 		m_uniformBuff.getPersistentMappingAddress());
 	m_uniformBuffMapAddr = m_uniformPtr;

+ 3 - 3
src/renderer/Hdr.cpp

@@ -64,12 +64,12 @@ Error Hdr::initInternal(const ConfigSet& initializer)
 
 	// init shaders
 	GrManager& gl = getGrManager();
-	CommandBufferHandle cmdb;
-	ANKI_CHECK(cmdb.create(&gl));
 
-	ANKI_CHECK(m_commonBuff.create(cmdb, GL_UNIFORM_BUFFER, nullptr,
+	ANKI_CHECK(m_commonBuff.create(&gl, GL_UNIFORM_BUFFER, nullptr,
 		sizeof(Vec4), GL_DYNAMIC_STORAGE_BIT));
 
+	CommandBufferHandle cmdb;
+	ANKI_CHECK(cmdb.create(&gl));
 	updateDefaultBlock(cmdb);
 
 	cmdb.flush();

+ 11 - 10
src/renderer/Is.cpp

@@ -211,7 +211,7 @@ Error Is::initInternal(const ConfigSet& config)
 	PipelineHandle::Initializer init;
 		init.m_shaders[U(ShaderType::VERTEX)] = m_lightVert->getGrShader();
 		init.m_shaders[U(ShaderType::FRAGMENT)] = m_lightFrag->getGrShader();
-	ANKI_CHECK(m_lightPpline.create(cmdBuff, init));
+	ANKI_CHECK(m_lightPpline.create(&getGrManager(), init));
 
 	//
 	// Create framebuffer
@@ -221,7 +221,7 @@ Error Is::initInternal(const ConfigSet& config)
 		m_r->getWidth(), m_r->getHeight(), 
 		PixelFormat(ComponentFormat::R11G11B10, TransformFormat::FLOAT), 
 		//PixelFormat(ComponentFormat::R8G8B8, TransformFormat::UNORM), 
-		1, SamplingFilter::LINEAR, 7, m_rt));
+		1, SamplingFilter::LINEAR, MIPMAPS_COUNT, m_rt));
 
 	FramebufferHandle::Initializer fbInit;
 	fbInit.m_colorAttachmentsCount = 1;
@@ -236,29 +236,30 @@ Error Is::initInternal(const ConfigSet& config)
 	static const F32 quadVertCoords[][2] = 
 		{{1.0, 1.0}, {0.0, 1.0}, {1.0, 0.0}, {0.0, 0.0}};
 
-	ANKI_CHECK(m_quadPositionsVertBuff.create(cmdBuff, GL_ARRAY_BUFFER, 
+	ANKI_CHECK(m_quadPositionsVertBuff.create(&getGrManager(), GL_ARRAY_BUFFER, 
 		&quadVertCoords[0][0], sizeof(quadVertCoords), 0));
 
 	//
 	// Create UBOs
 	//
-	ANKI_CHECK(m_commonBuffer.create(cmdBuff, GL_UNIFORM_BUFFER, nullptr,
-		sizeof(shader::CommonUniforms), GL_DYNAMIC_STORAGE_BIT));
+	ANKI_CHECK(m_commonBuffer.create(&getGrManager(), GL_UNIFORM_BUFFER, 
+		nullptr, sizeof(shader::CommonUniforms), GL_DYNAMIC_STORAGE_BIT));
 
 	for(U i = 0; i < MAX_FRAMES; ++i)
 	{
 		// Lights
-		ANKI_CHECK(m_lightsBuffers[i].create(cmdBuff, GL_SHADER_STORAGE_BUFFER, 
-			nullptr, calcLightsBufferSize(), 
+		ANKI_CHECK(m_lightsBuffers[i].create(&getGrManager(), 
+			GL_SHADER_STORAGE_BUFFER, nullptr, calcLightsBufferSize(), 
 			GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT));
 
 		// Tiles
-		ANKI_CHECK(m_tilesBuffers[i].create(cmdBuff, GL_SHADER_STORAGE_BUFFER,
-			nullptr, m_r->getTilesCountXY() * sizeof(shader::Tile),
+		ANKI_CHECK(m_tilesBuffers[i].create(&getGrManager(), 
+			GL_SHADER_STORAGE_BUFFER, nullptr, 
+			m_r->getTilesCountXY() * sizeof(shader::Tile),
 			GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT));
 
 		// Index
-		ANKI_CHECK(m_lightIdsBuffers[i].create(cmdBuff, 
+		ANKI_CHECK(m_lightIdsBuffers[i].create(&getGrManager(), 
 			GL_SHADER_STORAGE_BUFFER,
 			nullptr, (m_maxPointLights * m_maxSpotLights * m_maxSpotTexLights)
 			* sizeof(U32),

+ 9 - 11
src/renderer/Lf.cpp

@@ -83,8 +83,7 @@ Error Lf::initPseudo(const ConfigSet& config,
 }
 
 //==============================================================================
-Error Lf::initSprite(const ConfigSet& config, 
-	CommandBufferHandle& cmdBuff)
+Error Lf::initSprite(const ConfigSet& config)
 {
 	// Load program + ppline
 	StringAuto pps(getAllocator());
@@ -100,7 +99,7 @@ Error Lf::initSprite(const ConfigSet& config,
 	PipelineHandle::Initializer init;
 	init.m_shaders[U(ShaderType::VERTEX)] = m_realVert->getGrShader();
 	init.m_shaders[U(ShaderType::FRAGMENT)] = m_realFrag->getGrShader();
-	ANKI_CHECK(m_realPpline.create(cmdBuff, init));
+	ANKI_CHECK(m_realPpline.create(&getGrManager(), init));
 
 	// Create buffer
 	PtrSize uboAlignment = 
@@ -112,7 +111,7 @@ Error Lf::initSprite(const ConfigSet& config,
 	for(U i = 0; i < m_flareDataBuff.getSize(); ++i)
 	{
 		ANKI_CHECK(m_flareDataBuff[i].create(
-			cmdBuff, GL_UNIFORM_BUFFER, nullptr, blockSize, 
+			&getGrManager(), GL_UNIFORM_BUFFER, nullptr, blockSize, 
 			GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT));
 	}
 
@@ -120,8 +119,7 @@ Error Lf::initSprite(const ConfigSet& config,
 }
 
 //==============================================================================
-Error Lf::initOcclusion(
-	const ConfigSet& config, CommandBufferHandle& cmdBuff)
+Error Lf::initOcclusion(const ConfigSet& config)
 {
 	// Init vert buff
 	U buffSize = sizeof(Vec3) * m_maxFlares;
@@ -129,12 +127,12 @@ Error Lf::initOcclusion(
 	for(U i = 0; i < m_positionsVertBuff.getSize(); ++i)
 	{
 		ANKI_CHECK(m_positionsVertBuff[i].create(
-			cmdBuff, GL_ARRAY_BUFFER, nullptr, buffSize, 
+			&getGrManager(), GL_ARRAY_BUFFER, nullptr, buffSize, 
 			GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT));
 	}
 
 	// Init MVP buff
-	ANKI_CHECK(m_mvpBuff.create(cmdBuff, GL_UNIFORM_BUFFER, 
+	ANKI_CHECK(m_mvpBuff.create(&getGrManager(), GL_UNIFORM_BUFFER, 
 		nullptr, sizeof(Mat4), GL_DYNAMIC_STORAGE_BIT));
 
 	// Shaders
@@ -148,7 +146,7 @@ Error Lf::initOcclusion(
 		init.m_shaders[U(ShaderType::VERTEX)] = m_occlusionVert->getGrShader();
 		init.m_shaders[U(ShaderType::FRAGMENT)] = 
 			m_occlusionFrag->getGrShader();
-	ANKI_CHECK(m_occlusionPpline.create(cmdBuff, init));
+	ANKI_CHECK(m_occlusionPpline.create(&getGrManager(), init));
 
 	return ErrorCode::NONE;
 }
@@ -167,8 +165,8 @@ Error Lf::initInternal(const ConfigSet& config)
 	ANKI_CHECK(cmdBuff.create(&getGrManager()));
 
 	ANKI_CHECK(initPseudo(config, cmdBuff));
-	ANKI_CHECK(initSprite(config, cmdBuff));
-	ANKI_CHECK(initOcclusion(config, cmdBuff));
+	ANKI_CHECK(initSprite(config));
+	ANKI_CHECK(initOcclusion(config));
 
 	// Create the render target
 	ANKI_CHECK(m_r->createRenderTarget(m_r->getPps().getHdr()._getWidth(), 

+ 11 - 1
src/renderer/Pps.cpp

@@ -7,6 +7,7 @@
 #include "anki/renderer/Renderer.h"
 #include "anki/renderer/Hdr.h"
 #include "anki/renderer/Ssao.h"
+#include "anki/renderer/Tm.h"
 #include "anki/util/Logger.h"
 #include "anki/misc/ConfigSet.h"
 
@@ -24,7 +25,13 @@ Pps::Pps(Renderer* r)
 
 //==============================================================================
 Pps::~Pps()
-{}
+{
+	if(m_tm)
+	{
+		getAllocator().deleteInstance(m_tm);
+		m_tm = nullptr;
+	}
+}
 
 //==============================================================================
 Error Pps::initInternal(const ConfigSet& config)
@@ -37,6 +44,9 @@ Error Pps::initInternal(const ConfigSet& config)
 
 	ANKI_ASSERT("Initializing PPS");
 
+	m_tm = getAllocator().newInstance<Tm>(m_r);
+	ANKI_CHECK(m_tm->create(config));
+
 	ANKI_CHECK(m_ssao.init(config));
 	ANKI_CHECK(m_hdr.init(config));
 	ANKI_CHECK(m_lf.init(config));

+ 5 - 18
src/renderer/Renderer.cpp

@@ -118,7 +118,7 @@ Error Renderer::initInternal(const ConfigSet& config)
 	CommandBufferHandle cmdBuff;
 	ANKI_CHECK(cmdBuff.create(m_gl));
 
-	ANKI_CHECK(m_quadPositionsBuff.create(cmdBuff, GL_ARRAY_BUFFER, 
+	ANKI_CHECK(m_quadPositionsBuff.create(m_gl, GL_ARRAY_BUFFER, 
 		&quadVertCoords[0][0], sizeof(quadVertCoords), 0));
 
 	ANKI_CHECK(m_drawQuadVert.load("shaders/Quad.vert.glsl", m_resources));
@@ -289,24 +289,11 @@ Error Renderer::createRenderTarget(U32 w, U32 h, const PixelFormat& format,
 Error Renderer::createDrawQuadPipeline(
 	ShaderHandle frag, PipelineHandle& ppline)
 {
-	CommandBufferHandle cmdBuff;
-	Error err = cmdBuff.create(m_gl);
-
-	if(!err)
-	{
-		PipelineHandle::Initializer init;
-		init.m_shaders[U(ShaderType::VERTEX)] = m_drawQuadVert->getGrShader();
-		init.m_shaders[U(ShaderType::FRAGMENT)] = frag;
-
-		err = ppline.create(cmdBuff, init);
-	}
+	PipelineHandle::Initializer init;
+	init.m_shaders[U(ShaderType::VERTEX)] = m_drawQuadVert->getGrShader();
+	init.m_shaders[U(ShaderType::FRAGMENT)] = frag;
 
-	if(!err)
-	{
-		cmdBuff.finish();
-	}
-
-	return err;
+	return ppline.create(m_gl, init);
 }
 
 } // end namespace anki

+ 1 - 1
src/renderer/Ssao.cpp

@@ -165,7 +165,7 @@ Error Ssao::initInternal(const ConfigSet& config)
 	//
 	// Shaders
 	//
-	ANKI_CHECK(m_uniformsBuff.create(cmdb, GL_SHADER_STORAGE_BUFFER, 
+	ANKI_CHECK(m_uniformsBuff.create(&getGrManager(), GL_SHADER_STORAGE_BUFFER, 
 		nullptr, sizeof(ShaderCommonUniforms), GL_DYNAMIC_STORAGE_BIT));
 
 	StringAuto pps(getAllocator());

+ 3 - 8
src/renderer/Tiler.cpp

@@ -164,11 +164,6 @@ Error Tiler::initInternal()
 //==============================================================================
 Error Tiler::initPbos()
 {
-	Error err = ErrorCode::NONE;
-
-	CommandBufferHandle cmd;
-	ANKI_CHECK(cmd.create(&getGrManager()));
-
 	// Allocate the buffers
 	U pboSize = m_r->getTilesCount().x() * m_r->getTilesCount().y();
 	pboSize *= sizeof(Vec2); // The pixel size
@@ -176,10 +171,10 @@ Error Tiler::initPbos()
 	for(U i = 0; i < m_pbos.getSize(); ++i)
 	{
 		ANKI_CHECK(
-			m_pbos[i].create(cmd, GL_PIXEL_PACK_BUFFER, nullptr, pboSize,
+			m_pbos[i].create(&getGrManager(), GL_PIXEL_PACK_BUFFER, nullptr, 
+			pboSize,
 			GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT));
 	}
-	cmd.flush();
 
 	// Get persistent address
 	for(U i = 0; i < m_pbos.getSize(); ++i)
@@ -188,7 +183,7 @@ Error Tiler::initPbos()
 			static_cast<Vec2*>(m_pbos[i].getPersistentMappingAddress());
 	}
 
-	return err;
+	return ErrorCode::NONE;
 }
 
 //==============================================================================

+ 34 - 1
src/renderer/Tm.cpp

@@ -4,12 +4,45 @@
 // http://www.anki3d.org/LICENSE
 
 #include "anki/renderer/Tm.h"
+#include "anki/renderer/Is.h"
+#include "anki/renderer/Renderer.h"
 
 namespace anki {
 
 //==============================================================================
-Error Tm::init(const ConfigSet& initializer)
+Error Tm::create(const ConfigSet& initializer)
 {
+	// Create shader
+	StringAuto pps(getAllocator());
+
+	pps.sprintf(
+		"#define IS_RT_MIPMAP %u\n"
+		"#define ANKI_RENDERER_WIDTH %u\n"
+		"#define ANKI_RENDERER_HEIGHT %u\n",
+		Is::MIPMAPS_COUNT,
+		m_r->getWidth(),
+		m_r->getHeight());
+
+	ANKI_CHECK(m_avgLuminanceShader.loadToCache(&getResourceManager(), 
+		"shaders/PpsTmAverageLuminance.comp.glsl", pps.toCString(), "rppstm_"));
+
+	// Create ppline
+	PipelineHandle::Initializer pplineInit;
+	pplineInit.m_shaders[U(ShaderType::COMPUTE)] = 
+		m_avgLuminanceShader->getGrShader();
+	ANKI_CHECK(m_avgLuminancePpline.create(&getGrManager(), pplineInit));
+
+	// Create buffer
+	ANKI_CHECK(m_luminanceBuff.create(&getGrManager(), GL_UNIFORM_BUFFER,
+		nullptr, sizeof(Vec4), GL_DYNAMIC_STORAGE_BIT));
+
+	return ErrorCode::NONE;
+}
+
+//==============================================================================
+Error Tm::run(CommandBufferHandle& cmdb)
+{
+
 	return ErrorCode::NONE;
 }
 

+ 1 - 7
src/resource/Material.cpp

@@ -338,13 +338,7 @@ Error Material::getProgramPipeline(
 		pplineInit.m_shaders[U(ShaderType::FRAGMENT)] = 
 			getProgram(key, ShaderType::FRAGMENT)->getGrShader();
 
-		GrManager& gl = m_resources->getGrManager();
-		CommandBufferHandle cmdBuff;
-		ANKI_CHECK(cmdBuff.create(&gl));
-
-		ANKI_CHECK(ppline.create(cmdBuff, pplineInit));
-
-		cmdBuff.flush();
+		ANKI_CHECK(ppline.create(&m_resources->getGrManager(), pplineInit));
 	}
 
 	out = ppline;

+ 5 - 24
src/resource/Mesh.cpp

@@ -65,36 +65,17 @@ Error Mesh::load(const CString& filename, ResourceInitializer& init)
 Error Mesh::createBuffers(const MeshLoader& loader,
 	ResourceInitializer& init)
 {
-	Error err = ErrorCode::NONE;
-
 	GrManager& gr = init.m_resources.getGrManager();
-	CommandBufferHandle cmdb;
-	err = cmdb.create(&gr);
-	if(err)
-	{
-		return err;
-	}
 
 	// Create vertex buffer
-	err = m_vertBuff.create(cmdb, GL_ARRAY_BUFFER, loader.getVertexData(), 
-		loader.getVertexDataSize(), 0);
-	if(err)
-	{
-		return err;
-	}
+	ANKI_CHECK(m_vertBuff.create(&gr, GL_ARRAY_BUFFER, loader.getVertexData(), 
+		loader.getVertexDataSize(), 0));
 
 	// Create index buffer
-	err = m_indicesBuff.create(
-		cmdb, GL_ELEMENT_ARRAY_BUFFER, loader.getIndexData(), 
-		loader.getIndexDataSize(), 0);
-	if(err)
-	{
-		return err;
-	}
+	ANKI_CHECK(m_indicesBuff.create(&gr, GL_ELEMENT_ARRAY_BUFFER, 
+		loader.getIndexData(), loader.getIndexDataSize(), 0));
 
-	cmdb.flush();
-
-	return err;
+	return ErrorCode::NONE;
 }
 
 //==============================================================================

+ 2 - 6
src/scene/ParticleEmitter.cpp

@@ -336,15 +336,11 @@ Error ParticleEmitter::create(
 	}
 
 	// Create the vertex buffer and object
-	CommandBufferHandle cmd;
-	GrManager& gr = getSceneGraph().getGrManager();
-	ANKI_CHECK(cmd.create(&gr));
-
 	PtrSize buffSize = m_maxNumOfParticles * VERT_SIZE * 3;
-	ANKI_CHECK(m_vertBuff.create(cmd, GL_ARRAY_BUFFER, nullptr, buffSize, 
+	ANKI_CHECK(m_vertBuff.create(&getSceneGraph().getGrManager(), 
+		GL_ARRAY_BUFFER, nullptr, buffSize, 
 		GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT));
 
-	cmd.finish(); /// TODO Optimize serialization
 	m_vertBuffMapping = 
 		static_cast<U8*>(m_vertBuff.getPersistentMappingAddress());