浏览代码

Tiler min/max is now a compute job

Panagiotis Christopoulos Charitos 10 年之前
父节点
当前提交
dadd36f09e

+ 7 - 2
include/anki/renderer/Common.h

@@ -7,15 +7,20 @@
 #define ANKI_RENDERER_COMMON_H
 
 #include "anki/Gr.h"
+#include "anki/util/Ptr.h"
 
 namespace anki {
 
 // Forward
+class Ms;
 class Fs;
-class Tm;
-class Bloom;
 class Lf;
+class Ssao;
+class Sslr;
 class Sslf;
+class Tm;
+class Bloom;
+class Pps;
 
 // Render target formats
 const U MS_COLOR_ATTACHMENTS_COUNT = 2;

+ 31 - 47
include/anki/renderer/Pps.h

@@ -7,27 +7,37 @@
 #define ANKI_RENDERER_PPS_H
 
 #include "anki/renderer/RenderingPass.h"
-#include "anki/Gr.h"
 #include "anki/resource/TextureResource.h"
 #include "anki/resource/Resource.h"
-#include "anki/renderer/Ssao.h"
-#include "anki/renderer/Bl.h"
-#include "anki/renderer/Sslr.h"
 
 namespace anki {
 
-class ShaderProgram;
-
 /// @addtogroup renderer
 /// @{
 
-/// Post-processing stage.This stage is divided into 2 two parts. The first
-/// happens before blending stage and the second after
+/// Post-processing stage.
 class Pps: public RenderingPass
 {
-	friend class Renderer;
-
 public:
+	Pps(Renderer* r);
+	~Pps();
+
+	/// @privatesection
+	/// @{
+	ANKI_USE_RESULT Error init(const ConfigSet& config);
+	ANKI_USE_RESULT Error run(CommandBufferHandle& jobs);
+
+	const TextureHandle& getRt() const
+	{
+		return m_rt;
+	}
+
+	TextureHandle& getRt()
+	{
+		return m_rt;
+	}
+	/// @}
+
 	const Bloom& getBloom() const
 	{
 		return *m_bloom;
@@ -40,29 +50,22 @@ public:
 
 	const Ssao& getSsao() const
 	{
-		return m_ssao;
-	}
-	Ssao& getSsao()
-	{
-		return m_ssao;
+		return *m_ssao;
 	}
 
-	const Bl& getBl() const
-	{
-		return m_bl;
-	}
-	Bl& getBl()
+	Ssao& getSsao()
 	{
-		return m_bl;
+		return *m_ssao;
 	}
 
 	const Sslr& getSslr() const
 	{
-		return m_sslr;
+		return *m_sslr;
 	}
+
 	Sslr& getSslr()
 	{
-		return m_sslr;
+		return *m_sslr;
 	}
 
 	const Tm& getTm() const
@@ -78,25 +81,12 @@ public:
 	/// Load the color grading texture.
 	Error loadColorGradingTexture(CString filename);
 
-	/// @privatesection
-	/// @{
-	const TextureHandle& _getRt() const
-	{
-		return m_rt;
-	}
-	TextureHandle& _getRt()
-	{
-		return m_rt;
-	}
-	/// @}
-
 private:
-	Tm* m_tm = nullptr;
-	Bloom* m_bloom;
-	Sslf* m_sslf;
-	Ssao m_ssao;
-	Bl m_bl;
-	Sslr m_sslr;
+	UniquePtr<Ssao> m_ssao;
+	UniquePtr<Sslr> m_sslr;
+	UniquePtr<Tm> m_tm;
+	UniquePtr<Bloom> m_bloom;
+	UniquePtr<Sslf> m_sslf;
 
 	FramebufferHandle m_fb;
 	ShaderResourcePointer m_frag;
@@ -105,12 +95,6 @@ private:
 
 	TextureResourcePointer m_lut; ///< Color grading lookup texture.
 
-	Pps(Renderer* r);
-	~Pps();
-
-	ANKI_USE_RESULT Error init(const ConfigSet& config);
-	ANKI_USE_RESULT Error run(CommandBufferHandle& jobs);
-
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& config);
 };
 /// @}

+ 7 - 0
include/anki/renderer/Renderer.h

@@ -38,6 +38,8 @@ public:
 	/// Cut the job submition into multiple chains. We want to avoid feeding
 	/// GL with a huge job chain
 	static const U32 JOB_CHAINS_COUNT = 2;
+
+	const U TILE_SIZE = 64;
 		
 	Renderer();
 
@@ -177,6 +179,11 @@ public:
 		return m_tilesCountXY;
 	}
 
+	UVec2 getTileSize() const
+	{
+		return UVec2(TILE_SIZE, TILE_SIZE);
+	}
+
 	const ShaderHandle& getDrawQuadVertexShader() const
 	{
 		return m_drawQuadVert->getGrShader();

+ 2 - 2
include/anki/renderer/RenderingPass.h

@@ -45,12 +45,12 @@ public:
 
 	Timestamp getGlobalTimestamp() const;
 
+	HeapAllocator<U8> getAllocator() const;
+
 protected:
 	Renderer* m_r; ///< Know your father
 	Bool8 m_enabled = false;
 
-	HeapAllocator<U8>& getAllocator();
-
 	GrManager& getGrManager();
 	const GrManager& getGrManager() const;
 

+ 15 - 10
include/anki/renderer/Ssao.h

@@ -21,15 +21,27 @@ namespace anki {
 /// Screen space ambient occlusion pass
 class Ssao: public RenderingPass
 {
-	friend class Pps;
-	friend class Sslr;
-	friend class MainRenderer;
+public:
+	/// @privatesection
+	/// @{
+	Ssao(Renderer* r)
+	:	RenderingPass(r)
+	{}
+
+	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
+	ANKI_USE_RESULT Error run(CommandBufferHandle& cmdBuff);
 
 	TextureHandle& _getRt()
 	{
 		return m_vblurRt;
 	}
 
+	BufferHandle& getUniformBuffer()
+	{
+		return m_uniformsBuff;
+	}
+	/// @}
+
 private:
 	U32 m_width, m_height; ///< Blur passes size
 	U8 m_blurringIterationsCount;
@@ -50,13 +62,6 @@ private:
 	BufferHandle m_uniformsBuff;
 	TextureHandle m_noiseTex;
 
-	Ssao(Renderer* r)
-	:	RenderingPass(r)
-	{}
-
-	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
-	ANKI_USE_RESULT Error run(CommandBufferHandle& cmdBuff);
-
 	ANKI_USE_RESULT Error createFb(
 		FramebufferHandle& fb, TextureHandle& rt);
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);

+ 3 - 2
include/anki/renderer/Sslf.h

@@ -17,12 +17,12 @@ namespace anki {
 class Sslf: public RenderingPass
 {
 public:
+	/// @privatesection
+	/// @{
 	Sslf(Renderer* r)
 	:	RenderingPass(r)
 	{}
 
-	~Sslf();
-
 	ANKI_USE_RESULT Error init(const ConfigSet& config);
 	void run(CommandBufferHandle& cmdb);
 
@@ -30,6 +30,7 @@ public:
 	{
 		return m_rt;
 	}
+	/// @}
 
 private:
 	TextureHandle m_rt;

+ 6 - 13
include/anki/renderer/Sslr.h

@@ -18,15 +18,15 @@ namespace anki {
 /// Screen space local reflections pass
 class Sslr: public BlurringRenderingPass
 {
-	friend class Pps;
-
 public:
 	/// @privatesection
 	/// @{
-	TextureHandle& _getRt()
-	{
-		return m_dirs[(U)DirectionEnum::VERTICAL].m_rt;
-	}
+	Sslr(Renderer* r)
+	:	BlurringRenderingPass(r)
+	{}
+
+	ANKI_USE_RESULT Error init(const ConfigSet& config);
+	ANKI_USE_RESULT Error run(CommandBufferHandle& cmdBuff);
 	/// @}
 
 private:
@@ -41,13 +41,6 @@ private:
 	// 2nd pass: blit
 	ShaderResourcePointer m_blitFrag;
 	PipelineHandle m_blitPpline;
-
-	Sslr(Renderer* r)
-	:	BlurringRenderingPass(r)
-	{}
-
-	ANKI_USE_RESULT Error init(const ConfigSet& config);
-	ANKI_USE_RESULT Error run(CommandBufferHandle& cmdBuff);
 };
 
 /// @}

+ 7 - 14
include/anki/renderer/Tiler.h

@@ -71,11 +71,10 @@ public:
 	Tiler(Renderer* r);
 	~Tiler();
 
-	Error init();
+	ANKI_USE_RESULT Error init();
 
 	/// Issue the GPU job
-	void runMinMax(TextureHandle& depthMap,
-		CommandBufferHandle& cmd);
+	void runMinMax(CommandBufferHandle& cmd);
 
 	/// Update the tiles before doing visibility tests
 	void updateTiles(Camera& cam);
@@ -86,9 +85,10 @@ public:
 
 	/// @privatesection
 	/// @{
-	TextureHandle& getRt()
+	BufferHandle& getTilesBuffer()
 	{
-		return m_rt;
+		U i = (getGlobalTimestamp() - m_pbos.getSize() + 1) % m_pbos.getSize();
+		return m_pbos[i];
 	}
 	/// @}
 
@@ -102,20 +102,13 @@ private:
 	SArray<Plane> m_nearPlanesW;
 	SArray<Plane> m_farPlanesW;
 
-	/// A texture of tilesXCount * tilesYCount size and format RG32UI. Used to
-	/// calculate the near and far planes of the tiles
-	TextureHandle m_rt;
-
-	/// Main FB for the fai
-	FramebufferHandle m_fb;
-
-	/// PBO buffer that is used to read the data of fai asynchronously
+	/// PBO buffer that is used to read the data
 	Array<BufferHandle, 2> m_pbos;
 	Array<Vec2*, 2> m_pbosAddress;
 	DArray<Vec2> m_prevMinMaxDepth;
 
 	/// Main shader program
-	ShaderResourcePointer m_frag;
+	ShaderResourcePointer m_shader;
 	PipelineHandle m_ppline;
 
 	/// Used to check if the camera is changed and we need to update the planes

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

@@ -14,7 +14,7 @@ namespace anki {
 /// @{
 
 /// Tonemapping.
-class Tm: private RenderingPass
+class Tm: public RenderingPass
 {
 public:
 	Tm(Renderer* r)

+ 145 - 8
include/anki/util/Ptr.h

@@ -19,22 +19,23 @@ template<typename T>
 class Ptr
 {
 public:
-	/// @name Constructors/Destructor
-	/// @{
 	Ptr()
-#if ANKI_ASSERTIONS == 1
-		: m_ptr(nullptr)
-#endif
+	:	m_ptr(nullptr)
 	{}
 
 	Ptr(T* ptr)
-		: m_ptr(ptr)
+	:	m_ptr(ptr)
 	{}
 
 	Ptr(const Ptr& other)
-		: m_ptr(other.m_ptr)
+	:	m_ptr(other.m_ptr)
 	{}
-	/// @}
+
+	Ptr(Ptr&& other)
+	:	m_ptr(other.m_ptr)
+	{
+		other.m_ptr = nullptr;
+	}
 
 	/// Copy
 	Ptr& operator=(const Ptr& other)
@@ -43,6 +44,14 @@ public:
 		return *this;
 	}
 
+	/// Move.
+	Ptr& operator=(Ptr&& other)
+	{
+		m_ptr = other.m_ptr;
+		other.m_ptr = nullptr;
+		return *this;
+	}
+
 	/// Dereference
 	T& operator*() const
 	{
@@ -59,6 +68,11 @@ public:
 
 	/// @name Compare operators
 	/// @{
+	operator bool() const 
+	{ 
+    	return m_ptr != nullptr; 
+	}
+
 	Bool operator==(const Ptr& other) const
 	{
 		return m_ptr == other.m_ptr;
@@ -139,6 +153,129 @@ private:
 	T* m_ptr;
 };
 
+/// UniquePtr default deleter.
+template<typename T>
+class UniquePtrDeleter
+{
+public:
+	void operator()(T* x)
+	{
+		auto alloc = x->getAllocator();
+		alloc.template deleteInstance<T>(x);
+	}
+};
+
+/// A unique pointer.
+template<typename T, typename TDeleter = UniquePtrDeleter<T>>
+class UniquePtr
+{
+public:
+	UniquePtr()
+	:	m_ptr(nullptr)
+	{}
+
+	explicit UniquePtr(T* ptr)
+	:	m_ptr(ptr)
+	{}
+
+	/// Non-copyable.
+	UniquePtr(const UniquePtr& other) = delete;
+
+	/// Move.
+	UniquePtr(UniquePtr&& other)
+	:	m_ptr(nullptr)
+	{
+		move(other);
+	}
+
+	/// Non-copyable.
+	UniquePtr& operator=(const UniquePtr& other) = delete;
+
+	/// Move.
+	UniquePtr& operator=(UniquePtr&& other)
+	{
+		move(other);
+		return *this;
+	}
+
+	/// Dereference
+	T& operator*() const
+	{
+		ANKI_ASSERT(m_ptr);
+		return *m_ptr;
+	}
+
+	/// Dereference
+	T* operator->() const
+	{
+		ANKI_ASSERT(m_ptr);
+		return m_ptr;
+	}
+
+	/// Set a new pointer. Will destroy the previous.
+	void reset(T* ptr)
+	{
+		destroy();
+		m_ptr = ptr;
+	}
+
+	/// @name Compare operators
+	/// @{
+	operator bool() const 
+	{ 
+    	return m_ptr != nullptr; 
+	}
+
+	Bool operator==(const UniquePtr& other) const
+	{
+		return m_ptr == other.m_ptr;
+	}
+
+	Bool operator!=(const UniquePtr& other) const
+	{
+		return m_ptr != other.m_ptr;
+	}
+
+	Bool operator<(const UniquePtr& other) const
+	{
+		return m_ptr < other.m_ptr;
+	}
+
+	Bool operator<=(const UniquePtr& other) const
+	{
+		return m_ptr <= other.m_ptr;
+	}
+
+	Bool operator>(const UniquePtr& other) const
+	{
+		return m_ptr > other.m_ptr;
+	}
+
+	Bool operator>=(const UniquePtr& other) const
+	{
+		return m_ptr >= other.m_ptr;
+	}
+	/// @}
+
+private:
+	T* m_ptr;
+
+	void destroy()
+	{
+		if(m_ptr)
+		{
+			TDeleter deleter;
+			deleter(m_ptr);
+			m_ptr = nullptr;
+		}
+	}
+
+	void move(UniquePtr& b)
+	{
+		reset(b.m_ptr);
+		b.m_ptr = nullptr;
+	}
+};
 /// @}
 
 } // end namespace anki

+ 84 - 0
shaders/TilerMinMax.comp.glsl

@@ -0,0 +1,84 @@
+// 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"
+
+const uint U32_MAX = 0xFFFFFFFFU;
+
+const uint WORKGROUP_SIZE_X = 16;
+const uint WORKGROUP_SIZE_Y = 16;
+
+const uint PIXEL_READ_X = TILE_SIZE_X / WORKGROUP_SIZE_X;
+const uint PIXEL_READ_Y = TILE_SIZE_Y / WORKGROUP_SIZE_Y;
+
+layout(binding = 0) uniform sampler2D u_depthMap;
+
+layout(std430, binding = 0) writeonly buffer _blk
+{
+	vec2 u_depthLimits[];
+};
+
+layout(
+	local_size_x = WORKGROUP_SIZE_X, 
+	local_size_y = WORKGROUP_SIZE_Y, 
+	local_size_z = 1) in;
+
+shared uvec2 g_minMaxDepth[PIXEL_READ_Y][PIXEL_READ_X];
+
+//==============================================================================
+void main()
+{
+	// Init
+	for(uint y = 0; y < PIXEL_READ_Y; ++y)
+	{
+		for(uint x = 0; x < PIXEL_READ_X; ++x)
+		{
+			g_minMaxDepth[y][x] = uvec2(U32_MAX, 0U);
+		}
+	}
+
+	memoryBarrierShared();
+	barrier();
+
+	// Get max/min depth
+	ivec2 coord = 
+		ivec2(gl_GlobalInvocationID.xy) * ivec2(PIXEL_READ_X, PIXEL_READ_Y);
+
+	for(uint y = 0; y < PIXEL_READ_Y; ++y)
+	{
+		for(uint x = 0; x < PIXEL_READ_X; ++x)
+		{
+			float depth = texelFetchOffset(u_depthMap, coord, 0, ivec2(x, y)).r;
+			uint udepth = uint(depth * float(U32_MAX));
+			atomicMin(g_minMaxDepth[y][x].x, udepth);
+			atomicMax(g_minMaxDepth[y][x].y, udepth);
+		}
+	}
+
+	memoryBarrierShared();
+	barrier();
+
+	// Write result
+	if(gl_LocalInvocationIndex == 0)
+	{
+		float mind = 1.0;
+		float maxd = 0.0;
+		for(uint y = 0; y < PIXEL_READ_Y; ++y)
+		{
+			for(uint x = 0; x < PIXEL_READ_X; ++x)
+			{
+				vec2 depthLimits = vec2(g_minMaxDepth[y][x]) / float(U32_MAX);
+				mind = min(mind, depthLimits.x);
+				maxd = max(maxd, depthLimits.y);
+			}
+		}
+
+		uint idx = gl_WorkGroupID.y * TILES_COUNT_X + gl_WorkGroupID.x;
+		u_depthLimits[idx] = vec2(mind, maxd);
+	}
+}
+
+

+ 0 - 40
shaders/TilerMinMax.frag.glsl

@@ -1,40 +0,0 @@
-// Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma anki type frag
-#pragma anki include "shaders/Common.glsl"
-
-uniform sampler2D u_depthMap;
-
-layout(location = 0) out vec2 out_color;
-
-layout(pixel_center_integer) in vec4 gl_FragCoord;
-
-#define W (RENDERER_WIDTH / TILES_X_COUNT)
-#define H (RENDERER_HEIGHT / TILES_Y_COUNT)
-
-//==============================================================================
-void main()
-{
-	ivec2 coord = ivec2(gl_FragCoord.xy * vec2(W, H));
-
-	float maxDepth = -10000.0;
-	float minDepth = 100000.0;
-
-	for(int x = 0; x < W; x++)
-	{
-		for(int y = 0; y < H; y++)
-		{
-			float depth = texelFetch(u_depthMap, coord + ivec2(x, y), 0).r;
-
-			minDepth = min(depth, minDepth);
-			maxDepth = max(depth, maxDepth);
-		}
-	}
-
-	out_color = vec2(minDepth, maxDepth);
-}
-
-

+ 1 - 1
src/renderer/Dbg.cpp

@@ -45,7 +45,7 @@ Error Dbg::init(const ConfigSet& initializer)
 	fbInit.m_depthStencilAttachment.m_texture = m_r->getMs()._getDepthRt();
 	if(m_r->getPps().getEnabled())
 	{
-		fbInit.m_colorAttachments[0].m_texture = m_r->getPps()._getRt();
+		fbInit.m_colorAttachments[0].m_texture = m_r->getPps().getRt();
 	}
 	else
 	{

+ 1 - 1
src/renderer/MainRenderer.cpp

@@ -87,7 +87,7 @@ Error MainRenderer::render(SceneGraph& scene)
 
 		if(getPps().getEnabled())
 		{
-			rt = &getPps()._getRt();
+			rt = &getPps().getRt();
 		}
 		else
 		{

+ 19 - 31
src/renderer/Pps.cpp

@@ -8,6 +8,7 @@
 #include "anki/renderer/Bloom.h"
 #include "anki/renderer/Sslf.h"
 #include "anki/renderer/Ssao.h"
+#include "anki/renderer/Sslr.h"
 #include "anki/renderer/Tm.h"
 #include "anki/renderer/Is.h"
 #include "anki/util/Logger.h"
@@ -17,27 +18,12 @@ namespace anki {
 
 //==============================================================================
 Pps::Pps(Renderer* r)
-:	RenderingPass(r), 
-	m_ssao(r), 
-	m_bl(r), 
-	m_sslr(r)
+:	RenderingPass(r)
 {}
 
 //==============================================================================
 Pps::~Pps()
-{
-	if(m_tm)
-	{
-		getAllocator().deleteInstance(m_tm);
-		m_tm = nullptr;
-	}
-
-	if(m_bloom)
-	{
-		getAllocator().deleteInstance(m_bloom);
-		m_bloom = nullptr;
-	}
-}
+{}
 
 //==============================================================================
 Error Pps::initInternal(const ConfigSet& config)
@@ -50,19 +36,21 @@ Error Pps::initInternal(const ConfigSet& config)
 
 	ANKI_ASSERT("Initializing PPS");
 
-	m_tm = getAllocator().newInstance<Tm>(m_r);
-	ANKI_CHECK(m_tm->create(config));
+	m_ssao.reset(getAllocator().newInstance<Ssao>(m_r));
+	ANKI_CHECK(m_ssao->init(config));
 
-	ANKI_CHECK(m_ssao.init(config));
+	m_sslr.reset(getAllocator().newInstance<Sslr>(m_r));
+	ANKI_CHECK(m_sslr->init(config));
 
-	m_bloom = getAllocator().newInstance<Bloom>(m_r);
+	m_tm.reset(getAllocator().newInstance<Tm>(m_r));
+	ANKI_CHECK(m_tm->create(config));
+
+	m_bloom.reset(getAllocator().newInstance<Bloom>(m_r));
 	ANKI_CHECK(m_bloom->init(config));
 
-	m_sslf = getAllocator().newInstance<Sslf>(m_r);
+	m_sslf.reset(getAllocator().newInstance<Sslf>(m_r));
 	ANKI_CHECK(m_sslf->init(config));
 
-	ANKI_CHECK(m_sslr.init(config));
-
 	// FBO
 	ANKI_CHECK(
 		m_r->createRenderTarget(
@@ -88,7 +76,7 @@ Error Pps::initInternal(const ConfigSet& config)
 		"#define GAMMA_CORRECTION_ENABLED %u\n"
 		"#define FBO_WIDTH %u\n"
 		"#define FBO_HEIGHT %u\n",
-		m_ssao.getEnabled(), 
+		m_ssao->getEnabled(), 
 		m_bloom->getEnabled(),
 		m_sslf->getEnabled(),
 		U(config.get("pps.sharpen")),
@@ -131,15 +119,15 @@ Error Pps::run(CommandBufferHandle& cmdb)
 	ANKI_ASSERT(m_enabled);
 
 	// First SSAO because it depends on MS where HDR depends on IS
-	if(m_ssao.getEnabled())
+	if(m_ssao->getEnabled())
 	{
-		ANKI_CHECK(m_ssao.run(cmdb));
+		ANKI_CHECK(m_ssao->run(cmdb));
 	}
 
 	// Then SSLR because HDR depends on it
-	if(m_sslr.getEnabled())
+	if(m_sslr->getEnabled())
 	{
-		ANKI_CHECK(m_sslr.run(cmdb));
+		ANKI_CHECK(m_sslr->run(cmdb));
 	}
 
 	m_r->getIs().generateMipmaps(cmdb);
@@ -177,9 +165,9 @@ Error Pps::run(CommandBufferHandle& cmdb)
 
 	m_r->getIs()._getRt().bind(cmdb, 0);
 
-	if(m_ssao.getEnabled())
+	if(m_ssao->getEnabled())
 	{
-		m_ssao._getRt().bind(cmdb, 1);
+		m_ssao->_getRt().bind(cmdb, 1);
 	}
 
 	if(m_bloom->getEnabled())

+ 1 - 3
src/renderer/Renderer.cpp

@@ -68,8 +68,6 @@ Error Renderer::init(
 Error Renderer::initInternal(const ConfigSet& config)
 {
 	// Set from the config
-	const U TILE_SIZE = 64;
-
 	m_renderingQuality = config.get("renderingQuality");
 	m_defaultFbWidth = config.get("width");
 	m_defaultFbHeight = config.get("height");
@@ -184,7 +182,7 @@ Error Renderer::render(SceneGraph& scene,
 
 	m_ms.generateMipmaps(cmdBuff[0]);
 
-	m_tiler.runMinMax(m_ms._getDepthRt(), cmdBuff[0]);
+	m_tiler.runMinMax(cmdBuff[0]);
 	cmdBuff[0].flush();
 
 	ANKI_COUNTER_START_TIMER(RENDERER_IS_TIME);

+ 1 - 1
src/renderer/RenderingPass.cpp

@@ -28,7 +28,7 @@ const GrManager& RenderingPass::getGrManager() const
 }
 
 //==============================================================================
-HeapAllocator<U8>& RenderingPass::getAllocator()
+HeapAllocator<U8> RenderingPass::getAllocator() const
 {
 	return m_r->_getAllocator();
 }

+ 2 - 1
src/renderer/Sslr.cpp

@@ -4,6 +4,7 @@
 // http://www.anki3d.org/LICENSE
 
 #include "anki/renderer/Sslr.h"
+#include "anki/renderer/Ssao.h"
 #include "anki/renderer/Renderer.h"
 #include "anki/misc/ConfigSet.h"
 
@@ -93,7 +94,7 @@ Error Sslr::run(CommandBufferHandle& cmdBuff)
 		m_r->getMs()._getRt1()}};
 	cmdBuff.bindTextures(0	, tarr.begin(), tarr.getSize()); 
 
-	m_r->getPps().getSsao().m_uniformsBuff.bindShaderBuffer(cmdBuff, 0);
+	m_r->getPps().getSsao().getUniformBuffer().bindShaderBuffer(cmdBuff, 0);
 
 	m_r->drawQuad(cmdBuff);
 

+ 22 - 37
src/renderer/Tiler.cpp

@@ -84,35 +84,22 @@ Error Tiler::initInternal()
 	StringAuto pps(getAllocator());
 
 	pps.sprintf(
-		"#define TILES_X_COUNT %u\n"
-		"#define TILES_Y_COUNT %u\n"
-		"#define RENDERER_WIDTH %u\n"
-		"#define RENDERER_HEIGHT %u\n",
+		"#define TILE_SIZE_X %u\n"
+		"#define TILE_SIZE_Y %u\n"
+		"#define TILES_COUNT_X %u\n"
+		"#define TILES_COUNT_Y %u\n",
+		m_r->getTileSize().x(),
+		m_r->getTileSize().y(),
 		m_r->getTilesCount().x(),
-		m_r->getTilesCount().y(),
-		m_r->getWidth(),
-		m_r->getHeight());
+		m_r->getTilesCount().y());
 
 	ANKI_CHECK(
-		m_frag.loadToCache(&getResourceManager(), 
-		"shaders/TilerMinMax.frag.glsl", pps.toCString(), "r_"));
+		m_shader.loadToCache(&getResourceManager(), 
+		"shaders/TilerMinMax.comp.glsl", pps.toCString(), "r_"));
 
-	ANKI_CHECK(
-		m_r->createDrawQuadPipeline(m_frag->getGrShader(), m_ppline));
-
-	// Create FB
-	ANKI_CHECK(
-		m_r->createRenderTarget(m_r->getTilesCount().x(), 
-		m_r->getTilesCount().y(), 
-		PixelFormat(ComponentFormat::R32G32, TransformFormat::UINT), 
-		1, SamplingFilter::NEAREST, 1, m_rt));
-
-	FramebufferHandle::Initializer fbInit;
-	fbInit.m_colorAttachmentsCount = 1;
-	fbInit.m_colorAttachments[0].m_texture = m_rt;
-	fbInit.m_colorAttachments[0].m_loadOperation = 
-		AttachmentLoadOperation::DONT_CARE;
-	ANKI_CHECK(m_fb.create(&getGrManager(), fbInit));
+	PipelineHandle::Initializer pplineInit;
+	pplineInit.m_shaders[U(ShaderType::COMPUTE)] = m_shader->getGrShader();
+	ANKI_CHECK(m_ppline.create(&getGrManager(), pplineInit));
 
 	// Init planes. One plane for each direction, plus near/far plus the world
 	// space of those
@@ -166,8 +153,8 @@ Error Tiler::initPbos()
 	for(U i = 0; i < m_pbos.getSize(); ++i)
 	{
 		ANKI_CHECK(
-			m_pbos[i].create(&getGrManager(), GL_PIXEL_PACK_BUFFER, nullptr, 
-			pboSize,
+			m_pbos[i].create(&getGrManager(), GL_SHADER_STORAGE_BUFFER, 
+			nullptr, pboSize,
 			GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT));
 	}
 
@@ -182,23 +169,21 @@ Error Tiler::initPbos()
 }
 
 //==============================================================================
-void Tiler::runMinMax(TextureHandle& depthMap,
-	CommandBufferHandle& cmd)
+void Tiler::runMinMax(CommandBufferHandle& cmd)
 {
 	if(m_enableGpuTests)
 	{
 		// Issue the min/max job
-		m_fb.bind(cmd);
+		U pboIdx = getGlobalTimestamp() % m_pbos.getSize();
+		m_pbos[pboIdx].bindShaderBuffer(cmd, 0);
 		m_ppline.bind(cmd);
-		depthMap.bind(cmd, 0);
-		cmd.setViewport(
-			0, 0, m_r->getTilesCount().x(), m_r->getTilesCount().y());
 
-		m_r->drawQuad(cmd);
+		m_r->getMs()._getDepthRt().bind(cmd, 0);
 
-		// Issue the async pixel read
-		U pboIdx = getGlobalTimestamp() % m_pbos.getSize();
-		cmd.copyTextureToBuffer(m_rt, m_pbos[pboIdx]);
+		cmd.dispatchCompute(
+			m_r->getTilesCount().x(), m_r->getTilesCount().y(), 1);
+
+		m_r->drawQuad(cmd);
 	}
 }
 

+ 1 - 1
testapp/Main.cpp

@@ -41,7 +41,7 @@ App* app;
 ModelNode* horse;
 PerspectiveCamera* cam;
 
-#define NO_PLAYER 1
+#define NO_PLAYER 0
 
 
 //==============================================================================