Browse Source

Add half rez depth to remove some barriers. SSAO much slower

Panagiotis Christopoulos Charitos 9 years ago
parent
commit
9c67fe18b4

+ 21 - 0
shaders/HalfDepth.frag.glsl

@@ -0,0 +1,21 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include "shaders/Common.glsl"
+
+layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_depthRt;
+
+layout(location = 0) in vec2 in_uv;
+
+void main()
+{
+	vec4 depths = textureGather(u_depthRt, in_uv, 0);
+
+	float mind = min(depths.x, depths.y);
+	mind = min(mind, depths.z);
+	mind = min(mind, depths.w);
+
+	gl_FragDepth = mind;
+}

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

@@ -29,6 +29,7 @@ class Ir;
 class Upsample;
 class Upsample;
 class DownscaleBlur;
 class DownscaleBlur;
 class Volumetric;
 class Volumetric;
+class HalfDepth;
 
 
 class RenderingContext;
 class RenderingContext;
 class DebugDrawer;
 class DebugDrawer;

+ 3 - 3
src/anki/renderer/Fs.cpp

@@ -8,6 +8,7 @@
 #include <anki/renderer/Ms.h>
 #include <anki/renderer/Ms.h>
 #include <anki/renderer/Is.h>
 #include <anki/renderer/Is.h>
 #include <anki/renderer/Sm.h>
 #include <anki/renderer/Sm.h>
+#include <anki/renderer/HalfDepth.h>
 #include <anki/scene/SceneGraph.h>
 #include <anki/scene/SceneGraph.h>
 #include <anki/scene/FrustumComponent.h>
 #include <anki/scene/FrustumComponent.h>
 
 
@@ -37,17 +38,16 @@ Error Fs::init(const ConfigSet&)
 	fbInit.m_colorAttachments[0].m_texture = m_rt;
 	fbInit.m_colorAttachments[0].m_texture = m_rt;
 	fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::CLEAR;
 	fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::CLEAR;
 	fbInit.m_colorAttachments[0].m_usageInsideRenderPass = TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE;
 	fbInit.m_colorAttachments[0].m_usageInsideRenderPass = TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE;
-	fbInit.m_depthStencilAttachment.m_texture = m_r->getMs().getDepthRt();
+	fbInit.m_depthStencilAttachment.m_texture = m_r->getHalfDepth().m_depthRt;
 	fbInit.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::LOAD;
 	fbInit.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::LOAD;
 	fbInit.m_depthStencilAttachment.m_usageInsideRenderPass =
 	fbInit.m_depthStencilAttachment.m_usageInsideRenderPass =
 		TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ;
 		TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ;
-	fbInit.m_depthStencilAttachment.m_surface.m_level = 1;
 	m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
 	m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
 
 
 	// Init the global resources
 	// Init the global resources
 	{
 	{
 		ResourceGroupInitInfo init;
 		ResourceGroupInitInfo init;
-		init.m_textures[0].m_texture = m_r->getMs().getDepthRt();
+		init.m_textures[0].m_texture = m_r->getHalfDepth().m_depthRt;
 		init.m_textures[0].m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ;
 		init.m_textures[0].m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ;
 		init.m_textures[1].m_texture = m_r->getSm().getSpotTextureArray();
 		init.m_textures[1].m_texture = m_r->getSm().getSpotTextureArray();
 		init.m_textures[2].m_texture = m_r->getSm().getOmniTextureArray();
 		init.m_textures[2].m_texture = m_r->getSm().getOmniTextureArray();

+ 80 - 0
src/anki/renderer/HalfDepth.cpp

@@ -0,0 +1,80 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <anki/renderer/HalfDepth.h>
+#include <anki/renderer/Renderer.h>
+#include <anki/renderer/Ms.h>
+
+namespace anki
+{
+
+HalfDepth::~HalfDepth()
+{
+}
+
+Error HalfDepth::init(const ConfigSet&)
+{
+	GrManager& gr = getGrManager();
+	U width = m_r->getWidth() / 2;
+	U height = m_r->getHeight() / 2;
+
+	// Create shader
+	ANKI_CHECK(getResourceManager().loadResource("shaders/HalfDepth.frag.glsl", m_frag));
+
+	// Create pipeline
+	PipelineInitInfo pinit;
+
+	pinit.m_inputAssembler.m_topology = PrimitiveTopology::TRIANGLE_STRIP;
+
+	pinit.m_depthStencil.m_depthWriteEnabled = true;
+	pinit.m_depthStencil.m_depthCompareFunction = CompareOperation::ALWAYS;
+	pinit.m_depthStencil.m_format = MS_DEPTH_ATTACHMENT_PIXEL_FORMAT;
+
+	pinit.m_shaders[ShaderType::VERTEX] = m_r->getDrawQuadVertexShader();
+	pinit.m_shaders[ShaderType::FRAGMENT] = m_frag->getGrShader();
+	m_ppline = gr.newInstance<Pipeline>(pinit);
+
+	// Create RT
+	m_r->createRenderTarget(width,
+		height,
+		MS_DEPTH_ATTACHMENT_PIXEL_FORMAT,
+		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE | TextureUsageBit::SAMPLED_FRAGMENT,
+		SamplingFilter::LINEAR,
+		1,
+		m_depthRt);
+
+	// Create FB
+	FramebufferInitInfo fbInit;
+	fbInit.m_depthStencilAttachment.m_texture = m_depthRt;
+	fbInit.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::DONT_CARE;
+	fbInit.m_depthStencilAttachment.m_usageInsideRenderPass = TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE;
+
+	m_fb = gr.newInstance<Framebuffer>(fbInit);
+
+	// Create RC group
+	ResourceGroupInitInfo rcinit;
+	rcinit.m_textures[0].m_texture = m_r->getMs().getDepthRt();
+	rcinit.m_textures[0].m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ;
+
+	m_rcgroup = gr.newInstance<ResourceGroup>(rcinit);
+
+	return ErrorCode::NONE;
+}
+
+void HalfDepth::run(RenderingContext& ctx)
+{
+	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
+
+	cmdb->beginRenderPass(m_fb);
+	cmdb->setViewport(0, 0, m_r->getWidth() / 2, m_r->getHeight() / 2);
+	cmdb->bindPipeline(m_ppline);
+	cmdb->bindResourceGroup(m_rcgroup, 0, nullptr);
+
+	m_r->drawQuad(cmdb);
+
+	cmdb->endRenderPass();
+}
+
+} // end namespace anki

+ 44 - 0
src/anki/renderer/HalfDepth.h

@@ -0,0 +1,44 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <anki/renderer/RenderingPass.h>
+#include <anki/Gr.h>
+#include <anki/resource/TextureResource.h>
+#include <anki/resource/ShaderResource.h>
+
+namespace anki
+{
+
+/// @addtogroup renderer
+/// @{
+
+// Quick pass to downscale the depth buffer.
+class HalfDepth : public RenderingPass
+{
+anki_internal:
+	TexturePtr m_depthRt;
+
+	HalfDepth(Renderer* r)
+		: RenderingPass(r)
+	{
+	}
+
+	~HalfDepth();
+
+	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
+
+	void run(RenderingContext& ctx);
+
+private:
+	ShaderResourcePtr m_frag;
+	PipelinePtr m_ppline;
+	ResourceGroupPtr m_rcgroup;
+	FramebufferPtr m_fb;
+};
+/// @}
+
+} // end namespace

+ 1 - 0
src/anki/renderer/Is.cpp

@@ -143,6 +143,7 @@ Error Is::initInternal(const ConfigSet& config)
 		init.m_textures[1].m_texture = m_r->getMs().getRt1();
 		init.m_textures[1].m_texture = m_r->getMs().getRt1();
 		init.m_textures[2].m_texture = m_r->getMs().getRt2();
 		init.m_textures[2].m_texture = m_r->getMs().getRt2();
 		init.m_textures[3].m_texture = m_r->getMs().getDepthRt();
 		init.m_textures[3].m_texture = m_r->getMs().getDepthRt();
+		init.m_textures[3].m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ;
 		init.m_textures[4].m_texture = m_r->getSm().getSpotTextureArray();
 		init.m_textures[4].m_texture = m_r->getSm().getSpotTextureArray();
 		init.m_textures[5].m_texture = m_r->getSm().getOmniTextureArray();
 		init.m_textures[5].m_texture = m_r->getSm().getOmniTextureArray();
 
 

+ 5 - 3
src/anki/renderer/Ms.cpp

@@ -28,7 +28,7 @@ Error Ms::createRt(U32 samples)
 		TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE
 		TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE
 			| TextureUsageBit::GENERATE_MIPMAPS,
 			| TextureUsageBit::GENERATE_MIPMAPS,
 		SamplingFilter::NEAREST,
 		SamplingFilter::NEAREST,
-		getDepthRtMipmapCount(),
+		1,
 		m_depthRt);
 		m_depthRt);
 
 
 	m_r->createRenderTarget(m_r->getWidth(),
 	m_r->createRenderTarget(m_r->getWidth(),
@@ -200,8 +200,10 @@ void Ms::setPostRunBarriers(RenderingContext& ctx)
 	cmdb->setTextureSurfaceBarrier(
 	cmdb->setTextureSurfaceBarrier(
 		m_rt2, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureUsageBit::SAMPLED_FRAGMENT, surf);
 		m_rt2, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureUsageBit::SAMPLED_FRAGMENT, surf);
 
 
-	cmdb->setTextureSurfaceBarrier(
-		m_depthRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, TextureUsageBit::SAMPLED_FRAGMENT, surf);
+	cmdb->setTextureSurfaceBarrier(m_depthRt,
+		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
+		TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ,
+		surf);
 
 
 	ANKI_TRACE_STOP_EVENT(RENDER_MS);
 	ANKI_TRACE_STOP_EVENT(RENDER_MS);
 }
 }

+ 0 - 5
src/anki/renderer/Ms.h

@@ -60,11 +60,6 @@ anki_internal:
 		return m_fb;
 		return m_fb;
 	}
 	}
 
 
-	static U getDepthRtMipmapCount()
-	{
-		return log2(SSAO_FRACTION) + 1;
-	}
-
 private:
 private:
 	FramebufferPtr m_fb;
 	FramebufferPtr m_fb;
 
 

+ 18 - 16
src/anki/renderer/Renderer.cpp

@@ -25,6 +25,7 @@
 #include <anki/renderer/Upsample.h>
 #include <anki/renderer/Upsample.h>
 #include <anki/renderer/DownscaleBlur.h>
 #include <anki/renderer/DownscaleBlur.h>
 #include <anki/renderer/Volumetric.h>
 #include <anki/renderer/Volumetric.h>
+#include <anki/renderer/HalfDepth.h>
 
 
 namespace anki
 namespace anki
 {
 {
@@ -143,6 +144,9 @@ Error Renderer::initInternal(const ConfigSet& config)
 	m_is.reset(m_alloc.newInstance<Is>(this));
 	m_is.reset(m_alloc.newInstance<Is>(this));
 	ANKI_CHECK(m_is->init(config));
 	ANKI_CHECK(m_is->init(config));
 
 
+	m_hd.reset(m_alloc.newInstance<HalfDepth>(this));
+	ANKI_CHECK(m_hd->init(config));
+
 	m_fs.reset(m_alloc.newInstance<Fs>(this));
 	m_fs.reset(m_alloc.newInstance<Fs>(this));
 	ANKI_CHECK(m_fs->init(config));
 	ANKI_CHECK(m_fs->init(config));
 
 
@@ -231,6 +235,12 @@ Error Renderer::render(RenderingContext& ctx)
 	m_ssao->setPreRunBarriers(ctx);
 	m_ssao->setPreRunBarriers(ctx);
 	m_bloom->setPreRunBarriers(ctx);
 	m_bloom->setPreRunBarriers(ctx);
 
 
+	cmdb->setTextureSurfaceBarrier(m_hd->m_depthRt,
+		TextureUsageBit::NONE,
+		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
+		TextureSurfaceInfo(0, 0, 0, 0));
+
+	// SM
 	m_sm->run(ctx);
 	m_sm->run(ctx);
 
 
 	m_ms->run(ctx);
 	m_ms->run(ctx);
@@ -238,27 +248,19 @@ Error Renderer::render(RenderingContext& ctx)
 	m_ms->setPostRunBarriers(ctx);
 	m_ms->setPostRunBarriers(ctx);
 	m_sm->setPostRunBarriers(ctx);
 	m_sm->setPostRunBarriers(ctx);
 
 
+	// Batch IS + HD
 	m_is->run(ctx);
 	m_is->run(ctx);
-
-	cmdb->setTextureSurfaceBarrier(m_ms->getDepthRt(),
-		TextureUsageBit::SAMPLED_FRAGMENT,
-		TextureUsageBit::GENERATE_MIPMAPS,
-		TextureSurfaceInfo(0, 0, 0, 0));
-
-	cmdb->generateMipmaps2d(m_ms->getDepthRt(), 0, 0);
-
-	for(U i = 0; i < m_ms->getDepthRtMipmapCount(); ++i)
-	{
-		cmdb->setTextureSurfaceBarrier(m_ms->getDepthRt(),
-			TextureUsageBit::GENERATE_MIPMAPS,
-			TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ,
-			TextureSurfaceInfo(i, 0, 0, 0));
-	}
+	m_hd->run(ctx);
 
 
 	m_lf->updateIndirectInfo(ctx, cmdb);
 	m_lf->updateIndirectInfo(ctx, cmdb);
 
 
-	m_fs->run(ctx);
+	cmdb->setTextureSurfaceBarrier(m_hd->m_depthRt,
+		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
+		TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ,
+		TextureSurfaceInfo(0, 0, 0, 0));
 
 
+	// Batch FS & SSAO
+	m_fs->run(ctx);
 	m_ssao->run(ctx);
 	m_ssao->run(ctx);
 
 
 	m_ssao->setPostRunBarriers(ctx);
 	m_ssao->setPostRunBarriers(ctx);

+ 6 - 0
src/anki/renderer/Renderer.h

@@ -154,6 +154,11 @@ public:
 		return *m_is;
 		return *m_is;
 	}
 	}
 
 
+	HalfDepth& getHalfDepth()
+	{
+		return *m_hd;
+	}
+
 	Fs& getFs()
 	Fs& getFs()
 	{
 	{
 		return *m_fs;
 		return *m_fs;
@@ -368,6 +373,7 @@ private:
 	UniquePtr<Sm> m_sm; ///< Shadow mapping.
 	UniquePtr<Sm> m_sm; ///< Shadow mapping.
 	UniquePtr<Ms> m_ms; ///< Material rendering stage
 	UniquePtr<Ms> m_ms; ///< Material rendering stage
 	UniquePtr<Is> m_is; ///< Illumination rendering stage
 	UniquePtr<Is> m_is; ///< Illumination rendering stage
+	UniquePtr<HalfDepth> m_hd;
 	UniquePtr<Fs> m_fs; ///< Forward shading.
 	UniquePtr<Fs> m_fs; ///< Forward shading.
 	UniquePtr<Volumetric> m_vol; ///< Volumetric effects.
 	UniquePtr<Volumetric> m_vol; ///< Volumetric effects.
 	UniquePtr<Lf> m_lf; ///< Forward shading lens flares.
 	UniquePtr<Lf> m_lf; ///< Forward shading lens flares.

+ 2 - 1
src/anki/renderer/Ssao.cpp

@@ -6,6 +6,7 @@
 #include <anki/renderer/Ssao.h>
 #include <anki/renderer/Ssao.h>
 #include <anki/renderer/Renderer.h>
 #include <anki/renderer/Renderer.h>
 #include <anki/renderer/Ms.h>
 #include <anki/renderer/Ms.h>
+#include <anki/renderer/HalfDepth.h>
 #include <anki/scene/SceneGraph.h>
 #include <anki/scene/SceneGraph.h>
 #include <anki/util/Functions.h>
 #include <anki/util/Functions.h>
 #include <anki/misc/ConfigSet.h>
 #include <anki/misc/ConfigSet.h>
@@ -219,7 +220,7 @@ Error Ssao::initInternal(const ConfigSet& config)
 	sinit.m_mipmapFilter = SamplingFilter::NEAREST;
 	sinit.m_mipmapFilter = SamplingFilter::NEAREST;
 	sinit.m_repeat = false;
 	sinit.m_repeat = false;
 
 
-	rcinit.m_textures[0].m_texture = m_r->getMs().getDepthRt();
+	rcinit.m_textures[0].m_texture = m_r->getHalfDepth().m_depthRt;
 	rcinit.m_textures[0].m_sampler = gr.newInstance<Sampler>(sinit);
 	rcinit.m_textures[0].m_sampler = gr.newInstance<Sampler>(sinit);
 	rcinit.m_textures[0].m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ;
 	rcinit.m_textures[0].m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ;
 
 

+ 2 - 2
src/anki/renderer/Upsample.cpp

@@ -9,6 +9,7 @@
 #include <anki/renderer/Is.h>
 #include <anki/renderer/Is.h>
 #include <anki/renderer/Fs.h>
 #include <anki/renderer/Fs.h>
 #include <anki/renderer/Ssao.h>
 #include <anki/renderer/Ssao.h>
+#include <anki/renderer/HalfDepth.h>
 #include <anki/scene/FrustumComponent.h>
 #include <anki/scene/FrustumComponent.h>
 
 
 namespace anki
 namespace anki
@@ -26,9 +27,8 @@ Error Upsample::init(const ConfigSet& config)
 	rcInit.m_textures[0].m_texture = m_r->getMs().getDepthRt();
 	rcInit.m_textures[0].m_texture = m_r->getMs().getDepthRt();
 	rcInit.m_textures[0].m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ;
 	rcInit.m_textures[0].m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ;
 
 
-	sinit.m_minLod = 1.0;
 	sinit.m_mipmapFilter = SamplingFilter::NEAREST;
 	sinit.m_mipmapFilter = SamplingFilter::NEAREST;
-	rcInit.m_textures[1].m_texture = m_r->getMs().getDepthRt();
+	rcInit.m_textures[1].m_texture = m_r->getHalfDepth().m_depthRt;
 	rcInit.m_textures[1].m_sampler = gr.newInstance<Sampler>(sinit);
 	rcInit.m_textures[1].m_sampler = gr.newInstance<Sampler>(sinit);
 	rcInit.m_textures[1].m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ;
 	rcInit.m_textures[1].m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ;
 
 

+ 2 - 2
src/anki/renderer/Volumetric.cpp

@@ -5,7 +5,7 @@
 
 
 #include <anki/renderer/Volumetric.h>
 #include <anki/renderer/Volumetric.h>
 #include <anki/renderer/Renderer.h>
 #include <anki/renderer/Renderer.h>
-#include <anki/renderer/Ms.h>
+#include <anki/renderer/HalfDepth.h>
 #include <anki/scene/FrustumComponent.h>
 #include <anki/scene/FrustumComponent.h>
 
 
 namespace anki
 namespace anki
@@ -37,7 +37,7 @@ Error Volumetric::init(const ConfigSet& config)
 
 
 	// Create the resource group
 	// Create the resource group
 	ResourceGroupInitInfo rcInit;
 	ResourceGroupInitInfo rcInit;
-	rcInit.m_textures[0].m_texture = m_r->getMs().getDepthRt();
+	rcInit.m_textures[0].m_texture = m_r->getHalfDepth().m_depthRt;
 	rcInit.m_textures[0].m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ;
 	rcInit.m_textures[0].m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ;
 	rcInit.m_uniformBuffers[0].m_uploadedMemory = true;
 	rcInit.m_uniformBuffers[0].m_uploadedMemory = true;
 	rcInit.m_uniformBuffers[0].m_usage = BufferUsageBit::UNIFORM_FRAGMENT;
 	rcInit.m_uniformBuffers[0].m_usage = BufferUsageBit::UNIFORM_FRAGMENT;