Browse Source

Add scaling

Panagiotis Christopoulos Charitos 4 years ago
parent
commit
ecce9e5e1c

+ 1 - 1
AnKi/Math/Vec.h

@@ -50,7 +50,7 @@ public:
 		m_simd = b.m_simd;
 	}
 
-	/// Convert from another type.
+	/// Convert from another type. From int to float vectors and the opposite.
 	template<typename Y, ANKI_ENABLE(!std::is_same<Y, T>::value)>
 	explicit TVec(const TVec<Y, N>& b)
 	{

+ 2 - 2
AnKi/Renderer/Bloom.cpp

@@ -53,8 +53,8 @@ Error Bloom::initExposure(const ConfigSet& config)
 
 Error Bloom::initUpscale(const ConfigSet& config)
 {
-	m_upscale.m_width = m_r->getResolution().x() / BLOOM_FRACTION;
-	m_upscale.m_height = m_r->getResolution().y() / BLOOM_FRACTION;
+	m_upscale.m_width = m_r->getPostProcessResolution().x() / BLOOM_FRACTION;
+	m_upscale.m_height = m_r->getPostProcessResolution().y() / BLOOM_FRACTION;
 
 	// Create RT descr
 	m_upscale.m_rtDescr =

+ 3 - 2
AnKi/Renderer/ClusterBinning.cpp

@@ -37,7 +37,8 @@ Error ClusterBinning::init(const ConfigSet& config)
 	variantInitInfo.addConstant("TILE_COUNT_X", m_r->getTileCounts().x());
 	variantInitInfo.addConstant("TILE_COUNT_Y", m_r->getTileCounts().y());
 	variantInitInfo.addConstant("Z_SPLIT_COUNT", m_r->getZSplitCount());
-	variantInitInfo.addConstant("RENDERING_SIZE", UVec2(m_r->getResolution().x(), m_r->getResolution().y()));
+	variantInitInfo.addConstant("RENDERING_SIZE",
+								UVec2(m_r->getInternalResolution().x(), m_r->getInternalResolution().y()));
 
 	const ShaderProgramResourceVariant* variant;
 	m_prog->getOrCreateVariant(variantInitInfo, variant);
@@ -417,7 +418,7 @@ void ClusterBinning::writeClustererBuffersTask()
 	{
 		ClusteredShadingUniforms& unis = *static_cast<ClusteredShadingUniforms*>(cs.m_clusteredShadingUniformsAddress);
 
-		unis.m_renderingSize = Vec2(F32(m_r->getResolution().x()), F32(m_r->getResolution().y()));
+		unis.m_renderingSize = Vec2(F32(m_r->getInternalResolution().x()), F32(m_r->getInternalResolution().y()));
 
 		unis.m_time = F32(HighRezTimer::getCurrentTime());
 		unis.m_frame = m_r->getFrameCount() & MAX_U32;

+ 4 - 28
AnKi/Renderer/Common.h

@@ -20,36 +20,12 @@ namespace anki
 #define ANKI_R_LOGF(...) ANKI_LOG("R   ", FATAL, __VA_ARGS__)
 
 // Forward
+#define ANKI_RENDERER_OBJECT_DEF(a, b) class a;
+#include <AnKi/Renderer/RendererObjectDefs.h>
+#undef ANKI_RENDERER_OBJECT_DEF
+
 class Renderer;
 class RendererObject;
-class GBuffer;
-class GBufferPost;
-class ShadowMapping;
-class LightShading;
-class ForwardShading;
-class LensFlare;
-class Ssao;
-class Tonemapping;
-class Bloom;
-class FinalComposite;
-class Dbg;
-class ProbeReflections;
-class DownscaleBlur;
-class VolumetricFog;
-class DepthDownscale;
-class TemporalAA;
-class UiStage;
-class Ssr;
-class Ssgi;
-class VolumetricLightingAccumulation;
-class GlobalIllumination;
-class GenericCompute;
-class ShadowmapsResolve;
-class RtShadows;
-class AccelerationStructureBuilder;
-class MotionVectors;
-class ClusterBinning;
-
 class DebugDrawer;
 
 class RenderQueue;

+ 2 - 2
AnKi/Renderer/Dbg.cpp

@@ -38,7 +38,7 @@ Error Dbg::lazyInit()
 	ANKI_ASSERT(!m_initialized);
 
 	// RT descr
-	m_rtDescr = m_r->create2DRenderTargetDescription(m_r->getResolution().x(), m_r->getResolution().y(),
+	m_rtDescr = m_r->create2DRenderTargetDescription(m_r->getInternalResolution().x(), m_r->getInternalResolution().y(),
 													 DBG_COLOR_ATTACHMENT_PIXEL_FORMAT, "Dbg");
 	m_rtDescr.bake();
 
@@ -60,7 +60,7 @@ void Dbg::run(RenderPassWorkContext& rgraphCtx, const RenderingContext& ctx)
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
 	// Set common state
-	cmdb->setViewport(0, 0, m_r->getResolution().x(), m_r->getResolution().y());
+	cmdb->setViewport(0, 0, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
 	cmdb->setDepthWrite(false);
 
 	cmdb->bindSampler(0, 0, m_r->getSamplers().m_nearestNearestClamp);

+ 4 - 4
AnKi/Renderer/DepthDownscale.cpp

@@ -20,8 +20,8 @@ DepthDownscale::~DepthDownscale()
 
 Error DepthDownscale::initInternal(const ConfigSet&)
 {
-	const U32 width = m_r->getResolution().x() >> 1;
-	const U32 height = m_r->getResolution().y() >> 1;
+	const U32 width = m_r->getInternalResolution().x() >> 1;
+	const U32 height = m_r->getInternalResolution().y() >> 1;
 
 	m_mipCount = computeMaxMipmapCount2d(width, height, HIERARCHICAL_Z_MIN_HEIGHT);
 
@@ -154,8 +154,8 @@ void DepthDownscale::run(RenderPassWorkContext& rgraphCtx)
 	const U32 mipsToFill = (level + 1 < m_mipCount) ? MIPS_WRITTEN_PER_PASS : 1;
 	const U32 copyToClientLevel = (level + mipsToFill == m_mipCount) ? mipsToFill - 1 : MAX_U32;
 
-	const U32 level0Width = m_r->getResolution().x() >> (level + 1);
-	const U32 level0Height = m_r->getResolution().y() >> (level + 1);
+	const U32 level0Width = m_r->getInternalResolution().x() >> (level + 1);
+	const U32 level0Height = m_r->getInternalResolution().y() >> (level + 1);
 	const U32 level1Width = level0Width >> 1;
 	const U32 level1Height = level0Height >> 1;
 

+ 10 - 9
AnKi/Renderer/DownscaleBlur.cpp

@@ -5,7 +5,7 @@
 
 #include <AnKi/Renderer/DownscaleBlur.h>
 #include <AnKi/Renderer/Renderer.h>
-#include <AnKi/Renderer/TemporalAA.h>
+#include <AnKi/Renderer/Scale.h>
 
 namespace anki
 {
@@ -28,14 +28,15 @@ Error DownscaleBlur::init(const ConfigSet& cfg)
 
 Error DownscaleBlur::initInternal(const ConfigSet&)
 {
-	m_passCount =
-		computeMaxMipmapCount2d(m_r->getResolution().x(), m_r->getResolution().y(), DOWNSCALE_BLUR_DOWN_TO) - 1;
+	m_passCount = computeMaxMipmapCount2d(m_r->getPostProcessResolution().x(), m_r->getPostProcessResolution().y(),
+										  DOWNSCALE_BLUR_DOWN_TO)
+				  - 1;
 	ANKI_R_LOGI("Initializing dowscale blur (passCount: %u)", m_passCount);
 
 	// Create the miped texture
-	TextureInitInfo texinit =
-		m_r->create2DRenderTargetDescription(m_r->getResolution().x() / 2, m_r->getResolution().y() / 2,
-											 LIGHT_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT, "DownscaleBlur");
+	TextureInitInfo texinit = m_r->create2DRenderTargetDescription(
+		m_r->getPostProcessResolution().x() / 2, m_r->getPostProcessResolution().y() / 2,
+		LIGHT_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT, "DownscaleBlur");
 	texinit.m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::SAMPLED_COMPUTE;
 	if(m_useCompute)
 	{
@@ -123,7 +124,7 @@ void DownscaleBlur::populateRenderGraph(RenderingContext& ctx)
 				TextureSubresourceInfo renderSubresource;
 
 				pass.newDependency({m_runCtx.m_rt, TextureUsageBit::IMAGE_COMPUTE_WRITE, renderSubresource});
-				pass.newDependency({m_r->getTemporalAA().getRt(), TextureUsageBit::SAMPLED_COMPUTE});
+				pass.newDependency({m_r->getScale().getRt(), TextureUsageBit::SAMPLED_COMPUTE});
 			}
 		}
 	}
@@ -155,7 +156,7 @@ void DownscaleBlur::populateRenderGraph(RenderingContext& ctx)
 				TextureSubresourceInfo renderSubresource;
 
 				pass.newDependency({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, renderSubresource});
-				pass.newDependency({m_r->getTemporalAA().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+				pass.newDependency({m_r->getScale().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 			}
 		}
 	}
@@ -181,7 +182,7 @@ void DownscaleBlur::run(RenderPassWorkContext& rgraphCtx)
 	}
 	else
 	{
-		rgraphCtx.bindColorTexture(0, 1, m_r->getTemporalAA().getRt());
+		rgraphCtx.bindColorTexture(0, 1, m_r->getScale().getRt());
 	}
 
 	if(m_useCompute)

+ 4 - 5
AnKi/Renderer/FinalComposite.cpp

@@ -6,7 +6,7 @@
 #include <AnKi/Renderer/FinalComposite.h>
 #include <AnKi/Renderer/Renderer.h>
 #include <AnKi/Renderer/Bloom.h>
-#include <AnKi/Renderer/TemporalAA.h>
+#include <AnKi/Renderer/Scale.h>
 #include <AnKi/Renderer/Tonemapping.h>
 #include <AnKi/Renderer/LightShading.h>
 #include <AnKi/Renderer/GBuffer.h>
@@ -50,8 +50,7 @@ Error FinalComposite::initInternal(const ConfigSet& config)
 	variantInitInfo.addMutation("BLUE_NOISE", 1);
 	variantInitInfo.addMutation("BLOOM_ENABLED", 1);
 	variantInitInfo.addConstant("LUT_SIZE", U32(LUT_SIZE));
-	variantInitInfo.addConstant("LUT_SIZE", U32(LUT_SIZE));
-	variantInitInfo.addConstant("FB_SIZE", UVec2(m_r->getResolution().x(), m_r->getResolution().y()));
+	variantInitInfo.addConstant("FB_SIZE", m_r->getPostProcessResolution());
 	variantInitInfo.addConstant("MOTION_BLUR_SAMPLES", config.getNumberU32("r_motionBlurSamples"));
 
 	for(U32 dbg = 0; dbg < 2; ++dbg)
@@ -125,7 +124,7 @@ void FinalComposite::run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx
 		cmdb->bindSampler(0, 2, m_r->getSamplers().m_trilinearClamp);
 		cmdb->bindSampler(0, 3, m_r->getSamplers().m_trilinearRepeat);
 
-		rgraphCtx.bindColorTexture(0, 4, m_r->getTemporalAA().getRt());
+		rgraphCtx.bindColorTexture(0, 4, m_r->getScale().getRt());
 
 		rgraphCtx.bindColorTexture(0, 5, m_r->getBloom().getRt());
 		cmdb->bindTexture(0, 6, m_lut->getTextureView());
@@ -186,7 +185,7 @@ void FinalComposite::populateRenderGraph(RenderingContext& ctx)
 		pass.newDependency({m_r->getDbg().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 	}
 
-	pass.newDependency({m_r->getTemporalAA().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+	pass.newDependency({m_r->getScale().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 	pass.newDependency({m_r->getBloom().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 	pass.newDependency({m_r->getMotionVectors().getMotionVectorsRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 	pass.newDependency({m_r->getGBuffer().getDepthRt(), TextureUsageBit::SAMPLED_FRAGMENT});

+ 5 - 4
AnKi/Renderer/GBuffer.cpp

@@ -38,7 +38,7 @@ Error GBuffer::initInternal(const ConfigSet& initializer)
 	for(U32 i = 0; i < 2; ++i)
 	{
 		TextureInitInfo texinit = m_r->create2DRenderTargetInitInfo(
-			m_r->getResolution().x(), m_r->getResolution().y(), GBUFFER_DEPTH_ATTACHMENT_PIXEL_FORMAT,
+			m_r->getInternalResolution().x(), m_r->getInternalResolution().y(), GBUFFER_DEPTH_ATTACHMENT_PIXEL_FORMAT,
 			TextureUsageBit::ALL_SAMPLED | TextureUsageBit::ALL_FRAMEBUFFER_ATTACHMENT, depthRtNames[i]);
 
 		texinit.m_initialUsage = TextureUsageBit::SAMPLED_FRAGMENT;
@@ -50,8 +50,9 @@ Error GBuffer::initInternal(const ConfigSet& initializer)
 		{"GBuffer rt0", "GBuffer rt1", "GBuffer rt2", "GBuffer rt3"}};
 	for(U i = 0; i < GBUFFER_COLOR_ATTACHMENT_COUNT; ++i)
 	{
-		m_colorRtDescrs[i] = m_r->create2DRenderTargetDescription(
-			m_r->getResolution().x(), m_r->getResolution().y(), GBUFFER_COLOR_ATTACHMENT_PIXEL_FORMATS[i], rtNames[i]);
+		m_colorRtDescrs[i] =
+			m_r->create2DRenderTargetDescription(m_r->getInternalResolution().x(), m_r->getInternalResolution().y(),
+												 GBUFFER_COLOR_ATTACHMENT_PIXEL_FORMATS[i], rtNames[i]);
 		m_colorRtDescrs[i].bake();
 	}
 
@@ -95,7 +96,7 @@ void GBuffer::runInThread(const RenderingContext& ctx, RenderPassWorkContext& rg
 	ANKI_ASSERT(end != start);
 
 	// Set some state, leave the rest to default
-	cmdb->setViewport(0, 0, m_r->getResolution().x(), m_r->getResolution().y());
+	cmdb->setViewport(0, 0, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
 
 	const I32 earlyZStart = max(I32(start), 0);
 	const I32 earlyZEnd = min(I32(end), I32(earlyZCount));

+ 1 - 1
AnKi/Renderer/GBufferPost.cpp

@@ -81,7 +81,7 @@ void GBufferPost::run(RenderPassWorkContext& rgraphCtx)
 	const ClusteredShadingContext& rsrc = ctx.m_clusteredShading;
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
-	cmdb->setViewport(0, 0, m_r->getResolution().x(), m_r->getResolution().y());
+	cmdb->setViewport(0, 0, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
 	cmdb->bindShaderProgram(m_grProg);
 
 	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::SRC_ALPHA, BlendFactor::ZERO, BlendFactor::ONE);

+ 2 - 2
AnKi/Renderer/LensFlare.cpp

@@ -73,8 +73,8 @@ Error LensFlare::initOcclusion(const ConfigSet& config)
 		getResourceManager().loadResource("Shaders/LensFlareUpdateIndirectInfo.ankiprog", m_updateIndirectBuffProg));
 
 	ShaderProgramResourceVariantInitInfo variantInitInfo(m_updateIndirectBuffProg);
-	variantInitInfo.addConstant("IN_DEPTH_MAP_SIZE",
-								UVec2(m_r->getResolution().x() / 2 / 2, m_r->getResolution().y() / 2 / 2));
+	variantInitInfo.addConstant(
+		"IN_DEPTH_MAP_SIZE", UVec2(m_r->getInternalResolution().x() / 2 / 2, m_r->getInternalResolution().y() / 2 / 2));
 	const ShaderProgramResourceVariant* variant;
 	m_updateIndirectBuffProg->getOrCreateVariant(variantInitInfo, variant);
 	m_updateIndirectBuffGrProg = variant->getProgram();

+ 2 - 2
AnKi/Renderer/LightShading.cpp

@@ -73,7 +73,7 @@ Error LightShading::initLightShading(const ConfigSet& config)
 
 	// Create RT descr
 	m_lightShading.m_rtDescr =
-		m_r->create2DRenderTargetDescription(m_r->getResolution().x(), m_r->getResolution().y(),
+		m_r->create2DRenderTargetDescription(m_r->getInternalResolution().x(), m_r->getInternalResolution().y(),
 											 LIGHT_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT, "Light Shading");
 	m_lightShading.m_rtDescr.bake();
 
@@ -109,7 +109,7 @@ void LightShading::run(RenderPassWorkContext& rgraphCtx)
 	const RenderingContext& ctx = *m_runCtx.m_ctx;
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
-	cmdb->setViewport(0, 0, m_r->getResolution().x(), m_r->getResolution().y());
+	cmdb->setViewport(0, 0, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
 
 	// Do light shading first
 	if(rgraphCtx.m_currentSecondLevelCommandBufferIndex == 0)

+ 6 - 6
AnKi/Renderer/MainRenderer.cpp

@@ -62,6 +62,11 @@ Error MainRenderer::init(ThreadHive* hive, ResourceManager* resources, GrManager
 														   Format::R8G8B8_UNORM, "Final Composite");
 		m_tmpRtDesc.bake();
 
+		// FB descr
+		m_fbDescr.m_colorAttachmentCount = 1;
+		m_fbDescr.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::DONT_CARE;
+		m_fbDescr.bake();
+
 		ANKI_R_LOGI("The main renderer will have to blit the offscreen renderer's result");
 	}
 
@@ -115,12 +120,7 @@ Error MainRenderer::render(RenderQueue& rqueue, TexturePtr presentTex)
 	{
 		GraphicsRenderPassDescription& pass = ctx.m_renderGraphDescr.newGraphicsRenderPass("Final Blit");
 
-		FramebufferDescription fbDescr;
-		fbDescr.m_colorAttachmentCount = 1;
-		fbDescr.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::DONT_CARE;
-		fbDescr.bake();
-
-		pass.setFramebufferInfo(fbDescr, {{presentRt}}, {});
+		pass.setFramebufferInfo(m_fbDescr, {{presentRt}}, {});
 		pass.setWork(
 			[](RenderPassWorkContext& rgraphCtx) {
 				MainRenderer* const self = static_cast<MainRenderer*>(rgraphCtx.m_userData);

+ 1 - 0
AnKi/Renderer/MainRenderer.h

@@ -83,6 +83,7 @@ private:
 
 	RenderGraphPtr m_rgraph;
 	RenderTargetDescription m_tmpRtDesc;
+	FramebufferDescription m_fbDescr;
 
 	MainRendererStats m_stats;
 	Bool m_statsEnabled = false;

+ 6 - 6
AnKi/Renderer/MotionVectors.cpp

@@ -22,18 +22,18 @@ Error MotionVectors::init(const ConfigSet& config)
 	// Prog
 	ANKI_CHECK(getResourceManager().loadResource("Shaders/MotionVectors.ankiprog", m_prog));
 	ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
-	variantInitInfo.addConstant("FB_SIZE", UVec2(m_r->getResolution().x(), m_r->getResolution().y()));
+	variantInitInfo.addConstant("FB_SIZE", UVec2(m_r->getInternalResolution().x(), m_r->getInternalResolution().y()));
 	const ShaderProgramResourceVariant* variant;
 	m_prog->getOrCreateVariant(variantInitInfo, variant);
 	m_grProg = variant->getProgram();
 
 	// RTs
-	m_motionVectorsRtDescr = m_r->create2DRenderTargetDescription(m_r->getResolution().x(), m_r->getResolution().y(),
-																  Format::R16G16_SFLOAT, "Motion vectors");
+	m_motionVectorsRtDescr = m_r->create2DRenderTargetDescription(
+		m_r->getInternalResolution().x(), m_r->getInternalResolution().y(), Format::R16G16_SFLOAT, "Motion vectors");
 	m_motionVectorsRtDescr.bake();
 
-	m_rejectionFactorRtDescr = m_r->create2DRenderTargetDescription(m_r->getResolution().x(), m_r->getResolution().y(),
-																	Format::R8_UNORM, "Motion vectors rej");
+	m_rejectionFactorRtDescr = m_r->create2DRenderTargetDescription(
+		m_r->getInternalResolution().x(), m_r->getInternalResolution().y(), Format::R8_UNORM, "Motion vectors rej");
 	m_rejectionFactorRtDescr.bake();
 
 	return Error::NONE;
@@ -92,7 +92,7 @@ void MotionVectors::run(RenderPassWorkContext& rgraphCtx)
 	pc.m_prevViewProjectionInvMat = ctx.m_prevMatrices.m_viewProjectionJitter.getInverse();
 	cmdb->setPushConstants(&pc, sizeof(pc));
 
-	dispatchPPCompute(cmdb, 8, 8, m_r->getResolution().x(), m_r->getResolution().y());
+	dispatchPPCompute(cmdb, 8, 8, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
 }
 
 } // end namespace anki

+ 18 - 8
AnKi/Renderer/Renderer.cpp

@@ -41,6 +41,7 @@
 #include <AnKi/Renderer/AccelerationStructureBuilder.h>
 #include <AnKi/Renderer/MotionVectors.h>
 #include <AnKi/Renderer/ClusterBinning.h>
+#include <AnKi/Renderer/Scale.h>
 
 namespace anki
 {
@@ -87,17 +88,22 @@ Error Renderer::initInternal(const ConfigSet& config)
 	m_frameCount = 0;
 
 	// Set from the config
-	m_resolution.x() = U32(F32(config.getNumberU32("width")) * config.getNumberF32("r_renderScaling"));
-	m_resolution.y() = U32(F32(config.getNumberU32("height")) * config.getNumberF32("r_renderScaling"));
-	ANKI_R_LOGI("Initializing offscreen renderer. Size %ux%u", m_resolution.x(), m_resolution.y());
+	const F32 renderScaling = config.getNumberF32("r_renderScaling");
+	const F32 internalRenderScaling = min(config.getNumberF32("r_internalRenderScaling"), renderScaling);
+
+	const Vec2 fresolution = Vec2(F32(config.getNumberU32("width")), F32(config.getNumberU32("height")));
+	m_postProcessResolution = UVec2(fresolution * renderScaling);
+	m_internalResolution = UVec2(fresolution * internalRenderScaling);
+	ANKI_R_LOGI("Initializing offscreen renderer. Size %ux%u. Internal size %ux%u", m_postProcessResolution.x(),
+				m_postProcessResolution.y(), m_internalResolution.x(), m_internalResolution.y());
 
 	m_tileSize = config.getNumberU32("r_tileSize");
-	m_tileCounts.x() = (m_resolution.x() + m_tileSize - 1) / m_tileSize;
-	m_tileCounts.y() = (m_resolution.y() + m_tileSize - 1) / m_tileSize;
+	m_tileCounts.x() = (m_internalResolution.x() + m_tileSize - 1) / m_tileSize;
+	m_tileCounts.y() = (m_internalResolution.y() + m_tileSize - 1) / m_tileSize;
 	m_zSplitCount = config.getNumberU32("r_zSplitCount");
 
 	// A few sanity checks
-	if(m_resolution.x() < 64 || m_resolution.y() < 64)
+	if(m_internalResolution.x() < 64 || m_internalResolution.y() < 64)
 	{
 		ANKI_R_LOGE("Incorrect sizes");
 		return Error::USER_DATA;
@@ -193,6 +199,9 @@ Error Renderer::initInternal(const ConfigSet& config)
 	m_uiStage.reset(m_alloc.newInstance<UiStage>(this));
 	ANKI_CHECK(m_uiStage->init(config));
 
+	m_scale.reset(m_alloc.newInstance<Scale>(this));
+	ANKI_CHECK(m_scale->init(config));
+
 	if(getGrManager().getDeviceCapabilities().m_rayTracingEnabled && config.getBool("scene_rayTracedShadows"))
 	{
 		m_accelerationStructureBuilder.reset(m_alloc.newInstance<AccelerationStructureBuilder>(this));
@@ -246,7 +255,7 @@ void Renderer::initJitteredMats()
 
 	for(U i = 0; i < 16; ++i)
 	{
-		Vec2 texSize(1.0f / Vec2(F32(m_resolution.x()), F32(m_resolution.y()))); // Texel size
+		Vec2 texSize(1.0f / Vec2(F32(m_internalResolution.x()), F32(m_internalResolution.y()))); // Texel size
 		texSize *= 2.0f; // Move it to NDC
 
 		Vec2 S = SAMPLE_LOCS_16[i] / 8.0f; // In [-1, 1]
@@ -263,7 +272,7 @@ void Renderer::initJitteredMats()
 
 	for(U i = 0; i < 8; ++i)
 	{
-		Vec2 texSize(1.0f / Vec2(F32(m_resolution.x()), F32(m_resolution.y()))); // Texel size
+		Vec2 texSize(1.0f / Vec2(F32(m_internalResolution.x()), F32(m_internalResolution.y()))); // Texel size
 		texSize *= 2.0f; // Move it to NDC
 
 		Vec2 S = SAMPLE_LOCS_8[i] / 8.0f; // In [-1, 1]
@@ -343,6 +352,7 @@ Error Renderer::populateRenderGraph(RenderingContext& ctx)
 	m_ssgi->populateRenderGraph(ctx);
 	m_lightShading->populateRenderGraph(ctx);
 	m_temporalAA->populateRenderGraph(ctx);
+	m_scale->populateRenderGraph(ctx);
 	m_downscaleBlur->populateRenderGraph(ctx);
 	m_tonemapping->populateRenderGraph(ctx);
 	m_bloom->populateRenderGraph(ctx);

+ 10 - 4
AnKi/Renderer/Renderer.h

@@ -56,14 +56,19 @@ public:
 		return m_rtShadows.isCreated();
 	}
 
-	const UVec2& getResolution() const
+	const UVec2& getInternalResolution() const
 	{
-		return m_resolution;
+		return m_internalResolution;
+	}
+
+	const UVec2& getPostProcessResolution() const
+	{
+		return m_postProcessResolution;
 	}
 
 	F32 getAspectRatio() const
 	{
-		return F32(m_resolution.x()) / F32(m_resolution.y());
+		return F32(m_internalResolution.x()) / F32(m_internalResolution.y());
 	}
 
 	/// Init the renderer.
@@ -232,7 +237,8 @@ private:
 	UVec2 m_tileCounts = UVec2(0u);
 	U32 m_zSplitCount = 0;
 
-	UVec2 m_resolution = UVec2(0u);
+	UVec2 m_internalResolution = UVec2(0u); ///< The resolution of all passes up until TAA.
+	UVec2 m_postProcessResolution = UVec2(0u); ///< The resolution of post processing and following passes.
 
 	RenderableDrawer m_sceneDrawer;
 

+ 1 - 0
AnKi/Renderer/RendererObjectDefs.h

@@ -30,3 +30,4 @@ ANKI_RENDERER_OBJECT_DEF(RtShadows, rtShadows)
 ANKI_RENDERER_OBJECT_DEF(AccelerationStructureBuilder, accelerationStructureBuilder)
 ANKI_RENDERER_OBJECT_DEF(MotionVectors, motionVectors)
 ANKI_RENDERER_OBJECT_DEF(ClusterBinning, clusterBinning)
+ANKI_RENDERER_OBJECT_DEF(Scale, scale)

+ 24 - 18
AnKi/Renderer/RtShadows.cpp

@@ -67,7 +67,7 @@ Error RtShadows::initInternal(const ConfigSet& cfg)
 		ANKI_CHECK(getResourceManager().loadResource("Shaders/RtShadowsDenoise.ankiprog", m_denoiseProg));
 		ShaderProgramResourceVariantInitInfo variantInitInfo(m_denoiseProg);
 		variantInitInfo.addConstant("OUT_IMAGE_SIZE",
-									UVec2(m_r->getResolution().x() / 2, m_r->getResolution().y() / 2));
+									UVec2(m_r->getInternalResolution().x() / 2, m_r->getInternalResolution().y() / 2));
 		variantInitInfo.addConstant("MIN_SAMPLE_COUNT", 8u);
 		variantInitInfo.addConstant("MAX_SAMPLE_COUNT", 32u);
 		variantInitInfo.addMutation("BLUR_ORIENTATION", 0);
@@ -86,7 +86,8 @@ Error RtShadows::initInternal(const ConfigSet& cfg)
 	{
 		ANKI_CHECK(getResourceManager().loadResource("Shaders/RtShadowsSvgfVariance.ankiprog", m_svgfVarianceProg));
 		ShaderProgramResourceVariantInitInfo variantInitInfo(m_svgfVarianceProg);
-		variantInitInfo.addConstant("FB_SIZE", UVec2(m_r->getResolution().x() / 2, m_r->getResolution().y() / 2));
+		variantInitInfo.addConstant("FB_SIZE",
+									UVec2(m_r->getInternalResolution().x() / 2, m_r->getInternalResolution().y() / 2));
 
 		const ShaderProgramResourceVariant* variant;
 		m_svgfVarianceProg->getOrCreateVariant(variantInitInfo, variant);
@@ -98,7 +99,8 @@ Error RtShadows::initInternal(const ConfigSet& cfg)
 	{
 		ANKI_CHECK(getResourceManager().loadResource("Shaders/RtShadowsSvgfAtrous.ankiprog", m_svgfAtrousProg));
 		ShaderProgramResourceVariantInitInfo variantInitInfo(m_svgfAtrousProg);
-		variantInitInfo.addConstant("FB_SIZE", UVec2(m_r->getResolution().x() / 2, m_r->getResolution().y() / 2));
+		variantInitInfo.addConstant("FB_SIZE",
+									UVec2(m_r->getInternalResolution().x() / 2, m_r->getInternalResolution().y() / 2));
 		variantInitInfo.addMutation("LAST_PASS", 0);
 
 		const ShaderProgramResourceVariant* variant;
@@ -114,7 +116,8 @@ Error RtShadows::initInternal(const ConfigSet& cfg)
 	{
 		ANKI_CHECK(getResourceManager().loadResource("Shaders/RtShadowsUpscale.ankiprog", m_upscaleProg));
 		ShaderProgramResourceVariantInitInfo variantInitInfo(m_upscaleProg);
-		variantInitInfo.addConstant("OUT_IMAGE_SIZE", UVec2(m_r->getResolution().x(), m_r->getResolution().y()));
+		variantInitInfo.addConstant("OUT_IMAGE_SIZE",
+									UVec2(m_r->getInternalResolution().x(), m_r->getInternalResolution().y()));
 
 		const ShaderProgramResourceVariant* variant;
 		m_upscaleProg->getOrCreateVariant(variantInitInfo, variant);
@@ -128,7 +131,7 @@ Error RtShadows::initInternal(const ConfigSet& cfg)
 	// Quarter rez shadow RT
 	{
 		TextureInitInfo texinit = m_r->create2DRenderTargetInitInfo(
-			m_r->getResolution().x() / 2, m_r->getResolution().y() / 2, Format::R32G32_UINT,
+			m_r->getInternalResolution().x() / 2, m_r->getInternalResolution().y() / 2, Format::R32G32_UINT,
 			TextureUsageBit::ALL_SAMPLED | TextureUsageBit::IMAGE_TRACE_RAYS_WRITE
 				| TextureUsageBit::IMAGE_COMPUTE_WRITE,
 			"RtShadows History");
@@ -138,15 +141,16 @@ Error RtShadows::initInternal(const ConfigSet& cfg)
 
 	// Temp shadow RT
 	{
-		m_intermediateShadowsRtDescr = m_r->create2DRenderTargetDescription(
-			m_r->getResolution().x() / 2, m_r->getResolution().y() / 2, Format::R32G32_UINT, "RtShadows Tmp");
+		m_intermediateShadowsRtDescr = m_r->create2DRenderTargetDescription(m_r->getInternalResolution().x() / 2,
+																			m_r->getInternalResolution().y() / 2,
+																			Format::R32G32_UINT, "RtShadows Tmp");
 		m_intermediateShadowsRtDescr.bake();
 	}
 
 	// Moments RT
 	{
 		TextureInitInfo texinit = m_r->create2DRenderTargetInitInfo(
-			m_r->getResolution().x() / 2, m_r->getResolution().y() / 2, Format::R32G32_SFLOAT,
+			m_r->getInternalResolution().x() / 2, m_r->getInternalResolution().y() / 2, Format::R32G32_SFLOAT,
 			TextureUsageBit::ALL_SAMPLED | TextureUsageBit::IMAGE_TRACE_RAYS_WRITE
 				| TextureUsageBit::IMAGE_COMPUTE_WRITE,
 			"RtShadows Moments #1");
@@ -160,7 +164,7 @@ Error RtShadows::initInternal(const ConfigSet& cfg)
 	// History len RT
 	{
 		TextureInitInfo texinit = m_r->create2DRenderTargetInitInfo(
-			m_r->getResolution().x() / 2, m_r->getResolution().y() / 2, Format::R8_UNORM,
+			m_r->getInternalResolution().x() / 2, m_r->getInternalResolution().y() / 2, Format::R8_UNORM,
 			TextureUsageBit::ALL_SAMPLED | TextureUsageBit::IMAGE_TRACE_RAYS_WRITE
 				| TextureUsageBit::IMAGE_COMPUTE_WRITE,
 			"RtShadows History Length #1");
@@ -174,15 +178,17 @@ Error RtShadows::initInternal(const ConfigSet& cfg)
 	// Variance RT
 	if(m_useSvgf)
 	{
-		m_varianceRtDescr = m_r->create2DRenderTargetDescription(
-			m_r->getResolution().x() / 2, m_r->getResolution().y() / 2, Format::R32_SFLOAT, "RtShadows Variance");
+		m_varianceRtDescr = m_r->create2DRenderTargetDescription(m_r->getInternalResolution().x() / 2,
+																 m_r->getInternalResolution().y() / 2,
+																 Format::R32_SFLOAT, "RtShadows Variance");
 		m_varianceRtDescr.bake();
 	}
 
 	// Final RT
 	{
-		m_upscaledRtDescr = m_r->create2DRenderTargetDescription(m_r->getResolution().x(), m_r->getResolution().y(),
-																 Format::R32G32_UINT, "RtShadows Upscaled");
+		m_upscaledRtDescr =
+			m_r->create2DRenderTargetDescription(m_r->getInternalResolution().x(), m_r->getInternalResolution().y(),
+												 Format::R32G32_UINT, "RtShadows Upscaled");
 		m_upscaledRtDescr.bake();
 	}
 
@@ -521,7 +527,7 @@ void RtShadows::run(RenderPassWorkContext& rgraphCtx)
 	cmdb->setPushConstants(&unis, sizeof(unis));
 
 	cmdb->traceRays(m_runCtx.m_sbtBuffer, m_runCtx.m_sbtOffset, m_sbtRecordSize, m_runCtx.m_hitGroupCount, 1,
-					m_r->getResolution().x() / 2, m_r->getResolution().y() / 2, 1);
+					m_r->getInternalResolution().x() / 2, m_r->getInternalResolution().y() / 2, 1);
 }
 
 void RtShadows::runDenoise(RenderPassWorkContext& rgraphCtx)
@@ -546,7 +552,7 @@ void RtShadows::runDenoise(RenderPassWorkContext& rgraphCtx)
 	unis.time = F32(m_r->getGlobalTimestamp());
 	cmdb->setPushConstants(&unis, sizeof(unis));
 
-	dispatchPPCompute(cmdb, 8, 8, m_r->getResolution().x() / 2, m_r->getResolution().y() / 2);
+	dispatchPPCompute(cmdb, 8, 8, m_r->getInternalResolution().x() / 2, m_r->getInternalResolution().y() / 2);
 
 	m_runCtx.m_denoiseOrientation = !m_runCtx.m_denoiseOrientation;
 }
@@ -571,7 +577,7 @@ void RtShadows::runSvgfVariance(RenderPassWorkContext& rgraphCtx)
 	const Mat4& invProjMat = m_runCtx.m_ctx->m_matrices.m_projectionJitter.getInverse();
 	cmdb->setPushConstants(&invProjMat, sizeof(invProjMat));
 
-	dispatchPPCompute(cmdb, 8, 8, m_r->getResolution().x() / 2, m_r->getResolution().y() / 2);
+	dispatchPPCompute(cmdb, 8, 8, m_r->getInternalResolution().x() / 2, m_r->getInternalResolution().y() / 2);
 }
 
 void RtShadows::runSvgfAtrous(RenderPassWorkContext& rgraphCtx)
@@ -610,7 +616,7 @@ void RtShadows::runSvgfAtrous(RenderPassWorkContext& rgraphCtx)
 	const Mat4& invProjMat = m_runCtx.m_ctx->m_matrices.m_projectionJitter.getInverse();
 	cmdb->setPushConstants(&invProjMat, sizeof(invProjMat));
 
-	dispatchPPCompute(cmdb, 8, 8, m_r->getResolution().x() / 2, m_r->getResolution().y() / 2);
+	dispatchPPCompute(cmdb, 8, 8, m_r->getInternalResolution().x() / 2, m_r->getInternalResolution().y() / 2);
 
 	++m_runCtx.m_atrousPassIdx;
 }
@@ -629,7 +635,7 @@ void RtShadows::runUpscale(RenderPassWorkContext& rgraphCtx)
 	rgraphCtx.bindTexture(0, 4, m_r->getDepthDownscale().getHiZRt(), HIZ_HALF_DEPTH);
 	rgraphCtx.bindTexture(0, 5, m_r->getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::DEPTH));
 
-	dispatchPPCompute(cmdb, 8, 8, m_r->getResolution().x(), m_r->getResolution().y());
+	dispatchPPCompute(cmdb, 8, 8, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
 }
 
 void RtShadows::buildSbt()

+ 90 - 0
AnKi/Renderer/Scale.cpp

@@ -0,0 +1,90 @@
+// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <AnKi/Renderer/Scale.h>
+#include <AnKi/Renderer/Renderer.h>
+#include <AnKi/Renderer/TemporalAA.h>
+#include <AnKi/Core/ConfigSet.h>
+
+namespace anki
+{
+
+Scale::~Scale()
+{
+}
+
+Error Scale::init(const ConfigSet& cfg)
+{
+	const Bool needsScale = m_r->getPostProcessResolution() != m_r->getInternalResolution();
+	if(!needsScale)
+	{
+		return Error::NONE;
+	}
+
+	ANKI_R_LOGI("Initializing (up|down)scale pass");
+
+	// Program
+	ANKI_CHECK(getResourceManager().loadResource("Shaders/Blit.ankiprog", m_blitProg));
+	const ShaderProgramResourceVariant* variant;
+	m_blitProg->getOrCreateVariant(variant);
+	m_blitGrProg = variant->getProgram();
+
+	// The RT desc
+	m_rtDesc =
+		m_r->create2DRenderTargetDescription(m_r->getPostProcessResolution().x(), m_r->getPostProcessResolution().y(),
+											 LIGHT_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT, "Scaled");
+	m_rtDesc.bake();
+
+	// FB descr
+	m_fbDescr.m_colorAttachmentCount = 1;
+	m_fbDescr.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::DONT_CARE;
+	m_fbDescr.bake();
+
+	return Error::NONE;
+}
+
+void Scale::populateRenderGraph(RenderingContext& ctx)
+{
+	const Bool needsScale = m_blitGrProg.isCreated();
+	if(!needsScale)
+	{
+		m_runCtx.m_upscaledRt = m_r->getTemporalAA().getRt();
+	}
+	else
+	{
+		RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
+
+		m_runCtx.m_upscaledRt = rgraph.newRenderTarget(m_rtDesc);
+
+		GraphicsRenderPassDescription& pass = ctx.m_renderGraphDescr.newGraphicsRenderPass("Scale");
+		pass.newDependency(RenderPassDependency(m_r->getTemporalAA().getRt(), TextureUsageBit::SAMPLED_FRAGMENT));
+		pass.newDependency(RenderPassDependency(m_runCtx.m_upscaledRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE));
+
+		pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_upscaledRt}}, {});
+
+		pass.setWork(
+			[](RenderPassWorkContext& rgraphCtx) {
+				Scale* const self = static_cast<Scale*>(rgraphCtx.m_userData);
+				self->run(rgraphCtx);
+			},
+			this, 0);
+	}
+}
+
+void Scale::run(RenderPassWorkContext& rgraphCtx)
+{
+	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
+
+	cmdb->bindShaderProgram(m_blitGrProg);
+
+	cmdb->setViewport(0, 0, m_r->getPostProcessResolution().x(), m_r->getPostProcessResolution().y());
+
+	cmdb->bindSampler(0, 0, m_r->getSamplers().m_trilinearClamp);
+	rgraphCtx.bindColorTexture(0, 1, m_r->getTemporalAA().getRt());
+
+	cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 3, 1);
+}
+
+} // end namespace anki

+ 53 - 0
AnKi/Renderer/Scale.h

@@ -0,0 +1,53 @@
+// Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <AnKi/Renderer/RendererObject.h>
+
+namespace anki
+{
+
+/// @addtogroup renderer
+/// @{
+
+/// Upscale or downscale pass.
+class Scale : public RendererObject
+{
+public:
+	Scale(Renderer* r)
+		: RendererObject(r)
+	{
+	}
+
+	~Scale();
+
+	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
+
+	void populateRenderGraph(RenderingContext& ctx);
+
+	RenderTargetHandle getRt() const
+	{
+		return m_runCtx.m_upscaledRt;
+	}
+
+private:
+	ShaderProgramResourcePtr m_blitProg;
+	ShaderProgramPtr m_blitGrProg;
+
+	RenderTargetDescription m_rtDesc;
+	FramebufferDescription m_fbDescr;
+
+	class
+	{
+	public:
+		RenderTargetHandle m_upscaledRt;
+	} m_runCtx;
+
+	void run(RenderPassWorkContext& rgraphCtx);
+};
+/// @}
+
+} // end namespace anki

+ 4 - 4
AnKi/Renderer/ShadowmapsResolve.cpp

@@ -29,10 +29,10 @@ Error ShadowmapsResolve::init(const ConfigSet& cfg)
 
 Error ShadowmapsResolve::initInternal(const ConfigSet& cfg)
 {
-	U32 width = U32(cfg.getNumberF32("r_smResolveFactor") * F32(m_r->getResolution().x()));
-	width = min(m_r->getResolution().x(), getAlignedRoundUp(4, width));
-	U32 height = U32(cfg.getNumberF32("r_smResolveFactor") * F32(m_r->getResolution().y()));
-	height = min(m_r->getResolution().y(), getAlignedRoundUp(4, height));
+	U32 width = U32(cfg.getNumberF32("r_smResolveFactor") * F32(m_r->getInternalResolution().x()));
+	width = min(m_r->getInternalResolution().x(), getAlignedRoundUp(4, width));
+	U32 height = U32(cfg.getNumberF32("r_smResolveFactor") * F32(m_r->getInternalResolution().y()));
+	height = min(m_r->getInternalResolution().y(), getAlignedRoundUp(4, height));
 	ANKI_R_LOGI("Initializing shadow resolve pass. Size %ux%u", width, height);
 
 	m_rtDescr = m_r->create2DRenderTargetDescription(width, height, Format::R8G8B8A8_UNORM, "SM resolve");

+ 2 - 2
AnKi/Renderer/Ssao.cpp

@@ -93,8 +93,8 @@ Error Ssao::initBlur(const ConfigSet& config)
 
 Error Ssao::init(const ConfigSet& config)
 {
-	m_width = m_r->getResolution().x() / SSAO_FRACTION;
-	m_height = m_r->getResolution().y() / SSAO_FRACTION;
+	m_width = m_r->getInternalResolution().x() / SSAO_FRACTION;
+	m_height = m_r->getInternalResolution().y() / SSAO_FRACTION;
 
 	ANKI_R_LOGI("Initializing SSAO. Size %ux%u", m_width, m_height);
 

+ 11 - 9
AnKi/Renderer/Ssgi.cpp

@@ -34,8 +34,8 @@ Error Ssgi::init(const ConfigSet& cfg)
 
 Error Ssgi::initInternal(const ConfigSet& cfg)
 {
-	const U32 width = m_r->getResolution().x();
-	const U32 height = m_r->getResolution().y();
+	const U32 width = m_r->getInternalResolution().x();
+	const U32 height = m_r->getInternalResolution().y();
 	ANKI_ASSERT((width % 2) == 0 && (height % 2) == 0 && "The algorithms won't work");
 	ANKI_R_LOGI("Initializing SSGI pass");
 	m_main.m_maxSteps = cfg.getNumberU32("r_ssgiMaxSteps");
@@ -92,7 +92,8 @@ Error Ssgi::initInternal(const ConfigSet& cfg)
 	{
 		ANKI_CHECK(getResourceManager().loadResource("Shaders/SsgiReconstruct.ankiprog", m_recontruction.m_prog));
 		ShaderProgramResourceVariantInitInfo variantInitInfo(m_recontruction.m_prog);
-		variantInitInfo.addConstant("FB_SIZE", UVec2(m_r->getResolution().x(), m_r->getResolution().y()));
+		variantInitInfo.addConstant("FB_SIZE",
+									UVec2(m_r->getInternalResolution().x(), m_r->getInternalResolution().y()));
 		const ShaderProgramResourceVariant* variant;
 
 		for(U32 i = 0; i < 4; ++i)
@@ -205,8 +206,9 @@ void Ssgi::run(RenderPassWorkContext& rgraphCtx)
 
 	// Bind uniforms
 	SsgiUniforms* unis = allocateAndBindUniforms<SsgiUniforms*>(sizeof(SsgiUniforms), cmdb, 0, 1);
-	unis->m_depthBufferSize = UVec2(m_r->getResolution().x(), m_r->getResolution().y()) >> (m_main.m_depthLod + 1);
-	unis->m_framebufferSize = UVec2(m_r->getResolution().x(), m_r->getResolution().y());
+	unis->m_depthBufferSize =
+		UVec2(m_r->getInternalResolution().x(), m_r->getInternalResolution().y()) >> (m_main.m_depthLod + 1);
+	unis->m_framebufferSize = UVec2(m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
 	unis->m_invProjMat = ctx.m_matrices.m_projectionJitter.getInverse();
 	unis->m_projMat = ctx.m_matrices.m_projectionJitter;
 	unis->m_prevViewProjMatMulInvViewProjMat =
@@ -230,7 +232,7 @@ void Ssgi::run(RenderPassWorkContext& rgraphCtx)
 	rgraphCtx.bindColorTexture(0, 8, m_r->getMotionVectors().getRejectionFactorRt());
 
 	// Dispatch
-	dispatchPPCompute(cmdb, 16, 16, m_r->getResolution().x() / 2, m_r->getResolution().y() / 2);
+	dispatchPPCompute(cmdb, 16, 16, m_r->getInternalResolution().x() / 2, m_r->getInternalResolution().y() / 2);
 }
 
 void Ssgi::runVBlur(RenderPassWorkContext& rgraphCtx)
@@ -248,7 +250,7 @@ void Ssgi::runVBlur(RenderPassWorkContext& rgraphCtx)
 	const Mat4 mat = m_runCtx.m_ctx->m_matrices.m_viewProjectionJitter.getInverse();
 	cmdb->setPushConstants(&mat, sizeof(mat));
 
-	dispatchPPCompute(cmdb, 8, 8, m_r->getResolution().x() / 2, m_r->getResolution().y() / 2);
+	dispatchPPCompute(cmdb, 8, 8, m_r->getInternalResolution().x() / 2, m_r->getInternalResolution().y() / 2);
 }
 
 void Ssgi::runHBlur(RenderPassWorkContext& rgraphCtx)
@@ -266,7 +268,7 @@ void Ssgi::runHBlur(RenderPassWorkContext& rgraphCtx)
 	const Mat4 mat = m_runCtx.m_ctx->m_matrices.m_viewProjectionJitter.getInverse();
 	cmdb->setPushConstants(&mat, sizeof(mat));
 
-	dispatchPPCompute(cmdb, 8, 8, m_r->getResolution().x() / 2, m_r->getResolution().y() / 2);
+	dispatchPPCompute(cmdb, 8, 8, m_r->getInternalResolution().x() / 2, m_r->getInternalResolution().y() / 2);
 }
 
 void Ssgi::runRecontruct(RenderPassWorkContext& rgraphCtx)
@@ -280,7 +282,7 @@ void Ssgi::runRecontruct(RenderPassWorkContext& rgraphCtx)
 
 	rgraphCtx.bindImage(0, 3, m_runCtx.m_finalRt, TextureSubresourceInfo());
 
-	dispatchPPCompute(cmdb, 16, 16, m_r->getResolution().x(), m_r->getResolution().y());
+	dispatchPPCompute(cmdb, 16, 16, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
 }
 
 } // end namespace anki

+ 7 - 6
AnKi/Renderer/Ssr.cpp

@@ -31,8 +31,8 @@ Error Ssr::init(const ConfigSet& cfg)
 
 Error Ssr::initInternal(const ConfigSet& cfg)
 {
-	const U32 width = m_r->getResolution().x();
-	const U32 height = m_r->getResolution().y();
+	const U32 width = m_r->getInternalResolution().x();
+	const U32 height = m_r->getInternalResolution().y();
 	ANKI_R_LOGI("Initializing SSR pass (%ux%u)", width, height);
 	m_maxSteps = cfg.getNumberU32("r_ssrMaxSteps");
 	m_depthLod = cfg.getNumberU32("r_ssrDepthLod");
@@ -102,8 +102,9 @@ void Ssr::run(RenderPassWorkContext& rgraphCtx)
 
 	// Bind uniforms
 	SsrUniforms* unis = allocateAndBindUniforms<SsrUniforms*>(sizeof(SsrUniforms), cmdb, 0, 1);
-	unis->m_depthBufferSize = UVec2(m_r->getResolution().x(), m_r->getResolution().y()) >> (depthLod + 1);
-	unis->m_framebufferSize = UVec2(m_r->getResolution().x(), m_r->getResolution().y());
+	unis->m_depthBufferSize =
+		UVec2(m_r->getInternalResolution().x(), m_r->getInternalResolution().y()) >> (depthLod + 1);
+	unis->m_framebufferSize = UVec2(m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
 	unis->m_frameCount = m_r->getFrameCount() & MAX_U32;
 	unis->m_depthMipCount = m_r->getDepthDownscale().getMipmapCount();
 	unis->m_maxSteps = m_maxSteps;
@@ -131,8 +132,8 @@ void Ssr::run(RenderPassWorkContext& rgraphCtx)
 	cmdb->bindTexture(0, 8, m_noiseImage->getTextureView());
 
 	// Dispatch
-	dispatchPPCompute(cmdb, m_workgroupSize[0], m_workgroupSize[1], m_r->getResolution().x() / 2,
-					  m_r->getResolution().y());
+	dispatchPPCompute(cmdb, m_workgroupSize[0], m_workgroupSize[1], m_r->getInternalResolution().x() / 2,
+					  m_r->getInternalResolution().y());
 }
 
 } // end namespace anki

+ 5 - 3
AnKi/Renderer/TemporalAA.cpp

@@ -44,7 +44,8 @@ Error TemporalAA::initInternal(const ConfigSet& config)
 		ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
 		variantInitInfo.addConstant("VARIANCE_CLIPPING_GAMMA", 2.7f);
 		variantInitInfo.addConstant("BLEND_FACTOR", 1.0f / 16.0f);
-		variantInitInfo.addConstant("FB_SIZE", UVec2(m_r->getResolution().x(), m_r->getResolution().y()));
+		variantInitInfo.addConstant("FB_SIZE",
+									UVec2(m_r->getInternalResolution().x(), m_r->getInternalResolution().y()));
 		variantInitInfo.addMutation("SHARPEN", i + 1);
 		variantInitInfo.addMutation("VARIANCE_CLIPPING", 1);
 		variantInitInfo.addMutation("TONEMAP_FIX", 1);
@@ -58,7 +59,8 @@ Error TemporalAA::initInternal(const ConfigSet& config)
 	for(U i = 0; i < 2; ++i)
 	{
 		TextureInitInfo texinit = m_r->create2DRenderTargetInitInfo(
-			m_r->getResolution().x(), m_r->getResolution().y(), LIGHT_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT,
+			m_r->getInternalResolution().x(), m_r->getInternalResolution().y(),
+			LIGHT_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT,
 			TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::SAMPLED_COMPUTE | TextureUsageBit::IMAGE_COMPUTE_WRITE,
 			"TemporalAA");
 
@@ -84,7 +86,7 @@ void TemporalAA::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphC
 	rgraphCtx.bindImage(0, 5, m_runCtx.m_renderRt, TextureSubresourceInfo());
 	rgraphCtx.bindUniformBuffer(0, 6, m_r->getTonemapping().getAverageLuminanceBuffer());
 
-	dispatchPPCompute(cmdb, 8, 8, m_r->getResolution().x(), m_r->getResolution().y());
+	dispatchPPCompute(cmdb, 8, 8, m_r->getInternalResolution().x(), m_r->getInternalResolution().y());
 }
 
 void TemporalAA::populateRenderGraph(RenderingContext& ctx)

+ 2 - 2
AnKi/Renderer/UiStage.cpp

@@ -25,8 +25,8 @@ UiStage::~UiStage()
 Error UiStage::init(const ConfigSet&)
 {
 	ANKI_CHECK(m_r->getUiManager().newInstance(m_font, "EngineAssets/UbuntuRegular.ttf", Array<U32, 3>{12, 16, 20}));
-	ANKI_CHECK(
-		m_r->getUiManager().newInstance(m_canvas, m_font, 12, m_r->getResolution().x(), m_r->getResolution().y()));
+	ANKI_CHECK(m_r->getUiManager().newInstance(m_canvas, m_font, 12, m_r->getPostProcessResolution().x(),
+											   m_r->getPostProcessResolution().y()));
 
 	return Error::NONE;
 }