Browse Source

Forward shading in half resolution

Panagiotis Christopoulos Charitos 10 years ago
parent
commit
b68d4478d1

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

@@ -26,10 +26,7 @@ class Dbg;
 class Tiler;
 class Tiler;
 class Ir;
 class Ir;
 class Refl;
 class Refl;
-
-/// Cut the job submition into multiple chains. We want to avoid feeding
-/// GL with a huge job chain
-const U RENDERER_COMMAND_BUFFERS_COUNT = 2;
+class Upsample;
 
 
 /// Computes the 'a' and 'b' numbers for linearizeDepthOptimal
 /// Computes the 'a' and 'b' numbers for linearizeDepthOptimal
 inline void computeLinearizeDepthOptimal(F32 near, F32 far, F32& a, F32& b)
 inline void computeLinearizeDepthOptimal(F32 near, F32 far, F32& a, F32& b)

+ 5 - 3
include/anki/renderer/Ir.h

@@ -121,12 +121,14 @@ private:
 	void binProbes(U32 threadId, PtrSize threadsCount, IrRunContext& ctx);
 	void binProbes(U32 threadId, PtrSize threadsCount, IrRunContext& ctx);
 
 
 	ANKI_USE_RESULT Error writeProbeAndRender(
 	ANKI_USE_RESULT Error writeProbeAndRender(
-		SceneNode& node, IrShaderReflectionProbe& probe);
+		SceneNode& node, IrShaderReflectionProbe& probe, CommandBufferPtr cmdb);
 
 
 	void binProbe(U probeIdx, IrRunContext& ctx, IrTaskContext& task) const;
 	void binProbe(U probeIdx, IrRunContext& ctx, IrTaskContext& task) const;
 
 
-	ANKI_USE_RESULT Error renderReflection(
-		SceneNode& node, ReflectionProbeComponent& reflc, U cubemapIdx);
+	ANKI_USE_RESULT Error renderReflection(SceneNode& node,
+		ReflectionProbeComponent& reflc,
+		U cubemapIdx,
+		CommandBufferPtr cmdb);
 
 
 	static void writeIndicesAndCluster(
 	static void writeIndicesAndCluster(
 		U clusterIdx, Bool hasPrevCluster, IrRunContext& ctx);
 		U clusterIdx, Bool hasPrevCluster, IrRunContext& ctx);

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

@@ -79,7 +79,7 @@ private:
 	F32 m_renderingQuality = 1.0;
 	F32 m_renderingQuality = 1.0;
 
 
 	/// Optimize job chain
 	/// Optimize job chain
-	Array<CommandBufferInitHints, RENDERER_COMMAND_BUFFERS_COUNT> m_cbInitHints;
+	CommandBufferInitHints m_cbInitHints;
 };
 };
 /// @}
 /// @}
 
 

+ 6 - 21
include/anki/renderer/Refl.h

@@ -26,22 +26,20 @@ anki_internal:
 
 
 	ANKI_USE_RESULT Error init(const ConfigSet& config);
 	ANKI_USE_RESULT Error init(const ConfigSet& config);
 
 
-	/// Run before MS.
-	ANKI_USE_RESULT Error run1(CommandBufferPtr cmdb);
-
 	/// Run after IS.
 	/// Run after IS.
-	void run2(CommandBufferPtr cmdb);
+	void run(CommandBufferPtr cmdb);
+
+	TexturePtr getRt() const
+	{
+		return m_rt;
+	}
 
 
 private:
 private:
 	U32 m_width = 0;
 	U32 m_width = 0;
 	U32 m_height = 0;
 	U32 m_height = 0;
 
 
-	Bool8 m_irEnabled = false;
 	Bool8 m_sslrEnabled = false;
 	Bool8 m_sslrEnabled = false;
 
 
-	// Sub-stages
-	UniquePtr<Ir> m_ir;
-
 	// 1st pass: Do the indirect lighting computation
 	// 1st pass: Do the indirect lighting computation
 	ShaderResourcePtr m_frag;
 	ShaderResourcePtr m_frag;
 	ShaderResourcePtr m_vert;
 	ShaderResourcePtr m_vert;
@@ -49,21 +47,8 @@ private:
 	TexturePtr m_rt;
 	TexturePtr m_rt;
 	FramebufferPtr m_fb;
 	FramebufferPtr m_fb;
 	ResourceGroupPtr m_rcGroup;
 	ResourceGroupPtr m_rcGroup;
-	BufferPtr m_uniforms;
-	Timestamp m_uniformsUpdateTimestamp = 0;
-
-	// 2nd pass: Blit
-	ResourceGroupPtr m_blitRcGroup;
-	FramebufferPtr m_isFb;
-	ShaderResourcePtr m_blitFrag;
-	ShaderResourcePtr m_blitVert;
-	PipelinePtr m_blitPpline;
 
 
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& config);
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& config);
-	ANKI_USE_RESULT Error init1stPass(const ConfigSet& config);
-	ANKI_USE_RESULT Error init2ndPass();
-
-	void writeUniforms(CommandBufferPtr cmdb);
 };
 };
 /// @}
 /// @}
 
 

+ 19 - 5
include/anki/renderer/Renderer.h

@@ -34,6 +34,16 @@ public:
 
 
 	~Renderer();
 	~Renderer();
 
 
+	Bool getIrEnabled() const
+	{
+		return m_ir.isCreated();
+	}
+
+	Ir& getIr()
+	{
+		return *m_ir;
+	}
+
 	const Ms& getMs() const
 	const Ms& getMs() const
 	{
 	{
 		return *m_ms;
 		return *m_ms;
@@ -74,6 +84,11 @@ public:
 		return *m_dbg;
 		return *m_dbg;
 	}
 	}
 
 
+	Refl& getRefl()
+	{
+		return *m_refl;
+	}
+
 	U32 getWidth() const
 	U32 getWidth() const
 	{
 	{
 		return m_width;
 		return m_width;
@@ -106,9 +121,8 @@ public:
 	}
 	}
 
 
 	/// This function does all the rendering stages and produces a final result.
 	/// This function does all the rendering stages and produces a final result.
-	ANKI_USE_RESULT Error render(SceneNode& frustumableNode,
-		U frustumIdx,
-		Array<CommandBufferPtr, RENDERER_COMMAND_BUFFERS_COUNT>& cmdBuff);
+	ANKI_USE_RESULT Error render(
+		SceneNode& frustumableNode, U frustumIdx, CommandBufferPtr cmdb);
 
 
 anki_internal:
 anki_internal:
 	/// WARNING: If you change the tile size you need to change some shaders
 	/// WARNING: If you change the tile size you need to change some shaders
@@ -295,12 +309,14 @@ private:
 
 
 	/// @name Rendering stages
 	/// @name Rendering stages
 	/// @{
 	/// @{
+	UniquePtr<Ir> m_ir;
 	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<Refl> m_refl; ///< Reflections.
 	UniquePtr<Refl> m_refl; ///< Reflections.
 	UniquePtr<Tiler> m_tiler;
 	UniquePtr<Tiler> m_tiler;
 	UniquePtr<Pps> m_pps; ///< Postprocessing rendering stage
 	UniquePtr<Pps> m_pps; ///< Postprocessing rendering stage
 	UniquePtr<Fs> m_fs; ///< Forward shading.
 	UniquePtr<Fs> m_fs; ///< Forward shading.
+	UniquePtr<Upsample> m_upsample;
 	UniquePtr<Lf> m_lf; ///< Forward shading lens flares.
 	UniquePtr<Lf> m_lf; ///< Forward shading lens flares.
 	UniquePtr<Dbg> m_dbg; ///< Debug stage.
 	UniquePtr<Dbg> m_dbg; ///< Debug stage.
 	/// @}
 	/// @}
@@ -335,8 +351,6 @@ private:
 	FramebufferPtr m_outputFb;
 	FramebufferPtr m_outputFb;
 	UVec2 m_outputFbSize;
 	UVec2 m_outputFbSize;
 
 
-	TexturePtr m_reflectionsCubemapArr;
-
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
 };
 };
 /// @}
 /// @}

+ 10 - 11
include/anki/renderer/Downsample.h → include/anki/renderer/Upsample.h

@@ -5,7 +5,7 @@
 
 
 #pragma once
 #pragma once
 
 
-#include <anki/renderer/Ms.h>
+#include <anki/renderer/RenderingPass.h>
 
 
 namespace anki
 namespace anki
 {
 {
@@ -13,26 +13,25 @@ namespace anki
 /// @addtogroup renderer
 /// @addtogroup renderer
 /// @{
 /// @{
 
 
-/// Downsample some render targets.
-class Downsample : public RenderingPass
+/// Upsample some textures and append them to IS.
+class Upsample : public RenderingPass
 {
 {
-anki_internal:
-	Downsample(Renderer* r)
+public:
+	Upsample(Renderer* r)
 		: RenderingPass(r)
 		: RenderingPass(r)
 	{
 	{
 	}
 	}
 
 
-	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
+	ANKI_USE_RESULT Error init(const ConfigSet& config);
+
+	void run(CommandBufferPtr cmdb);
 
 
 private:
 private:
+	ResourceGroupPtr m_rcGroup;
+	FramebufferPtr m_fb;
 	ShaderResourcePtr m_frag;
 	ShaderResourcePtr m_frag;
 	ShaderResourcePtr m_vert;
 	ShaderResourcePtr m_vert;
 	PipelinePtr m_ppline;
 	PipelinePtr m_ppline;
-	FramebufferPtr m_fb;
-	Array<TexturePtr, Ms::ATTACHMENT_COUNT> m_msRts;
-	TexturePtr m_depthRt;
-	TexturePtr m_isRt;
-	ResourceGroupPtr m_rg;
 };
 };
 /// @}
 /// @}
 
 

+ 5 - 9
shaders/FsCommonFrag.glsl

@@ -19,6 +19,7 @@ layout(TEX_BINDING(1, 0)) uniform sampler2D anki_msDepthRt;
 #undef LIGHT_TEX_BINDING
 #undef LIGHT_TEX_BINDING
 
 
 #define anki_u_time u_lightingUniforms.rendererSizeTimePad1.z
 #define anki_u_time u_lightingUniforms.rendererSizeTimePad1.z
+#define RENDERER_SIZE (u_lightingUniforms.rendererSizeTimePad1.xy * 0.5)
 
 
 layout(location = 0) in vec3 in_vertPosViewSpace;
 layout(location = 0) in vec3 in_vertPosViewSpace;
 layout(location = 1) flat in float in_alpha;
 layout(location = 1) flat in float in_alpha;
@@ -69,8 +70,7 @@ void particleAlpha(in sampler2D tex, in float alpha)
 void particleSoftTextureAlpha(
 void particleSoftTextureAlpha(
 	in sampler2D depthMap, in sampler2D tex, in float alpha)
 	in sampler2D depthMap, in sampler2D tex, in float alpha)
 {
 {
-	vec2 screenSize = vec2(1.0 / u_lightingUniforms.rendererSizeTimePad1.x,
-		1.0 / u_lightingUniforms.rendererSizeTimePad1.y);
+	vec2 screenSize = 1.0 / RENDERER_SIZE;
 
 
 	float depth = texture(depthMap, gl_FragCoord.xy * screenSize).r;
 	float depth = texture(depthMap, gl_FragCoord.xy * screenSize).r;
 
 
@@ -103,8 +103,7 @@ void particleTextureAlpha(in sampler2D tex, in float alpha)
 void particleSoftColorAlpha(
 void particleSoftColorAlpha(
 	in sampler2D depthMap, in vec3 icolor, in float alpha)
 	in sampler2D depthMap, in vec3 icolor, in float alpha)
 {
 {
-	vec2 screenSize = vec2(1.0 / u_lightingUniforms.rendererSizeTimePad1.x,
-		1.0 / u_lightingUniforms.rendererSizeTimePad1.y);
+	vec2 screenSize = 1.0 / RENDERER_SIZE;
 
 
 	float depth = texture(depthMap, gl_FragCoord.xy * screenSize).r;
 	float depth = texture(depthMap, gl_FragCoord.xy * screenSize).r;
 
 
@@ -135,8 +134,7 @@ vec3 computeLightColor(vec3 diffCol)
 		fragPos.z = u_lightingUniforms.projectionParams.z
 		fragPos.z = u_lightingUniforms.projectionParams.z
 			/ (u_lightingUniforms.projectionParams.w + depth);
 			/ (u_lightingUniforms.projectionParams.w + depth);
 
 
-		vec2 screenSize = vec2(1.0 / u_lightingUniforms.rendererSizeTimePad1.x,
-			1.0 / u_lightingUniforms.rendererSizeTimePad1.y);
+		vec2 screenSize = 1.0 / RENDERER_SIZE;
 
 
 		vec2 ndc = gl_FragCoord.xy * screenSize * 2.0 - 1.0;
 		vec2 ndc = gl_FragCoord.xy * screenSize * 2.0 - 1.0;
 
 
@@ -262,9 +260,7 @@ void particleAnimatedTextureAlphaLight(
 #define fog_DEFINED
 #define fog_DEFINED
 void fog(in sampler2D depthMap, in vec3 color, in float fogScale)
 void fog(in sampler2D depthMap, in vec3 color, in float fogScale)
 {
 {
-	const vec2 screenSize =
-		vec2(1.0 / u_lightingUniforms.rendererSizeTimePad1.x,
-			1.0 / u_lightingUniforms.rendererSizeTimePad1.y);
+	const vec2 screenSize = 1.0 / RENDERER_SIZE;
 
 
 	vec2 texCoords = gl_FragCoord.xy * screenSize;
 	vec2 texCoords = gl_FragCoord.xy * screenSize;
 	float depth = texture(depthMap, texCoords).r;
 	float depth = texture(depthMap, texCoords).r;

+ 2 - 2
shaders/FsCommonVert.glsl

@@ -56,8 +56,8 @@ void particle(in mat4 mvp)
 {
 {
 	gl_Position = mvp * vec4(in_position, 1);
 	gl_Position = mvp * vec4(in_position, 1);
 	out_alpha = in_alpha;
 	out_alpha = in_alpha;
-	gl_PointSize =
-		in_scale * u_lightingUniforms.rendererSizeTimePad1.x / gl_Position.w;
+	gl_PointSize = in_scale * u_lightingUniforms.rendererSizeTimePad1.x * 0.5
+		/ gl_Position.w;
 }
 }
 
 
 //==============================================================================
 //==============================================================================

+ 6 - 1
shaders/Refl.frag.glsl

@@ -36,6 +36,7 @@ layout(TEX_BINDING(0, 4)) uniform sampler2D u_isRt;
 // In/out
 // In/out
 layout(location = 0) in vec2 in_texCoord;
 layout(location = 0) in vec2 in_texCoord;
 layout(location = 0) out vec3 out_indirectColor;
 layout(location = 0) out vec3 out_indirectColor;
+layout(location = 1) out vec4 out_rt2;
 
 
 void main()
 void main()
 {
 {
@@ -55,6 +56,8 @@ void main()
 	vec3 eye = normalize(posVSpace);
 	vec3 eye = normalize(posVSpace);
 	vec3 r = reflect(eye, gbuffer.normal);
 	vec3 r = reflect(eye, gbuffer.normal);
 
 
+	out_indirectColor = vec3(0.0);
+
 //
 //
 // SSLR
 // SSLR
 //
 //
@@ -86,7 +89,6 @@ void main()
 		posVSpace, r, gbuffer.normal, reflLod, specIndirect, diffIndirect);
 		posVSpace, r, gbuffer.normal, reflLod, specIndirect, diffIndirect);
 
 
 	diffIndirect *= gbuffer.diffuse;
 	diffIndirect *= gbuffer.diffuse;
-#endif
 
 
 	// Finalize the indirect specular
 	// Finalize the indirect specular
 	float ndotv = dot(gbuffer.normal, -eye);
 	float ndotv = dot(gbuffer.normal, -eye);
@@ -95,5 +97,8 @@ void main()
 
 
 	// Finalize
 	// Finalize
 	out_indirectColor = diffIndirect + specIndirect;
 	out_indirectColor = diffIndirect + specIndirect;
+#endif
+
+	out_rt2 = vec4(gbuffer.normal, 0.0);
 	gl_FragDepth = depth;
 	gl_FragDepth = depth;
 }
 }

+ 0 - 6
src/renderer/Downsample.cpp

@@ -1,6 +0,0 @@
-// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include <anki/renderer/Downsample.h>

+ 4 - 1
src/renderer/Fs.cpp

@@ -7,6 +7,7 @@
 #include <anki/renderer/Renderer.h>
 #include <anki/renderer/Renderer.h>
 #include <anki/renderer/Ms.h>
 #include <anki/renderer/Ms.h>
 #include <anki/renderer/Is.h>
 #include <anki/renderer/Is.h>
+#include <anki/renderer/Refl.h>
 #include <anki/scene/SceneGraph.h>
 #include <anki/scene/SceneGraph.h>
 #include <anki/scene/Camera.h>
 #include <anki/scene/Camera.h>
 
 
@@ -23,12 +24,13 @@ Error Fs::init(const ConfigSet&)
 {
 {
 	FramebufferInitializer fbInit;
 	FramebufferInitializer fbInit;
 	fbInit.m_colorAttachmentsCount = 1;
 	fbInit.m_colorAttachmentsCount = 1;
-	fbInit.m_colorAttachments[0].m_texture = m_r->getIs().getRt();
+	fbInit.m_colorAttachments[0].m_texture = m_r->getRefl().getRt();
 	fbInit.m_colorAttachments[0].m_loadOperation =
 	fbInit.m_colorAttachments[0].m_loadOperation =
 		AttachmentLoadOperation::LOAD;
 		AttachmentLoadOperation::LOAD;
 	fbInit.m_depthStencilAttachment.m_texture = m_r->getMs().getDepthRt();
 	fbInit.m_depthStencilAttachment.m_texture = m_r->getMs().getDepthRt();
 	fbInit.m_depthStencilAttachment.m_loadOperation =
 	fbInit.m_depthStencilAttachment.m_loadOperation =
 		AttachmentLoadOperation::LOAD;
 		AttachmentLoadOperation::LOAD;
+	fbInit.m_depthStencilAttachment.m_mipmap = 1;
 	m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
 	m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
 
 
 	// Init the global resources
 	// Init the global resources
@@ -57,6 +59,7 @@ Error Fs::init(const ConfigSet&)
 Error Fs::run(CommandBufferPtr& cmdb)
 Error Fs::run(CommandBufferPtr& cmdb)
 {
 {
 	cmdb->bindFramebuffer(m_fb);
 	cmdb->bindFramebuffer(m_fb);
+	cmdb->setViewport(0, 0, m_r->getWidth() / 2, m_r->getHeight() / 2);
 
 
 	FrustumComponent& camFr = m_r->getActiveFrustumComponent();
 	FrustumComponent& camFr = m_r->getActiveFrustumComponent();
 
 

+ 12 - 20
src/renderer/Ir.cpp

@@ -191,7 +191,7 @@ Error Ir::init(const ConfigSet& config)
 	nestedRConfig.set("is.sm.resolution", 16);
 	nestedRConfig.set("is.sm.resolution", 16);
 	nestedRConfig.set("lf.maxFlares", 8);
 	nestedRConfig.set("lf.maxFlares", 8);
 	nestedRConfig.set("pps.enabled", true);
 	nestedRConfig.set("pps.enabled", true);
-	nestedRConfig.set("pps.bloom.enabled", true);
+	nestedRConfig.set("pps.bloom.enabled", true); // XXX ?
 	nestedRConfig.set("pps.ssao.enabled", false);
 	nestedRConfig.set("pps.ssao.enabled", false);
 	nestedRConfig.set("renderingQuality", 1.0);
 	nestedRConfig.set("renderingQuality", 1.0);
 	nestedRConfig.set("clusterSizeZ", 4);
 	nestedRConfig.set("clusterSizeZ", 4);
@@ -251,6 +251,8 @@ Error Ir::init(const ConfigSet& config)
 	// Init the clusterer
 	// Init the clusterer
 	U width = m_r->getWidth() / 2;
 	U width = m_r->getWidth() / 2;
 	U height = m_r->getHeight() / 2;
 	U height = m_r->getHeight() / 2;
+	ANKI_ASSERT(isAligned(Renderer::TILE_SIZE, width)
+		&& isAligned(Renderer::TILE_SIZE, height));
 
 
 	U tileCountX = width / Renderer::TILE_SIZE;
 	U tileCountX = width / Renderer::TILE_SIZE;
 	U tileCountY = height / Renderer::TILE_SIZE;
 	U tileCountY = height / Renderer::TILE_SIZE;
@@ -360,7 +362,7 @@ Error Ir::run(CommandBufferPtr cmdb)
 	while(it != end)
 	while(it != end)
 	{
 	{
 		// Write and render probe
 		// Write and render probe
-		ANKI_CHECK(writeProbeAndRender(*it->m_node, probes[probeIdx]));
+		ANKI_CHECK(writeProbeAndRender(*it->m_node, probes[probeIdx], cmdb));
 
 
 		++it;
 		++it;
 		++probeIdx;
 		++probeIdx;
@@ -478,7 +480,8 @@ void Ir::binProbes(U32 threadId, PtrSize threadsCount, IrRunContext& ctx)
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-Error Ir::writeProbeAndRender(SceneNode& node, IrShaderReflectionProbe& probe)
+Error Ir::writeProbeAndRender(
+	SceneNode& node, IrShaderReflectionProbe& probe, CommandBufferPtr cmdb)
 {
 {
 	const FrustumComponent& frc = m_r->getActiveFrustumComponent();
 	const FrustumComponent& frc = m_r->getActiveFrustumComponent();
 	ReflectionProbeComponent& reflc =
 	ReflectionProbeComponent& reflc =
@@ -496,7 +499,7 @@ Error Ir::writeProbeAndRender(SceneNode& node, IrShaderReflectionProbe& probe)
 	if(reflc.getMarkedForRendering())
 	if(reflc.getMarkedForRendering())
 	{
 	{
 		reflc.setMarkedForRendering(false);
 		reflc.setMarkedForRendering(false);
-		ANKI_CHECK(renderReflection(node, reflc, entry));
+		ANKI_CHECK(renderReflection(node, reflc, entry, cmdb));
 	}
 	}
 
 
 	// If you need to render it mark it for the next frame
 	// If you need to render it mark it for the next frame
@@ -584,23 +587,18 @@ void Ir::writeIndicesAndCluster(
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-Error Ir::renderReflection(
-	SceneNode& node, ReflectionProbeComponent& reflc, U cubemapIdx)
+Error Ir::renderReflection(SceneNode& node,
+	ReflectionProbeComponent& reflc,
+	U cubemapIdx,
+	CommandBufferPtr cmdb)
 {
 {
 	ANKI_TRACE_INC_COUNTER(RENDERER_REFLECTIONS, 1);
 	ANKI_TRACE_INC_COUNTER(RENDERER_REFLECTIONS, 1);
 
 
 	// Render cubemap
 	// Render cubemap
 	for(U i = 0; i < 6; ++i)
 	for(U i = 0; i < 6; ++i)
 	{
 	{
-		Array<CommandBufferPtr, RENDERER_COMMAND_BUFFERS_COUNT> cmdbs;
-		for(U j = 0; j < cmdbs.getSize(); ++j)
-		{
-			cmdbs[j] = getGrManager().newInstance<CommandBuffer>();
-		}
-
 		// Render
 		// Render
-		ANKI_CHECK(m_nestedR.render(node, i, cmdbs));
-		auto& cmdb = cmdbs[cmdbs.getSize() - 1];
+		ANKI_CHECK(m_nestedR.render(node, i, cmdb));
 
 
 		// Copy env texture
 		// Copy env texture
 		cmdb->copyTextureToTexture(m_nestedR.getPps().getRt(),
 		cmdb->copyTextureToTexture(m_nestedR.getPps().getRt(),
@@ -637,12 +635,6 @@ Error Ir::renderReflection(
 		cmdb->bindPipeline(m_computeIrradiancePpline);
 		cmdb->bindPipeline(m_computeIrradiancePpline);
 		m_r->drawQuad(cmdb);
 		m_r->drawQuad(cmdb);
 		cmdb->generateMipmaps(m_irradianceCubemapArr, 6 * cubemapIdx + i);
 		cmdb->generateMipmaps(m_irradianceCubemapArr, 6 * cubemapIdx + i);
-
-		// Flush
-		for(U j = 0; j < cmdbs.getSize(); ++j)
-		{
-			cmdbs[j]->flush();
-		}
 	}
 	}
 
 
 	return ErrorCode::NONE;
 	return ErrorCode::NONE;

+ 5 - 17
src/renderer/MainRenderer.cpp

@@ -123,13 +123,7 @@ Error MainRenderer::render(SceneGraph& scene)
 	m_frameAlloc.getMemoryPool().reset();
 	m_frameAlloc.getMemoryPool().reset();
 
 
 	GrManager& gl = m_r->getGrManager();
 	GrManager& gl = m_r->getGrManager();
-	Array<CommandBufferPtr, RENDERER_COMMAND_BUFFERS_COUNT> cmdbs;
-	CommandBufferPtr& cmdb = cmdbs[RENDERER_COMMAND_BUFFERS_COUNT - 1];
-
-	for(U i = 0; i < RENDERER_COMMAND_BUFFERS_COUNT; i++)
-	{
-		cmdbs[i] = gl.newInstance<CommandBuffer>(m_cbInitHints[i]);
-	}
+	CommandBufferPtr cmdb = gl.newInstance<CommandBuffer>(m_cbInitHints);
 
 
 	// Find where the m_r should draw
 	// Find where the m_r should draw
 	Bool rDrawToDefault;
 	Bool rDrawToDefault;
@@ -154,7 +148,7 @@ Error MainRenderer::render(SceneGraph& scene)
 
 
 	// Run renderer
 	// Run renderer
 	m_r->getIs().setAmbientColor(scene.getAmbientColor());
 	m_r->getIs().setAmbientColor(scene.getAmbientColor());
-	ANKI_CHECK(m_r->render(scene.getActiveCamera(), 0, cmdbs));
+	ANKI_CHECK(m_r->render(scene.getActiveCamera(), 0, cmdb));
 
 
 	if(!rDrawToDefault)
 	if(!rDrawToDefault)
 	{
 	{
@@ -167,17 +161,11 @@ Error MainRenderer::render(SceneGraph& scene)
 		m_r->drawQuad(cmdb);
 		m_r->drawQuad(cmdb);
 	}
 	}
 
 
-	// Flush the command buffers
-	for(U i = 0; i < RENDERER_COMMAND_BUFFERS_COUNT; i++)
-	{
-		cmdbs[i]->flush();
-	}
+	// Flush the command buffer
+	cmdb->flush();
 
 
 	// Set the hints
 	// Set the hints
-	for(U i = 0; i < RENDERER_COMMAND_BUFFERS_COUNT; i++)
-	{
-		m_cbInitHints[i] = cmdbs[i]->computeInitHints();
-	}
+	m_cbInitHints = cmdb->computeInitHints();
 
 
 	ANKI_TRACE_STOP_EVENT(RENDER);
 	ANKI_TRACE_STOP_EVENT(RENDER);
 
 

+ 4 - 1
src/renderer/Ms.cpp

@@ -5,11 +5,11 @@
 
 
 #include <anki/renderer/Ms.h>
 #include <anki/renderer/Ms.h>
 #include <anki/renderer/Renderer.h>
 #include <anki/renderer/Renderer.h>
-
 #include <anki/util/Logger.h>
 #include <anki/util/Logger.h>
 #include <anki/scene/Camera.h>
 #include <anki/scene/Camera.h>
 #include <anki/scene/SceneGraph.h>
 #include <anki/scene/SceneGraph.h>
 #include <anki/misc/ConfigSet.h>
 #include <anki/misc/ConfigSet.h>
+#include <anki/core/Trace.h>
 
 
 namespace anki
 namespace anki
 {
 {
@@ -118,6 +118,8 @@ Error Ms::initInternal(const ConfigSet& initializer)
 //==============================================================================
 //==============================================================================
 Error Ms::run(CommandBufferPtr& cmdb)
 Error Ms::run(CommandBufferPtr& cmdb)
 {
 {
+	ANKI_TRACE_START_EVENT(RENDER_MS);
+
 	// Create 2nd level cmdbs
 	// Create 2nd level cmdbs
 	U threadCount = m_r->getThreadPool().getThreadsCount();
 	U threadCount = m_r->getThreadPool().getThreadsCount();
 	GrManager& gr = m_r->getGrManager();
 	GrManager& gr = m_r->getGrManager();
@@ -147,6 +149,7 @@ Error Ms::run(CommandBufferPtr& cmdb)
 		}
 		}
 	}
 	}
 
 
+	ANKI_TRACE_STOP_EVENT(RENDER_MS);
 	return ErrorCode::NONE;
 	return ErrorCode::NONE;
 }
 }
 
 

+ 31 - 183
src/renderer/Refl.cpp

@@ -55,43 +55,18 @@ Error Refl::init(const ConfigSet& config)
 //==============================================================================
 //==============================================================================
 Error Refl::initInternal(const ConfigSet& config)
 Error Refl::initInternal(const ConfigSet& config)
 {
 {
-	m_irEnabled = config.getNumber("ir.enabled");
-	m_sslrEnabled = config.getNumber("sslr.enabled");
-
-	m_enabled = m_irEnabled || m_sslrEnabled;
-	if(!m_enabled)
-	{
-		return ErrorCode::NONE;
-	}
+	m_sslrEnabled = config.getNumber("sslr.enabled") && m_r->getIrEnabled();
 
 
 	// Size
 	// Size
 	m_width = m_r->getWidth() / 2;
 	m_width = m_r->getWidth() / 2;
 	m_height = m_r->getHeight() / 2;
 	m_height = m_r->getHeight() / 2;
-	ANKI_ASSERT(isAligned(Renderer::TILE_SIZE, m_width)
-		&& isAligned(Renderer::TILE_SIZE, m_height));
-
-	// IR
-	if(m_irEnabled)
-	{
-		m_ir.reset(getAllocator().newInstance<Ir>(m_r));
-		ANKI_CHECK(m_ir->init(config));
-	}
 
 
 	// Continue
 	// Continue
-	ANKI_CHECK(init1stPass(config));
-	ANKI_CHECK(init2ndPass());
-
-	return ErrorCode::NONE;
-}
-
-//==============================================================================
-Error Refl::init1stPass(const ConfigSet& config)
-{
 	GrManager& gr = getGrManager();
 	GrManager& gr = getGrManager();
 
 
 	// Create shader
 	// Create shader
 	StringAuto pps(getFrameAllocator());
 	StringAuto pps(getFrameAllocator());
-	const PixelFormat& pixFormat = Pps::RT_PIXEL_FORMAT;
+	const PixelFormat& pixFormat = Is::RT_PIXEL_FORMAT;
 
 
 	pps.sprintf("#define WIDTH %u\n"
 	pps.sprintf("#define WIDTH %u\n"
 				"#define HEIGHT %u\n"
 				"#define HEIGHT %u\n"
@@ -104,11 +79,13 @@ Error Refl::init1stPass(const ConfigSet& config)
 				"#define SSLR_START_ROUGHNESS %f\n",
 				"#define SSLR_START_ROUGHNESS %f\n",
 		m_width,
 		m_width,
 		m_height,
 		m_height,
-		(m_irEnabled) ? m_ir->getClusterer().getClusterCountX() : 0,
-		(m_irEnabled) ? m_ir->getClusterer().getClusterCountY() : 0,
+		(m_r->getIrEnabled()) ? m_r->getIr().getClusterer().getClusterCountX()
+							  : 0,
+		(m_r->getIrEnabled()) ? m_r->getIr().getClusterer().getClusterCountY()
+							  : 0,
 		U(m_sslrEnabled),
 		U(m_sslrEnabled),
-		U(m_irEnabled),
-		(m_irEnabled) ? m_ir->getCubemapArrayMipmapCount() : 0,
+		U(m_r->getIrEnabled()),
+		(m_r->getIrEnabled()) ? m_r->getIr().getCubemapArrayMipmapCount() : 0,
 		Renderer::TILE_SIZE,
 		Renderer::TILE_SIZE,
 		config.getNumber("sslr.startRoughnes"));
 		config.getNumber("sslr.startRoughnes"));
 
 
@@ -125,10 +102,6 @@ Error Refl::init1stPass(const ConfigSet& config)
 		m_vert, "shaders/Quad.vert.glsl", pps.toCString(), "r_refl_"));
 		m_vert, "shaders/Quad.vert.glsl", pps.toCString(), "r_refl_"));
 
 
 	// Create ppline
 	// Create ppline
-	ColorStateInfo colorState;
-	colorState.m_attachmentCount = 1;
-	colorState.m_attachments[0].m_format = pixFormat;
-
 	PipelineInitializer ppinit;
 	PipelineInitializer ppinit;
 	ppinit.m_color.m_attachmentCount = 1;
 	ppinit.m_color.m_attachmentCount = 1;
 	ppinit.m_color.m_attachments[0].m_format = pixFormat;
 	ppinit.m_color.m_attachments[0].m_format = pixFormat;
@@ -140,11 +113,6 @@ Error Refl::init1stPass(const ConfigSet& config)
 
 
 	m_ppline = gr.newInstance<Pipeline>(ppinit);
 	m_ppline = gr.newInstance<Pipeline>(ppinit);
 
 
-	// Create uniform buffer
-	m_uniforms = getGrManager().newInstance<Buffer>(sizeof(ReflUniforms),
-		BufferUsageBit::UNIFORM,
-		BufferAccessBit::CLIENT_WRITE);
-
 	// Create RC group
 	// Create RC group
 	ResourceGroupInitializer rcInit;
 	ResourceGroupInitializer rcInit;
 
 
@@ -167,19 +135,22 @@ Error Refl::init1stPass(const ConfigSet& config)
 		rcInit.m_textures[4].m_texture = m_r->getIs().getRt();
 		rcInit.m_textures[4].m_texture = m_r->getIs().getRt();
 	}
 	}
 
 
-	if(m_irEnabled)
+	if(m_r->getIrEnabled())
 	{
 	{
-		rcInit.m_textures[5].m_texture = m_ir->getEnvironmentCubemapArray();
+		rcInit.m_textures[5].m_texture =
+			m_r->getIr().getEnvironmentCubemapArray();
 
 
-		rcInit.m_textures[6].m_texture = m_ir->getIrradianceCubemapArray();
+		rcInit.m_textures[6].m_texture =
+			m_r->getIr().getIrradianceCubemapArray();
 
 
-		rcInit.m_textures[7].m_texture = m_ir->getIntegrationLut();
-		rcInit.m_textures[7].m_sampler = m_ir->getIntegrationLutSampler();
+		rcInit.m_textures[7].m_texture = m_r->getIr().getIntegrationLut();
+		rcInit.m_textures[7].m_sampler =
+			m_r->getIr().getIntegrationLutSampler();
 	}
 	}
 
 
-	rcInit.m_uniformBuffers[0].m_buffer = m_uniforms;
+	rcInit.m_uniformBuffers[0].m_dynamic = true;
 
 
-	if(m_irEnabled)
+	if(m_r->getIrEnabled())
 	{
 	{
 		rcInit.m_storageBuffers[0].m_dynamic = true;
 		rcInit.m_storageBuffers[0].m_dynamic = true;
 		rcInit.m_storageBuffers[1].m_dynamic = true;
 		rcInit.m_storageBuffers[1].m_dynamic = true;
@@ -216,154 +187,31 @@ Error Refl::init1stPass(const ConfigSet& config)
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-Error Refl::init2ndPass()
+void Refl::run(CommandBufferPtr cmdb)
 {
 {
-	GrManager& gr = getGrManager();
-
-	// Create RC group
-	ResourceGroupInitializer rcInit;
-	SamplerInitializer sinit;
-	sinit.m_repeat = false;
-
-	rcInit.m_textures[0].m_texture = m_r->getMs().getDepthRt();
-
-	sinit.m_minLod = 1.0;
-	sinit.m_mipmapFilter = SamplingFilter::NEAREST;
-	rcInit.m_textures[1].m_texture = m_r->getMs().getDepthRt();
-	rcInit.m_textures[1].m_sampler = gr.newInstance<Sampler>(sinit);
-
-	sinit.m_minLod = 0.0;
-	rcInit.m_textures[2].m_texture = m_rt;
-	rcInit.m_textures[2].m_sampler = gr.newInstance<Sampler>(sinit);
-
-	sinit.m_minMagFilter = SamplingFilter::LINEAR;
-	rcInit.m_textures[3].m_texture = m_rt;
-	rcInit.m_textures[3].m_sampler = gr.newInstance<Sampler>(sinit);
-
-	rcInit.m_uniformBuffers[0].m_dynamic = true;
-
-	m_blitRcGroup = getGrManager().newInstance<ResourceGroup>(rcInit);
-
-	// Shader
-	StringAuto pps(getFrameAllocator());
-	pps.sprintf("#define TEXTURE_WIDTH %uu\n"
-				"#define TEXTURE_HEIGHT %uu\n",
-		m_width,
-		m_height);
-
-	ANKI_CHECK(getResourceManager().loadResourceToCache(m_blitFrag,
-		"shaders/NearDepthUpscale.frag.glsl",
-		pps.toCString(),
-		"r_refl_"));
-
-	ANKI_CHECK(getResourceManager().loadResourceToCache(m_blitVert,
-		"shaders/NearDepthUpscale.vert.glsl",
-		pps.toCString(),
-		"r_refl_"));
-
-	// Ppline
-	PipelineInitializer ppinit;
-
-	ppinit.m_inputAssembler.m_topology = PrimitiveTopology::TRIANGLE_STRIP;
-
-	ppinit.m_depthStencil.m_depthWriteEnabled = false;
-	ppinit.m_depthStencil.m_depthCompareFunction = CompareOperation::ALWAYS;
-
-	ppinit.m_color.m_attachmentCount = 1;
-	ppinit.m_color.m_attachments[0].m_format = Is::RT_PIXEL_FORMAT;
-	// ppinit.m_color.m_attachments[0].m_srcBlendMethod = BlendMethod::ONE;
-	// ppinit.m_color.m_attachments[0].m_dstBlendMethod = BlendMethod::ONE;
-
-	ppinit.m_shaders[U(ShaderType::VERTEX)] = m_blitVert->getGrShader();
-	ppinit.m_shaders[U(ShaderType::FRAGMENT)] = m_blitFrag->getGrShader();
-	m_blitPpline = gr.newInstance<Pipeline>(ppinit);
-
-	// Create FB
-	FramebufferInitializer fbInit;
-	fbInit.m_colorAttachmentsCount = 1;
-	fbInit.m_colorAttachments[0].m_texture = m_r->getIs().getRt();
-	fbInit.m_colorAttachments[0].m_loadOperation =
-		AttachmentLoadOperation::LOAD;
-	m_isFb = getGrManager().newInstance<Framebuffer>(fbInit);
-
-	return ErrorCode::NONE;
-}
-
-//==============================================================================
-Error Refl::run1(CommandBufferPtr cmdb)
-{
-	ANKI_ASSERT(m_enabled);
-	return m_ir->run(cmdb);
-}
-
-//==============================================================================
-void Refl::run2(CommandBufferPtr cmdb)
-{
-	ANKI_ASSERT(m_enabled);
-
-	// Compute the reflection
-	//
-	writeUniforms(cmdb);
-
 	cmdb->bindFramebuffer(m_fb);
 	cmdb->bindFramebuffer(m_fb);
 	cmdb->setViewport(0, 0, m_width, m_height);
 	cmdb->setViewport(0, 0, m_width, m_height);
 	cmdb->bindPipeline(m_ppline);
 	cmdb->bindPipeline(m_ppline);
 
 
 	DynamicBufferInfo dyn;
 	DynamicBufferInfo dyn;
-	DynamicBufferInfo* pdyn = nullptr;
-	if(m_irEnabled)
+	if(m_r->getIrEnabled())
 	{
 	{
-		dyn.m_storageBuffers[0] = m_ir->getProbesToken();
-		dyn.m_storageBuffers[1] = m_ir->getProbeIndicesToken();
-		dyn.m_storageBuffers[2] = m_ir->getClustersToken();
-		pdyn = &dyn;
+		dyn.m_storageBuffers[0] = m_r->getIr().getProbesToken();
+		dyn.m_storageBuffers[1] = m_r->getIr().getProbeIndicesToken();
+		dyn.m_storageBuffers[2] = m_r->getIr().getClustersToken();
 	};
 	};
-	cmdb->bindResourceGroup(m_rcGroup, 0, pdyn);
-
-	m_r->drawQuad(cmdb);
-
-	// Write the reflection back to IS RT
-	//
-	DynamicBufferToken token;
-	Vec4* linearDepth =
-		static_cast<Vec4*>(getGrManager().allocateFrameHostVisibleMemory(
-			sizeof(Vec4), BufferUsage::UNIFORM, token));
-	const Frustum& fr = m_r->getActiveFrustumComponent().getFrustum();
-	computeLinearizeDepthOptimal(
-		fr.getNear(), fr.getFar(), linearDepth->x(), linearDepth->y());
-
-	DynamicBufferInfo dyn1;
-	dyn1.m_uniformBuffers[0] = token;
-
-	cmdb->bindFramebuffer(m_isFb);
-	cmdb->bindPipeline(m_blitPpline);
-	cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
-	cmdb->bindResourceGroup(m_blitRcGroup, 0, &dyn1);
-
-	m_r->drawQuad(cmdb);
-}
 
 
-//==============================================================================
-void Refl::writeUniforms(CommandBufferPtr cmdb)
-{
 	const FrustumComponent& frc = m_r->getActiveFrustumComponent();
 	const FrustumComponent& frc = m_r->getActiveFrustumComponent();
+	ReflUniforms* blk = static_cast<ReflUniforms*>(
+		getGrManager().allocateFrameHostVisibleMemory(sizeof(ReflUniforms),
+			BufferUsage::UNIFORM,
+			dyn.m_uniformBuffers[0]));
+	blk->m_projectionParams = m_r->getProjectionParameters();
+	blk->m_projectionMat = frc.getProjectionMatrix();
 
 
-	if(m_uniformsUpdateTimestamp < m_r->getProjectionParametersUpdateTimestamp()
-		|| m_uniformsUpdateTimestamp < frc.getTimestamp()
-		|| m_uniformsUpdateTimestamp == 0)
-	{
-		DynamicBufferToken token;
-		ReflUniforms* blk = static_cast<ReflUniforms*>(
-			getGrManager().allocateFrameHostVisibleMemory(
-				sizeof(ReflUniforms), BufferUsage::TRANSFER, token));
+	cmdb->bindResourceGroup(m_rcGroup, 0, &dyn);
 
 
-		blk->m_projectionParams = m_r->getProjectionParameters();
-		blk->m_projectionMat = frc.getProjectionMatrix();
-
-		cmdb->writeBuffer(m_uniforms, 0, token);
-
-		m_uniformsUpdateTimestamp = getGlobalTimestamp();
-	}
+	m_r->drawQuad(cmdb);
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

+ 26 - 20
src/renderer/Renderer.cpp

@@ -9,6 +9,7 @@
 #include <anki/core/Trace.h>
 #include <anki/core/Trace.h>
 #include <anki/misc/ConfigSet.h>
 #include <anki/misc/ConfigSet.h>
 
 
+#include <anki/renderer/Ir.h>
 #include <anki/renderer/Ms.h>
 #include <anki/renderer/Ms.h>
 #include <anki/renderer/Is.h>
 #include <anki/renderer/Is.h>
 #include <anki/renderer/Pps.h>
 #include <anki/renderer/Pps.h>
@@ -17,6 +18,7 @@
 #include <anki/renderer/Dbg.h>
 #include <anki/renderer/Dbg.h>
 #include <anki/renderer/Tiler.h>
 #include <anki/renderer/Tiler.h>
 #include <anki/renderer/Refl.h>
 #include <anki/renderer/Refl.h>
+#include <anki/renderer/Upsample.h>
 
 
 namespace anki
 namespace anki
 {
 {
@@ -112,6 +114,12 @@ Error Renderer::initInternal(const ConfigSet& config)
 		m_resources->loadResource("shaders/Quad.vert.glsl", m_drawQuadVert));
 		m_resources->loadResource("shaders/Quad.vert.glsl", m_drawQuadVert));
 
 
 	// Init the stages. Careful with the order!!!!!!!!!!
 	// Init the stages. Careful with the order!!!!!!!!!!
+	if(config.getNumber("ir.enabled"))
+	{
+		m_ir.reset(m_alloc.newInstance<Ir>(this));
+		ANKI_CHECK(m_ir->init(config));
+	}
+
 	m_ms.reset(m_alloc.newInstance<Ms>(this));
 	m_ms.reset(m_alloc.newInstance<Ms>(this));
 	ANKI_CHECK(m_ms->init(config));
 	ANKI_CHECK(m_ms->init(config));
 
 
@@ -127,6 +135,9 @@ Error Renderer::initInternal(const ConfigSet& 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));
 
 
+	m_upsample.reset(m_alloc.newInstance<Upsample>(this));
+	ANKI_CHECK(m_upsample->init(config));
+
 	m_lf.reset(m_alloc.newInstance<Lf>(this));
 	m_lf.reset(m_alloc.newInstance<Lf>(this));
 	ANKI_CHECK(m_lf->init(config));
 	ANKI_CHECK(m_lf->init(config));
 
 
@@ -140,9 +151,8 @@ Error Renderer::initInternal(const ConfigSet& config)
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-Error Renderer::render(SceneNode& frustumableNode,
-	U frustumIdx,
-	Array<CommandBufferPtr, RENDERER_COMMAND_BUFFERS_COUNT>& cmdb)
+Error Renderer::render(
+	SceneNode& frustumableNode, U frustumIdx, CommandBufferPtr cmdb)
 {
 {
 	m_frc = nullptr;
 	m_frc = nullptr;
 	Error err = frustumableNode.iterateComponentsOfType<FrustumComponent>(
 	Error err = frustumableNode.iterateComponentsOfType<FrustumComponent>(
@@ -170,38 +180,34 @@ Error Renderer::render(SceneNode& frustumableNode,
 	m_clusterer.prepare(getThreadPool(), *m_frc);
 	m_clusterer.prepare(getThreadPool(), *m_frc);
 
 
 	// First part of reflections
 	// First part of reflections
-	if(m_refl->getEnabled())
+	if(m_ir)
 	{
 	{
-		ANKI_CHECK(m_refl->run1(cmdb[0]));
+		ANKI_CHECK(m_ir->run(cmdb));
 	}
 	}
 
 
-	ANKI_TRACE_START_EVENT(RENDER_MS);
-	ANKI_CHECK(m_ms->run(cmdb[0]));
-	ANKI_TRACE_STOP_EVENT(RENDER_MS);
+	ANKI_CHECK(m_ms->run(cmdb));
 
 
-	m_lf->runOcclusionTests(cmdb[0]);
+	m_lf->runOcclusionTests(cmdb);
 
 
-	m_tiler->run(cmdb[0]);
+	m_tiler->run(cmdb);
 
 
-	ANKI_CHECK(m_is->run(cmdb[1]));
+	ANKI_CHECK(m_is->run(cmdb));
 
 
-	ANKI_CHECK(m_fs->run(cmdb[1]));
-	m_lf->run(cmdb[1]);
+	m_refl->run(cmdb);
 
 
-	// 2nd part of reflections
-	if(m_refl->getEnabled())
-	{
-		m_refl->run2(cmdb[1]);
-	}
+	ANKI_CHECK(m_fs->run(cmdb));
+	m_lf->run(cmdb);
+
+	m_upsample->run(cmdb);
 
 
 	if(m_pps->getEnabled())
 	if(m_pps->getEnabled())
 	{
 	{
-		m_pps->run(cmdb[1]);
+		m_pps->run(cmdb);
 	}
 	}
 
 
 	if(m_dbg->getEnabled())
 	if(m_dbg->getEnabled())
 	{
 	{
-		ANKI_CHECK(m_dbg->run(cmdb[1]));
+		ANKI_CHECK(m_dbg->run(cmdb));
 	}
 	}
 
 
 	++m_framesNum;
 	++m_framesNum;

+ 108 - 0
src/renderer/Upsample.cpp

@@ -0,0 +1,108 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <anki/renderer/Upsample.h>
+#include <anki/renderer/Renderer.h>
+#include <anki/renderer/Ms.h>
+#include <anki/renderer/Is.h>
+#include <anki/renderer/Refl.h>
+#include <anki/scene/FrustumComponent.h>
+
+namespace anki
+{
+
+//==============================================================================
+Error Upsample::init(const ConfigSet& config)
+{
+	GrManager& gr = getGrManager();
+
+	// Create RC group
+	ResourceGroupInitializer rcInit;
+	SamplerInitializer sinit;
+	sinit.m_repeat = false;
+
+	rcInit.m_textures[0].m_texture = m_r->getMs().getDepthRt();
+
+	sinit.m_minLod = 1.0;
+	sinit.m_mipmapFilter = SamplingFilter::NEAREST;
+	rcInit.m_textures[1].m_texture = m_r->getMs().getDepthRt();
+	rcInit.m_textures[1].m_sampler = gr.newInstance<Sampler>(sinit);
+
+	sinit.m_minLod = 0.0;
+	rcInit.m_textures[2].m_texture = m_r->getRefl().getRt();
+	rcInit.m_textures[2].m_sampler = gr.newInstance<Sampler>(sinit);
+
+	sinit.m_minMagFilter = SamplingFilter::LINEAR;
+	rcInit.m_textures[3].m_texture = m_r->getRefl().getRt();
+	rcInit.m_textures[3].m_sampler = gr.newInstance<Sampler>(sinit);
+
+	rcInit.m_uniformBuffers[0].m_dynamic = true;
+
+	m_rcGroup = getGrManager().newInstance<ResourceGroup>(rcInit);
+
+	// Shader
+	StringAuto pps(getFrameAllocator());
+	pps.sprintf("#define TEXTURE_WIDTH %uu\n"
+				"#define TEXTURE_HEIGHT %uu\n",
+		m_r->getWidth() / 2,
+		m_r->getHeight() / 2);
+
+	ANKI_CHECK(getResourceManager().loadResourceToCache(m_frag,
+		"shaders/NearDepthUpscale.frag.glsl",
+		pps.toCString(),
+		"r_refl_"));
+
+	ANKI_CHECK(getResourceManager().loadResourceToCache(m_vert,
+		"shaders/NearDepthUpscale.vert.glsl",
+		pps.toCString(),
+		"r_refl_"));
+
+	// Ppline
+	PipelineInitializer ppinit;
+
+	ppinit.m_depthStencil.m_depthWriteEnabled = false;
+	ppinit.m_depthStencil.m_depthCompareFunction = CompareOperation::ALWAYS;
+
+	ppinit.m_color.m_attachmentCount = 1;
+	ppinit.m_color.m_attachments[0].m_format = Is::RT_PIXEL_FORMAT;
+	ppinit.m_color.m_attachments[0].m_srcBlendMethod = BlendMethod::ONE;
+	ppinit.m_color.m_attachments[0].m_dstBlendMethod = BlendMethod::ONE;
+
+	ppinit.m_shaders[U(ShaderType::VERTEX)] = m_vert->getGrShader();
+	ppinit.m_shaders[U(ShaderType::FRAGMENT)] = m_frag->getGrShader();
+	m_ppline = gr.newInstance<Pipeline>(ppinit);
+
+	// Create FB
+	FramebufferInitializer fbInit;
+	fbInit.m_colorAttachmentsCount = 1;
+	fbInit.m_colorAttachments[0].m_texture = m_r->getIs().getRt();
+	fbInit.m_colorAttachments[0].m_loadOperation =
+		AttachmentLoadOperation::LOAD;
+	m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
+
+	return ErrorCode::NONE;
+}
+
+//==============================================================================
+void Upsample::run(CommandBufferPtr cmdb)
+{
+	DynamicBufferInfo dyn;
+
+	Vec4* linearDepth =
+		static_cast<Vec4*>(getGrManager().allocateFrameHostVisibleMemory(
+			sizeof(Vec4), BufferUsage::UNIFORM, dyn.m_uniformBuffers[0]));
+	const Frustum& fr = m_r->getActiveFrustumComponent().getFrustum();
+	computeLinearizeDepthOptimal(
+		fr.getNear(), fr.getFar(), linearDepth->x(), linearDepth->y());
+
+	cmdb->bindFramebuffer(m_fb);
+	cmdb->bindPipeline(m_ppline);
+	cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
+	cmdb->bindResourceGroup(m_rcGroup, 0, &dyn);
+
+	m_r->drawQuad(cmdb);
+}
+
+} // end namespace anki

+ 2 - 2
testapp/Main.cpp

@@ -502,7 +502,7 @@ Error initSubsystems(int argc, char* argv[])
 	config.set("is.sm.poissonEnabled", true);
 	config.set("is.sm.poissonEnabled", true);
 	config.set("is.sm.resolution", 1024);
 	config.set("is.sm.resolution", 1024);
 	config.set("lf.maxFlares", 32);
 	config.set("lf.maxFlares", 32);
-	config.set("pps.enabled", false);
+	config.set("pps.enabled", true);
 	config.set("pps.bloom.enabled", true);
 	config.set("pps.bloom.enabled", true);
 	config.set("pps.bloom.renderingQuality", 0.5);
 	config.set("pps.bloom.renderingQuality", 0.5);
 	config.set("pps.bloom.blurringDist", 1.0);
 	config.set("pps.bloom.blurringDist", 1.0);
@@ -530,7 +530,7 @@ Error initSubsystems(int argc, char* argv[])
 	config.set("sslr.enabled", false);
 	config.set("sslr.enabled", false);
 	config.set("ir.rendererSize", 64);
 	config.set("ir.rendererSize", 64);
 	config.set("ir.clusterSizeZ", 16);
 	config.set("ir.clusterSizeZ", 16);
-	config.set("fullscreenDesktopResolution", false);
+	config.set("fullscreenDesktopResolution", true);
 	// config.set("clusterSizeZ", 16);
 	// config.set("clusterSizeZ", 16);
 	config.set("debugContext", false);
 	config.set("debugContext", false);
 	if(getenv("ANKI_DATA_PATH"))
 	if(getenv("ANKI_DATA_PATH"))