Browse Source

Cleaning MS. Adding downsampling rendering pass (WIP)

Panagiotis Christopoulos Charitos 10 years ago
parent
commit
c9851fdd1f

+ 39 - 0
include/anki/renderer/Downsample.h

@@ -0,0 +1,39 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <anki/renderer/Ms.h>
+
+namespace anki
+{
+
+/// @addtogroup renderer
+/// @{
+
+/// Downsample some render targets.
+class Downsample : public RenderingPass
+{
+anki_internal:
+	Downsample(Renderer* r)
+		: RenderingPass(r)
+	{
+	}
+
+	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
+
+private:
+	ShaderResourcePtr m_frag;
+	ShaderResourcePtr m_vert;
+	PipelinePtr m_ppline;
+	FramebufferPtr m_fb;
+	Array<TexturePtr, Ms::ATTACHMENT_COUNT> m_msRts;
+	TexturePtr m_depthRt;
+	TexturePtr m_isRt;
+	ResourceGroupPtr m_rg;
+};
+/// @}
+
+} // end namespace anki

+ 16 - 23
include/anki/renderer/Ms.h

@@ -35,59 +35,52 @@ anki_internal:
 
 	TexturePtr& getRt0()
 	{
-		return m_planes[1].m_rt0;
+		return m_rt0;
 	}
 
 	TexturePtr& getRt1()
 	{
-		return m_planes[1].m_rt1;
+		return m_rt1;
 	}
 
 	TexturePtr& getRt2()
 	{
-		return m_planes[1].m_rt2;
+		return m_rt2;
 	}
 
 	TexturePtr getDepthRt() const
 	{
-		return m_planes[1].m_depthRt;
+		return m_depthRt;
 	}
 
 	FramebufferPtr& getFramebuffer()
 	{
-		return m_planes[1].m_fb;
+		return m_fb;
 	}
 
-	void generateMipmaps(CommandBufferPtr& cmdb);
+	void downScaleGBuffer(CommandBufferPtr& cmdb);
 
 private:
-	/// A collection of data
-	class Plane
-	{
-	public:
-		FramebufferPtr m_fb;
+	FramebufferPtr m_fb;
 
-		/// Contains diffuse color and emission
-		TexturePtr m_rt0;
+	/// Contains diffuse color and emission
+	TexturePtr m_rt0;
 
-		/// Contains specular color, roughness
-		TexturePtr m_rt1;
+	/// Contains specular color, roughness
+	TexturePtr m_rt1;
 
-		/// Contains normals
-		TexturePtr m_rt2;
+	/// Contains normals
+	TexturePtr m_rt2;
 
-		/// Depth stencil
-		TexturePtr m_depthRt;
-	};
+	/// Depth stencil
+	TexturePtr m_depthRt;
 
-	/// One for multisampled and one for not. 0: multisampled, 1: not
-	Array<Plane, 2> m_planes;
 	DArray<CommandBufferPtr> m_secondLevelCmdbs;
 
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
 
 	/// Create a G buffer FBO
-	ANKI_USE_RESULT Error createRt(U32 index, U32 samples);
+	ANKI_USE_RESULT Error createRt(U32 samples);
 };
 
 /// @}

+ 28 - 0
shaders/Downsample.frag.glsl

@@ -0,0 +1,28 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include "shaders/Common.glsl"
+
+layout(TEX_BINDING(0, 0)) uniform sampler2D u_rt0;
+layout(TEX_BINDING(0, 1)) uniform sampler2D u_rt1;
+layout(TEX_BINDING(0, 2)) uniform sampler2D u_rt2;
+layout(TEX_BINDING(0, 3)) uniform sampler2D u_depth;
+layout(TEX_BINDING(0, 4)) uniform sampler2D u_isRt;
+
+layout(location = 0) in vec2 in_uv;
+
+layout(location = 0) out vec4 out_rt0;
+layout(location = 1) out vec4 out_rt1;
+layout(location = 2) out vec4 out_rt2;
+layout(location = 3) out vec3 out_isRt;
+
+void main()
+{
+	out_rt0 = texture(u_rt0, in_uv);
+	out_rt1 = texture(u_rt1, in_uv);
+	out_rt2 = texture(u_rt2, in_uv);
+	gl_FragDepth = texture(u_depth, in_uv).r;
+	out_isRt = texture(u_isRt, in_uv).rgb;
+}

+ 1 - 1
shaders/IsLp.frag.glsl

@@ -93,7 +93,7 @@ void main()
 	subsurface = gbuffer.subsurface;
 	emission = gbuffer.emission;
 
-	float a2 = pow(max(EPSILON, roughness), 2.0);
+	float a2 = pow(roughness, 2.0);
 
 	// Ambient and emissive color
 	out_color =

+ 1 - 1
shaders/Pack.glsl

@@ -125,7 +125,7 @@ void writeGBuffer(in GbufferInfo g, out vec4 rt0, out vec4 rt1, out vec4 rt2)
 	{                                                                          \
 		vec4 comp = texture(rt1_, uv_);                                        \
 		g_.specular = comp.xyz;                                                \
-		g_.roughness = comp.w;                                                 \
+		g_.roughness = max(EPSILON, comp.w);                                   \
 	}
 
 // Read from G-buffer

+ 6 - 2
shaders/Quad.vert.glsl

@@ -5,12 +5,16 @@
 
 #include "shaders/Common.glsl"
 
+#if !defined(UV_OFFSET)
+#define UV_OFFSET (0.0)
+#endif
+
 out gl_PerVertex
 {
 	vec4 gl_Position;
 };
 
-layout(location = 0) out vec2 out_texCoord;
+layout(location = 0) out vec2 out_uv;
 
 void main()
 {
@@ -18,6 +22,6 @@ void main()
 		vec2[](vec2(-1.0, -1.0), vec2(3.0, -1.0), vec2(-1.0, 3.0));
 
 	vec2 pos = POSITIONS[gl_VertexID];
-	out_texCoord = pos * 0.5 + 0.5;
+	out_uv = pos * 0.5 + (0.5 + UV_OFFSET);
 	gl_Position = vec4(pos, 0.0, 1.0);
 }

+ 7 - 0
src/renderer/Downsample.cpp

@@ -0,0 +1,7 @@
+// 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>
+

+ 8 - 3
src/renderer/MainRenderer.cpp

@@ -55,11 +55,16 @@ Error MainRenderer::create(ThreadPool* threadpool,
 	FramebufferInitializer fbInit;
 	m_defaultFb = gr->newInstance<Framebuffer>(fbInit);
 
-	// Init renderer
+	// Init renderer and manipulate the width/height
 	ConfigSet config2 = config;
 	m_renderingQuality = config.getNumber("renderingQuality");
-	config2.set("width", m_renderingQuality * F32(m_width));
-	config2.set("height", m_renderingQuality * F32(m_height));
+	UVec2 size(
+		m_renderingQuality * F32(m_width), m_renderingQuality * F32(m_height));
+	size.x() = getAlignedRoundDown(Renderer::TILE_SIZE, size.x() / 2) * 2;
+	size.y() = getAlignedRoundDown(Renderer::TILE_SIZE, size.y() / 2) * 2;
+
+	config2.set("width", size.x());
+	config2.set("height", size.y());
 
 	m_r.reset(m_alloc.newInstance<Renderer>());
 	ANKI_CHECK(m_r->init(threadpool,

+ 17 - 44
src/renderer/Ms.cpp

@@ -30,17 +30,15 @@ Ms::~Ms()
 }
 
 //==============================================================================
-Error Ms::createRt(U32 index, U32 samples)
+Error Ms::createRt(U32 samples)
 {
-	Plane& plane = m_planes[index];
-
 	m_r->createRenderTarget(m_r->getWidth(),
 		m_r->getHeight(),
 		DEPTH_RT_PIXEL_FORMAT,
 		samples,
 		SamplingFilter::NEAREST,
 		4,
-		plane.m_depthRt);
+		m_depthRt);
 
 	m_r->createRenderTarget(m_r->getWidth(),
 		m_r->getHeight(),
@@ -48,7 +46,7 @@ Error Ms::createRt(U32 index, U32 samples)
 		samples,
 		SamplingFilter::NEAREST,
 		2,
-		plane.m_rt0);
+		m_rt0);
 
 	m_r->createRenderTarget(m_r->getWidth(),
 		m_r->getHeight(),
@@ -56,7 +54,7 @@ Error Ms::createRt(U32 index, U32 samples)
 		samples,
 		SamplingFilter::NEAREST,
 		2,
-		plane.m_rt1);
+		m_rt1);
 
 	m_r->createRenderTarget(m_r->getWidth(),
 		m_r->getHeight(),
@@ -64,7 +62,7 @@ Error Ms::createRt(U32 index, U32 samples)
 		samples,
 		SamplingFilter::NEAREST,
 		2,
-		plane.m_rt2);
+		m_rt2);
 
 	AttachmentLoadOperation loadop = AttachmentLoadOperation::DONT_CARE;
 #if ANKI_DEBUG
@@ -73,21 +71,21 @@ Error Ms::createRt(U32 index, U32 samples)
 
 	FramebufferInitializer fbInit;
 	fbInit.m_colorAttachmentsCount = ATTACHMENT_COUNT;
-	fbInit.m_colorAttachments[0].m_texture = plane.m_rt0;
+	fbInit.m_colorAttachments[0].m_texture = m_rt0;
 	fbInit.m_colorAttachments[0].m_loadOperation = loadop;
 	fbInit.m_colorAttachments[0].m_clearValue.m_colorf = {{1.0, 0.0, 0.0, 0.0}};
-	fbInit.m_colorAttachments[1].m_texture = plane.m_rt1;
+	fbInit.m_colorAttachments[1].m_texture = m_rt1;
 	fbInit.m_colorAttachments[1].m_loadOperation = loadop;
 	fbInit.m_colorAttachments[1].m_clearValue.m_colorf = {{0.0, 1.0, 0.0, 0.0}};
-	fbInit.m_colorAttachments[2].m_texture = plane.m_rt2;
+	fbInit.m_colorAttachments[2].m_texture = m_rt2;
 	fbInit.m_colorAttachments[2].m_loadOperation = loadop;
 	fbInit.m_colorAttachments[2].m_clearValue.m_colorf = {{0.0, 0.0, 1.0, 0.0}};
-	fbInit.m_depthStencilAttachment.m_texture = plane.m_depthRt;
+	fbInit.m_depthStencilAttachment.m_texture = m_depthRt;
 	fbInit.m_depthStencilAttachment.m_loadOperation =
 		AttachmentLoadOperation::CLEAR;
 	fbInit.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 1.0;
 
-	plane.m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
+	m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
 
 	return ErrorCode::NONE;
 }
@@ -107,12 +105,7 @@ Error Ms::init(const ConfigSet& initializer)
 //==============================================================================
 Error Ms::initInternal(const ConfigSet& initializer)
 {
-	if(initializer.getNumber("samples") > 1)
-	{
-		ANKI_CHECK(createRt(0, initializer.getNumber("samples")));
-	}
-
-	ANKI_CHECK(createRt(1, 1));
+	ANKI_CHECK(createRt(initializer.getNumber("samples")));
 
 	m_secondLevelCmdbs.create(
 		getAllocator(), m_r->getThreadPool().getThreadsCount());
@@ -125,13 +118,6 @@ Error Ms::initInternal(const ConfigSet& initializer)
 //==============================================================================
 Error Ms::run(CommandBufferPtr& cmdb)
 {
-	// Chose the multisampled or the singlesampled framebuffer
-	U planeId = 0;
-	if(m_r->getSamples() == 1)
-	{
-		planeId = 1;
-	}
-
 	// Create 2nd level cmdbs
 	U threadCount = m_r->getThreadPool().getThreadsCount();
 	GrManager& gr = m_r->getGrManager();
@@ -143,7 +129,7 @@ Error Ms::run(CommandBufferPtr& cmdb)
 
 	cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
 
-	cmdb->bindFramebuffer(m_planes[planeId].m_fb);
+	cmdb->bindFramebuffer(m_fb);
 
 	// render all
 	FrustumComponent& frc = m_r->getActiveFrustumComponent();
@@ -152,18 +138,6 @@ Error Ms::run(CommandBufferPtr& cmdb)
 	ANKI_CHECK(m_r->getSceneDrawer().render(
 		frc, RenderingStage::MATERIAL, Pass::MS_FS, cmdbs));
 
-	// If there is multisampling then resolve to singlesampled
-	if(m_r->getSamples() > 1)
-	{
-#if 0
-		fbo[1].blitFrom(fbo[0], UVec2(0U), UVec2(r->getWidth(), r->getHeight()),
-			UVec2(0U), UVec2(r->getWidth(), r->getHeight()),
-			GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
-			GL_NEAREST_BASE);
-#endif
-		ANKI_ASSERT(0 && "TODO");
-	}
-
 	for(U i = 0; i < m_secondLevelCmdbs.getSize(); ++i)
 	{
 		if(!m_secondLevelCmdbs[i]->isEmpty())
@@ -177,13 +151,12 @@ Error Ms::run(CommandBufferPtr& cmdb)
 }
 
 //==============================================================================
-void Ms::generateMipmaps(CommandBufferPtr& cmdb)
+void Ms::downScaleGBuffer(CommandBufferPtr& cmdb)
 {
-	U planeId = (m_r->getSamples() == 1) ? 1 : 0;
-	cmdb->generateMipmaps(m_planes[planeId].m_depthRt);
-	cmdb->generateMipmaps(m_planes[planeId].m_rt0);
-	cmdb->generateMipmaps(m_planes[planeId].m_rt1);
-	cmdb->generateMipmaps(m_planes[planeId].m_rt2);
+	cmdb->generateMipmaps(m_depthRt);
+	cmdb->generateMipmaps(m_rt0);
+	cmdb->generateMipmaps(m_rt1);
+	cmdb->generateMipmaps(m_rt2);
 }
 
 } // end namespace anki

+ 3 - 1
src/renderer/Refl.cpp

@@ -67,6 +67,8 @@ Error Refl::initInternal(const ConfigSet& config)
 	// Size
 	m_width = m_r->getWidth() / 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)
@@ -152,7 +154,7 @@ Error Refl::init1stPass(const ConfigSet& config)
 	if(m_irEnabled)
 	{
 		rcInit.m_textures[5].m_texture = m_ir->getEnvironmentCubemapArray();
-		
+
 		rcInit.m_textures[6].m_texture = m_ir->getIrradianceCubemapArray();
 
 		rcInit.m_textures[7].m_texture = m_ir->getIntegrationLut();

+ 7 - 3
src/renderer/Renderer.cpp

@@ -61,8 +61,12 @@ Error Renderer::init(ThreadPool* threadpool,
 Error Renderer::initInternal(const ConfigSet& config)
 {
 	// Set from the config
-	m_width = getAlignedRoundDown(TILE_SIZE, U(config.getNumber("width")));
-	m_height = getAlignedRoundDown(TILE_SIZE, U(config.getNumber("height")));
+	m_width = config.getNumber("width");
+	m_height = config.getNumber("height");
+	ANKI_ASSERT(isAligned(Renderer::TILE_SIZE, m_width)
+		&& isAligned(Renderer::TILE_SIZE, m_height));
+	ANKI_LOGI("Initializing offscreen renderer. Size %ux%u", m_width, m_height);
+
 	m_lodDistance = config.getNumber("lodDistance");
 	m_framesNum = 0;
 	m_samples = config.getNumber("samples");
@@ -177,7 +181,7 @@ Error Renderer::render(SceneNode& frustumableNode,
 
 	m_lf->runOcclusionTests(cmdb[0]);
 
-	m_ms->generateMipmaps(cmdb[0]);
+	m_ms->downScaleGBuffer(cmdb[0]);
 
 	m_tiler->run(cmdb[0]);
 

+ 16 - 16
src/util/Logger.cpp

@@ -18,7 +18,7 @@ namespace anki
 
 //==============================================================================
 static const Array<const char*, static_cast<U>(Logger::MessageType::COUNT)>
-	MSG_TEXT = {{"Info", "Error", "Warning", "Fatal"}};
+	MSG_TEXT = {{"I", "E", "W", "F"}};
 
 //==============================================================================
 Logger::Logger()
@@ -109,13 +109,13 @@ void Logger::defaultSystemMessageHandler(void*, const Info& info)
 	}
 
 	fprintf(out,
-		"%s(%s:%d %s) %s: %s\033[0m\n",
+		"%s[%s] %s (%s:%d %s)\033[0m\n",
 		terminalColor,
+		MSG_TEXT[static_cast<U>(info.m_type)],
+		info.m_msg,
 		info.m_file,
 		info.m_line,
-		info.m_func,
-		MSG_TEXT[static_cast<U>(info.m_type)],
-		info.m_msg);
+		info.m_func);
 #elif ANKI_OS == ANKI_OS_ANDROID
 	U32 andMsgType = ANDROID_LOG_INFO;
 
@@ -141,11 +141,11 @@ void Logger::defaultSystemMessageHandler(void*, const Info& info)
 
 	__android_log_print(andMsgType,
 		"AnKi",
-		"(%s:%d %s) %s",
+		"%s (%s:%d %s)",
+		info.m_msg,
 		info.m_file,
 		info.m_line,
-		info.m_func,
-		info.m_msg);
+		info.m_func);
 #else
 	FILE* out = NULL;
 
@@ -168,12 +168,12 @@ void Logger::defaultSystemMessageHandler(void*, const Info& info)
 	}
 
 	fprintf(out,
-		"(%s:%d %s) %s: %s\n",
+		"[%s] %s (%s:%d %s)\n",
+		MSG_TEXT[static_cast<U>(info.m_type)],
+		info.m_msg,
 		info.m_file,
 		info.m_line,
-		info.m_func,
-		MSG_TEXT[static_cast<U>(info.m_type)],
-		info.m_msg);
+		info.m_func);
 
 	fflush(out);
 #endif
@@ -184,12 +184,12 @@ void Logger::fileMessageHandler(void* pfile, const Info& info)
 {
 	File* file = reinterpret_cast<File*>(pfile);
 
-	Error err = file->writeText("(%s:%d %s) %s: %s\n",
+	Error err = file->writeText("[%s] %s (%s:%d %s)\n",
+		MSG_TEXT[static_cast<U>(info.m_type)],
+		info.m_msg,
 		info.m_file,
 		info.m_line,
-		info.m_func,
-		MSG_TEXT[static_cast<U>(info.m_type)],
-		info.m_msg);
+		info.m_func);
 
 	if(!err)
 	{