Browse Source

Align the Depth Downscale to the new renderer

Panagiotis Christopoulos Charitos 2 years ago
parent
commit
c028122036

+ 0 - 6
AnKi/Renderer/Common.h

@@ -54,12 +54,6 @@ constexpr U32 kMinDrawcallsPerSecondaryCommandBuffer = 16;
 /// Bloom size is rendererSize/kBloomFraction.
 /// Bloom size is rendererSize/kBloomFraction.
 constexpr U32 kBloomFraction = 4;
 constexpr U32 kBloomFraction = 4;
 
 
-/// Used to calculate the mipmap count of the HiZ map.
-constexpr U32 hHierachicalZMinHeight = 80;
-
-constexpr TextureSubresourceInfo kHiZHalfSurface(TextureSurfaceInfo(0, 0, 0, 0));
-constexpr TextureSubresourceInfo kHiZQuarterSurface(TextureSurfaceInfo(1, 0, 0, 0));
-
 constexpr U32 kMaxDebugRenderTargets = 2;
 constexpr U32 kMaxDebugRenderTargets = 2;
 
 
 /// Computes the 'a' and 'b' numbers for linearizeDepthOptimal (see shaders)
 /// Computes the 'a' and 'b' numbers for linearizeDepthOptimal (see shaders)

+ 85 - 206
AnKi/Renderer/DepthDownscale.cpp

@@ -29,108 +29,58 @@ namespace anki {
 
 
 DepthDownscale::~DepthDownscale()
 DepthDownscale::~DepthDownscale()
 {
 {
-	if(m_clientBufferAddr)
-	{
-		m_clientBuffer->unmap();
-	}
 }
 }
 
 
 Error DepthDownscale::initInternal()
 Error DepthDownscale::initInternal()
 {
 {
-	const U32 width = getRenderer().getInternalResolution().x() >> 1;
-	const U32 height = getRenderer().getInternalResolution().y() >> 1;
+	const U32 width = getRenderer().getInternalResolution().x() / 2;
+	const U32 height = getRenderer().getInternalResolution().y() / 2;
 
 
-	m_mipCount = computeMaxMipmapCount2d(width, height, hHierachicalZMinHeight);
+	m_mipCount = 2;
 
 
-	m_lastMipSize.x() = width >> (m_mipCount - 1);
-	m_lastMipSize.y() = height >> (m_mipCount - 1);
+	const UVec2 lastMipSize = UVec2(width, height) >> (m_mipCount - 1);
 
 
-	ANKI_R_LOGV("Initializing HiZ. Mip count %u, last mip size %ux%u", m_mipCount, m_lastMipSize.x(), m_lastMipSize.y());
+	ANKI_R_LOGV("Initializing HiZ. Mip count %u, last mip size %ux%u", m_mipCount, lastMipSize.x(), lastMipSize.y());
 
 
 	const Bool preferCompute = g_preferComputeCVar.get();
 	const Bool preferCompute = g_preferComputeCVar.get();
-	const Bool supportsReductionSampler = GrManager::getSingleton().getDeviceCapabilities().m_samplingFilterMinMax;
 
 
 	// Create RT descr
 	// Create RT descr
 	{
 	{
-		TextureUsageBit usage = TextureUsageBit::kAllSampled;
-		if(preferCompute)
-		{
-			usage |= TextureUsageBit::kImageComputeWrite;
-		}
-		else
-		{
-			usage |= TextureUsageBit::kFramebufferWrite;
-		}
-
-		TextureInitInfo texInit = getRenderer().create2DRenderTargetInitInfo(width, height, Format::kR32_Sfloat, usage, "HiZ");
-		texInit.m_mipmapCount = U8(m_mipCount);
-		m_hizTex = getRenderer().createAndClearRenderTarget(texInit, TextureUsageBit::kSampledFragment);
+		m_rtDescr = getRenderer().create2DRenderTargetDescription(width, height, Format::kR32_Sfloat, "Downscaled depth");
+		m_rtDescr.m_mipmapCount = U8(m_mipCount);
+		m_rtDescr.bake();
 	}
 	}
 
 
 	// Progs
 	// Progs
 	if(preferCompute)
 	if(preferCompute)
 	{
 	{
-		ANKI_CHECK(ResourceManager::getSingleton().loadResource("ShaderBinaries/DepthDownscaleCompute.ankiprogbin", m_prog));
-
-		ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
-		variantInitInfo.addMutation("WAVE_OPERATIONS", 0);
-
-		const ShaderProgramResourceVariant* variant;
-		m_prog->getOrCreateVariant(variantInitInfo, variant);
-		m_grProg.reset(&variant->getProgram());
+		ANKI_CHECK(
+			loadShaderProgram("ShaderBinaries/DepthDownscaleCompute.ankiprogbin", Array<SubMutation, 1>{{"WAVE_OPERATIONS", 0}}, m_prog, m_grProg));
 	}
 	}
 	else
 	else
 	{
 	{
-		ANKI_CHECK(ResourceManager::getSingleton().loadResource("ShaderBinaries/DepthDownscaleRaster.ankiprogbin", m_prog));
-
-		ShaderProgramResourceVariantInitInfo variantInitInfo(m_prog);
-		variantInitInfo.addMutation("REDUCTION_SAMPLER", supportsReductionSampler);
-
-		const ShaderProgramResourceVariant* variant;
-		m_prog->getOrCreateVariant(variantInitInfo, variant);
-		m_grProg.reset(&variant->getProgram());
-
-		// 1st mip prog
-		variantInitInfo.addMutation("REDUCTION_SAMPLER", 1);
-		m_prog->getOrCreateVariant(variantInitInfo, variant);
-		m_firstMipGrProg.reset(&variant->getProgram());
+		ANKI_CHECK(loadShaderProgram("ShaderBinaries/DepthDownscaleRaster.ankiprogbin", m_prog, m_grProg));
 	}
 	}
 
 
 	// Counter buffer
 	// Counter buffer
 	if(preferCompute)
 	if(preferCompute)
 	{
 	{
-		BufferInitInfo buffInit("HiZCounterBuffer");
+		BufferInitInfo buffInit("Depth downscale counter buffer");
 		buffInit.m_size = sizeof(U32);
 		buffInit.m_size = sizeof(U32);
 		buffInit.m_usage = BufferUsageBit::kStorageComputeWrite | BufferUsageBit::kTransferDestination;
 		buffInit.m_usage = BufferUsageBit::kStorageComputeWrite | BufferUsageBit::kTransferDestination;
 		m_counterBuffer = GrManager::getSingleton().newBuffer(buffInit);
 		m_counterBuffer = GrManager::getSingleton().newBuffer(buffInit);
-	}
 
 
-	// Client buffer
-	{
-		// Create buffer
-		BufferInitInfo buffInit("HiZ Client");
-		buffInit.m_mapAccess = BufferMapAccessBit::kRead;
-		buffInit.m_size = PtrSize(m_lastMipSize.y()) * PtrSize(m_lastMipSize.x()) * sizeof(F32);
-		buffInit.m_usage = BufferUsageBit::kStorageComputeWrite | BufferUsageBit::kStorageFragmentWrite;
-		m_clientBuffer = GrManager::getSingleton().newBuffer(buffInit);
+		// Zero it
+		CommandBufferInitInfo cmdbInit;
+		cmdbInit.m_flags |= CommandBufferFlag::kSmallBatch;
+		CommandBufferPtr cmdb = GrManager::getSingleton().newCommandBuffer(cmdbInit);
 
 
-		m_clientBufferAddr = m_clientBuffer->map(0, buffInit.m_size, BufferMapAccessBit::kRead);
+		cmdb->fillBuffer(m_counterBuffer.get(), 0, kMaxPtrSize, 0);
 
 
-		// Fill the buffer with 1.0f
-		for(U32 i = 0; i < m_lastMipSize.x() * m_lastMipSize.y(); ++i)
-		{
-			static_cast<F32*>(m_clientBufferAddr)[i] = 1.0f;
-		}
-	}
+		FencePtr fence;
+		cmdb->flush({}, &fence);
 
 
-	// Reduction sampler
-	if(!preferCompute && supportsReductionSampler)
-	{
-		SamplerInitInfo sinit("HiZReductionMax");
-		sinit.m_addressing = SamplingAddressing::kClamp;
-		sinit.m_mipmapFilter = SamplingFilter::kMax;
-		sinit.m_minMagFilter = SamplingFilter::kMax;
-		m_reductionSampler = GrManager::getSingleton().newSampler(sinit);
+		fence->clientWait(6.0_sec);
 	}
 	}
 
 
 	if(!preferCompute)
 	if(!preferCompute)
@@ -159,22 +109,6 @@ Error DepthDownscale::init()
 	return err;
 	return err;
 }
 }
 
 
-void DepthDownscale::importRenderTargets(RenderingContext& ctx)
-{
-	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
-
-	// Import RT
-	if(m_hizTexImportedOnce)
-	{
-		m_runCtx.m_hizRt = rgraph.importRenderTarget(m_hizTex.get());
-	}
-	else
-	{
-		m_runCtx.m_hizRt = rgraph.importRenderTarget(m_hizTex.get(), TextureUsageBit::kSampledFragment);
-		m_hizTexImportedOnce = true;
-	}
-}
-
 void DepthDownscale::populateRenderGraph(RenderingContext& ctx)
 void DepthDownscale::populateRenderGraph(RenderingContext& ctx)
 {
 {
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
@@ -183,7 +117,9 @@ void DepthDownscale::populateRenderGraph(RenderingContext& ctx)
 	{
 	{
 		// Do it with compute
 		// Do it with compute
 
 
-		ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("HiZ");
+		m_runCtx.m_rt = rgraph.newRenderTarget(m_rtDescr);
+
+		ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("Depth downscale");
 
 
 		pass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSampledCompute,
 		pass.newTextureDependency(getRenderer().getGBuffer().getDepthRt(), TextureUsageBit::kSampledCompute,
 								  TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 								  TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
@@ -192,11 +128,48 @@ void DepthDownscale::populateRenderGraph(RenderingContext& ctx)
 		{
 		{
 			TextureSubresourceInfo subresource;
 			TextureSubresourceInfo subresource;
 			subresource.m_firstMipmap = mip;
 			subresource.m_firstMipmap = mip;
-			pass.newTextureDependency(m_runCtx.m_hizRt, TextureUsageBit::kImageComputeWrite, subresource);
+			pass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kImageComputeWrite, subresource);
 		}
 		}
 
 
 		pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
 		pass.setWork([this](RenderPassWorkContext& rgraphCtx) {
-			runCompute(rgraphCtx);
+			CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
+
+			cmdb.bindShaderProgram(m_grProg.get());
+
+			varAU2(dispatchThreadGroupCountXY);
+			varAU2(workGroupOffset); // needed if Left and Top are not 0,0
+			varAU2(numWorkGroupsAndMips);
+			varAU4(rectInfo) = initAU4(0, 0, getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y());
+			SpdSetup(dispatchThreadGroupCountXY, workGroupOffset, numWorkGroupsAndMips, rectInfo, m_mipCount);
+
+			DepthDownscaleUniforms pc;
+			pc.m_threadgroupCount = numWorkGroupsAndMips[0];
+			pc.m_mipmapCount = numWorkGroupsAndMips[1];
+			pc.m_srcTexSizeOverOne = 1.0f / Vec2(getRenderer().getInternalResolution());
+
+			cmdb.setPushConstants(&pc, sizeof(pc));
+
+			for(U32 mip = 0; mip < kMaxMipsSinglePassDownsamplerCanProduce; ++mip)
+			{
+				TextureSubresourceInfo subresource;
+				if(mip < m_mipCount)
+				{
+					subresource.m_firstMipmap = mip;
+				}
+				else
+				{
+					subresource.m_firstMipmap = 0; // Put something random
+				}
+
+				rgraphCtx.bindImage(0, 0, m_runCtx.m_rt, subresource, mip);
+			}
+
+			cmdb.bindStorageBuffer(0, 1, m_counterBuffer.get(), 0, sizeof(U32));
+
+			cmdb.bindSampler(0, 2, getRenderer().getSamplers().m_trilinearClamp.get());
+			rgraphCtx.bindTexture(0, 3, getRenderer().getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
+
+			cmdb.dispatchCompute(dispatchThreadGroupCountXY[0], dispatchThreadGroupCountXY[1], 1);
 		});
 		});
 	}
 	}
 	else
 	else
@@ -205,9 +178,9 @@ void DepthDownscale::populateRenderGraph(RenderingContext& ctx)
 
 
 		for(U32 mip = 0; mip < m_mipCount; ++mip)
 		for(U32 mip = 0; mip < m_mipCount; ++mip)
 		{
 		{
-			static constexpr Array<CString, 8> passNames = {"HiZ #1", "HiZ #2", "HiZ #3", "HiZ #4", "HiZ #5", "HiZ #6", "HiZ #7", "HiZ #8"};
+			static constexpr Array<CString, 4> passNames = {"Depth downscale #1", "Depth downscale #2", "Depth downscale #3", "Depth downscale #4"};
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(passNames[mip]);
 			GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass(passNames[mip]);
-			pass.setFramebufferInfo(m_fbDescrs[mip], {m_runCtx.m_hizRt});
+			pass.setFramebufferInfo(m_fbDescrs[mip], {m_runCtx.m_rt});
 
 
 			if(mip == 0)
 			if(mip == 0)
 			{
 			{
@@ -218,130 +191,36 @@ void DepthDownscale::populateRenderGraph(RenderingContext& ctx)
 			{
 			{
 				TextureSurfaceInfo subresource;
 				TextureSurfaceInfo subresource;
 				subresource.m_level = mip - 1;
 				subresource.m_level = mip - 1;
-				pass.newTextureDependency(m_runCtx.m_hizRt, TextureUsageBit::kSampledFragment, subresource);
+				pass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kSampledFragment, subresource);
 			}
 			}
 
 
 			TextureSurfaceInfo subresource;
 			TextureSurfaceInfo subresource;
 			subresource.m_level = mip;
 			subresource.m_level = mip;
-			pass.newTextureDependency(m_runCtx.m_hizRt, TextureUsageBit::kFramebufferWrite, subresource);
+			pass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kFramebufferWrite, subresource);
 
 
 			pass.setWork([this, mip](RenderPassWorkContext& rgraphCtx) {
 			pass.setWork([this, mip](RenderPassWorkContext& rgraphCtx) {
-				runGraphics(mip, rgraphCtx);
+				CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
+
+				cmdb.bindShaderProgram(m_grProg.get());
+				cmdb.bindSampler(0, 1, getRenderer().getSamplers().m_trilinearClamp.get());
+
+				if(mip == 0)
+				{
+					rgraphCtx.bindTexture(0, 0, getRenderer().getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
+				}
+				else
+				{
+					TextureSubresourceInfo subresource;
+					subresource.m_firstMipmap = mip - 1;
+					rgraphCtx.bindTexture(0, 0, m_runCtx.m_rt, subresource);
+				}
+
+				const UVec2 size = (getRenderer().getInternalResolution() / 2) >> mip;
+				cmdb.setViewport(0, 0, size.x(), size.y());
+				cmdb.draw(PrimitiveTopology::kTriangles, 3);
 			});
 			});
 		}
 		}
 	}
 	}
 }
 }
 
 
-void DepthDownscale::runCompute(RenderPassWorkContext& rgraphCtx)
-{
-	CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
-
-	// Zero the counter buffer before everything else
-	if(!m_counterBufferZeroed) [[unlikely]]
-	{
-		m_counterBufferZeroed = true;
-
-		cmdb.fillBuffer(m_counterBuffer.get(), 0, kMaxPtrSize, 0);
-
-		const BufferBarrierInfo barrier = {m_counterBuffer.get(), BufferUsageBit::kTransferDestination, BufferUsageBit::kStorageComputeWrite, 0,
-										   kMaxPtrSize};
-		cmdb.setPipelineBarrier({}, {&barrier, 1}, {});
-	}
-
-	cmdb.bindShaderProgram(m_grProg.get());
-
-	varAU2(dispatchThreadGroupCountXY);
-	varAU2(workGroupOffset); // needed if Left and Top are not 0,0
-	varAU2(numWorkGroupsAndMips);
-	varAU4(rectInfo) = initAU4(0, 0, getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y());
-	SpdSetup(dispatchThreadGroupCountXY, workGroupOffset, numWorkGroupsAndMips, rectInfo);
-	SpdSetup(dispatchThreadGroupCountXY, workGroupOffset, numWorkGroupsAndMips, rectInfo, m_mipCount);
-
-	DepthDownscaleUniforms pc;
-	pc.m_workgroupCount = numWorkGroupsAndMips[0];
-	pc.m_mipmapCount = numWorkGroupsAndMips[1];
-	pc.m_srcTexSizeOverOne = 1.0f / Vec2(getRenderer().getInternalResolution());
-	pc.m_lastMipWidth = m_lastMipSize.x();
-
-	cmdb.setPushConstants(&pc, sizeof(pc));
-
-	constexpr U32 maxMipsSpdCanProduce = 12;
-	for(U32 mip = 0; mip < maxMipsSpdCanProduce; ++mip)
-	{
-		TextureSubresourceInfo subresource;
-		if(mip < m_mipCount)
-		{
-			subresource.m_firstMipmap = mip;
-		}
-		else
-		{
-			subresource.m_firstMipmap = 0;
-		}
-
-		rgraphCtx.bindImage(0, 0, m_runCtx.m_hizRt, subresource, mip);
-	}
-
-	if(m_mipCount >= 5)
-	{
-		TextureSubresourceInfo subresource;
-		subresource.m_firstMipmap = 4;
-		rgraphCtx.bindImage(0, 1, m_runCtx.m_hizRt, subresource);
-	}
-	else
-	{
-		// Bind something random
-		TextureSubresourceInfo subresource;
-		subresource.m_firstMipmap = 0;
-		rgraphCtx.bindImage(0, 1, m_runCtx.m_hizRt, subresource);
-	}
-
-	cmdb.bindStorageBuffer(0, 2, m_counterBuffer.get(), 0, kMaxPtrSize);
-	cmdb.bindStorageBuffer(0, 3, m_clientBuffer.get(), 0, kMaxPtrSize);
-
-	cmdb.bindSampler(0, 4, getRenderer().getSamplers().m_trilinearClamp.get());
-	rgraphCtx.bindTexture(0, 5, getRenderer().getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
-
-	cmdb.dispatchCompute(dispatchThreadGroupCountXY[0], dispatchThreadGroupCountXY[1], 1);
-}
-
-void DepthDownscale::runGraphics(U32 mip, RenderPassWorkContext& rgraphCtx)
-{
-	CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
-
-	if(mip == 0)
-	{
-		rgraphCtx.bindTexture(0, 0, getRenderer().getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
-
-		cmdb.bindSampler(0, 1, getRenderer().getSamplers().m_trilinearClamp.get());
-
-		cmdb.bindShaderProgram(m_firstMipGrProg.get());
-	}
-	else
-	{
-		TextureSubresourceInfo subresource;
-		subresource.m_firstMipmap = mip - 1;
-		rgraphCtx.bindTexture(0, 0, m_runCtx.m_hizRt, subresource);
-
-		if(m_reductionSampler.isCreated())
-		{
-			cmdb.bindSampler(0, 1, m_reductionSampler.get());
-		}
-		else
-		{
-			cmdb.bindSampler(0, 1, getRenderer().getSamplers().m_trilinearClamp.get());
-		}
-
-		cmdb.bindShaderProgram(m_grProg.get());
-	}
-
-	cmdb.bindStorageBuffer(0, 2, m_clientBuffer.get(), 0, kMaxPtrSize);
-
-	const UVec4 pc((mip != m_mipCount - 1) ? 0 : m_lastMipSize.x());
-	cmdb.setPushConstants(&pc, sizeof(pc));
-
-	const UVec2 size = (getRenderer().getInternalResolution() / 2) >> mip;
-	cmdb.setViewport(0, 0, size.x(), size.y());
-	cmdb.draw(PrimitiveTopology::kTriangles, 3);
-}
-
 } // end namespace anki
 } // end namespace anki

+ 7 - 28
AnKi/Renderer/DepthDownscale.h

@@ -18,22 +18,22 @@ namespace anki {
 class DepthDownscale : public RendererObject
 class DepthDownscale : public RendererObject
 {
 {
 public:
 public:
+	static constexpr TextureSubresourceInfo kQuarterInternalResolution = TextureSurfaceInfo(0, 0, 0, 0);
+	static constexpr TextureSubresourceInfo kEighthInternalResolution = TextureSurfaceInfo(1, 0, 0, 0);
+
 	DepthDownscale() = default;
 	DepthDownscale() = default;
 
 
 	~DepthDownscale();
 	~DepthDownscale();
 
 
 	Error init();
 	Error init();
 
 
-	/// Import render targets
-	void importRenderTargets(RenderingContext& ctx);
-
 	/// Populate the rendergraph.
 	/// Populate the rendergraph.
 	void populateRenderGraph(RenderingContext& ctx);
 	void populateRenderGraph(RenderingContext& ctx);
 
 
 	/// Return a FP color render target with hierarchical Z (min Z) in it's mips.
 	/// Return a FP color render target with hierarchical Z (min Z) in it's mips.
-	RenderTargetHandle getHiZRt() const
+	RenderTargetHandle getRt() const
 	{
 	{
-		return m_runCtx.m_hizRt;
+		return m_runCtx.m_rt;
 	}
 	}
 
 
 	U32 getMipmapCount() const
 	U32 getMipmapCount() const
@@ -41,46 +41,25 @@ public:
 		return m_mipCount;
 		return m_mipCount;
 	}
 	}
 
 
-	void getClientDepthMapInfo(F32*& depthValues, U32& width, U32& height) const
-	{
-		width = m_lastMipSize.x();
-		height = m_lastMipSize.y();
-		ANKI_ASSERT(m_clientBuffer);
-		m_clientBuffer->invalidate(0, kMaxPtrSize);
-		depthValues = static_cast<F32*>(m_clientBufferAddr);
-	}
-
 private:
 private:
-	TexturePtr m_hizTex;
-	Bool m_hizTexImportedOnce = false;
+	RenderTargetDescription m_rtDescr;
 
 
 	ShaderProgramResourcePtr m_prog;
 	ShaderProgramResourcePtr m_prog;
 	ShaderProgramPtr m_grProg;
 	ShaderProgramPtr m_grProg;
-	ShaderProgramPtr m_firstMipGrProg;
 
 
 	BufferPtr m_counterBuffer;
 	BufferPtr m_counterBuffer;
-	Bool m_counterBufferZeroed = false;
-
-	BufferPtr m_clientBuffer;
-	void* m_clientBufferAddr = nullptr;
-
-	SamplerPtr m_reductionSampler;
 
 
 	RendererDynamicArray<FramebufferDescription> m_fbDescrs;
 	RendererDynamicArray<FramebufferDescription> m_fbDescrs;
 
 
-	UVec2 m_lastMipSize;
 	U32 m_mipCount = 0;
 	U32 m_mipCount = 0;
 
 
 	class
 	class
 	{
 	{
 	public:
 	public:
-		RenderTargetHandle m_hizRt;
+		RenderTargetHandle m_rt;
 	} m_runCtx; ///< Run context.
 	} m_runCtx; ///< Run context.
 
 
 	Error initInternal();
 	Error initInternal();
-
-	void runCompute(RenderPassWorkContext& rgraphCtx);
-	void runGraphics(U32 mip, RenderPassWorkContext& rgraphCtx);
 };
 };
 /// @}
 /// @}
 
 

+ 3 - 2
AnKi/Renderer/ForwardShading.cpp

@@ -53,7 +53,7 @@ void ForwardShading::run(const RenderingContext& ctx, RenderPassWorkContext& rgr
 	cmdb.bindSampler(set, U32(MaterialBinding::kLinearClampSampler), getRenderer().getSamplers().m_trilinearClamp.get());
 	cmdb.bindSampler(set, U32(MaterialBinding::kLinearClampSampler), getRenderer().getSamplers().m_trilinearClamp.get());
 	cmdb.bindSampler(set, U32(MaterialBinding::kShadowSampler), getRenderer().getSamplers().m_trilinearClampShadow.get());
 	cmdb.bindSampler(set, U32(MaterialBinding::kShadowSampler), getRenderer().getSamplers().m_trilinearClampShadow.get());
 
 
-	rgraphCtx.bindTexture(set, U32(MaterialBinding::kDepthRt), getRenderer().getDepthDownscale().getHiZRt(), kHiZHalfSurface);
+	rgraphCtx.bindTexture(set, U32(MaterialBinding::kDepthRt), getRenderer().getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
 	rgraphCtx.bindColorTexture(set, U32(MaterialBinding::kLightVolume), getRenderer().getVolumetricLightingAccumulation().getRt());
 	rgraphCtx.bindColorTexture(set, U32(MaterialBinding::kLightVolume), getRenderer().getVolumetricLightingAccumulation().getRt());
 
 
 	cmdb.bindUniformBuffer(set, U32(MaterialBinding::kClusterShadingUniforms), getRenderer().getClusterBinning2().getClusteredShadingUniforms());
 	cmdb.bindUniformBuffer(set, U32(MaterialBinding::kClusterShadingUniforms), getRenderer().getClusterBinning2().getClusteredShadingUniforms());
@@ -86,7 +86,8 @@ void ForwardShading::run(const RenderingContext& ctx, RenderPassWorkContext& rgr
 
 
 void ForwardShading::setDependencies(GraphicsRenderPassDescription& pass)
 void ForwardShading::setDependencies(GraphicsRenderPassDescription& pass)
 {
 {
-	pass.newTextureDependency(getRenderer().getDepthDownscale().getHiZRt(), TextureUsageBit::kSampledFragment, kHiZHalfSurface);
+	pass.newTextureDependency(getRenderer().getDepthDownscale().getRt(), TextureUsageBit::kSampledFragment,
+							  DepthDownscale::kQuarterInternalResolution);
 	pass.newTextureDependency(getRenderer().getVolumetricLightingAccumulation().getRt(), TextureUsageBit::kSampledFragment);
 	pass.newTextureDependency(getRenderer().getVolumetricLightingAccumulation().getRt(), TextureUsageBit::kSampledFragment);
 
 
 	if(getRenderer().getLensFlare().getIndirectDrawBuffer().isValid())
 	if(getRenderer().getLensFlare().getIndirectDrawBuffer().isValid())

+ 7 - 16
AnKi/Renderer/IndirectDiffuse.cpp

@@ -173,7 +173,8 @@ void IndirectDiffuse::populateRenderGraph(RenderingContext& ctx)
 		ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("IndirectDiffuse VRS SRI gen");
 		ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("IndirectDiffuse VRS SRI gen");
 
 
 		pass.newTextureDependency(m_runCtx.m_sriRt, TextureUsageBit::kImageComputeWrite);
 		pass.newTextureDependency(m_runCtx.m_sriRt, TextureUsageBit::kImageComputeWrite);
-		pass.newTextureDependency(getRenderer().getDepthDownscale().getHiZRt(), TextureUsageBit::kSampledCompute, kHiZHalfSurface);
+		pass.newTextureDependency(getRenderer().getDepthDownscale().getRt(), TextureUsageBit::kSampledCompute,
+								  DepthDownscale::kQuarterInternalResolution);
 
 
 		pass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
 		pass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
 			const UVec2 viewport = getRenderer().getInternalResolution() / 2u;
 			const UVec2 viewport = getRenderer().getInternalResolution() / 2u;
@@ -182,7 +183,7 @@ void IndirectDiffuse::populateRenderGraph(RenderingContext& ctx)
 
 
 			cmdb.bindShaderProgram(m_vrs.m_grProg.get());
 			cmdb.bindShaderProgram(m_vrs.m_grProg.get());
 
 
-			rgraphCtx.bindTexture(0, 0, getRenderer().getDepthDownscale().getHiZRt(), kHiZHalfSurface);
+			rgraphCtx.bindTexture(0, 0, getRenderer().getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
 			cmdb.bindSampler(0, 1, getRenderer().getSamplers().m_nearestNearestClamp.get());
 			cmdb.bindSampler(0, 1, getRenderer().getSamplers().m_nearestNearestClamp.get());
 			rgraphCtx.bindImage(0, 2, m_runCtx.m_sriRt);
 			rgraphCtx.bindImage(0, 2, m_runCtx.m_sriRt);
 
 
@@ -255,9 +256,7 @@ void IndirectDiffuse::populateRenderGraph(RenderingContext& ctx)
 		}
 		}
 
 
 		prpass->newTextureDependency(getRenderer().getGBuffer().getColorRt(2), readUsage);
 		prpass->newTextureDependency(getRenderer().getGBuffer().getColorRt(2), readUsage);
-		TextureSubresourceInfo hizSubresource;
-		hizSubresource.m_mipmapCount = 1;
-		prpass->newTextureDependency(getRenderer().getDepthDownscale().getHiZRt(), readUsage, hizSubresource);
+		prpass->newTextureDependency(getRenderer().getDepthDownscale().getRt(), readUsage, DepthDownscale::kQuarterInternalResolution);
 		prpass->newTextureDependency(getRenderer().getDownscaleBlur().getRt(), readUsage);
 		prpass->newTextureDependency(getRenderer().getDownscaleBlur().getRt(), readUsage);
 		prpass->newTextureDependency(getRenderer().getMotionVectors().getMotionVectorsRt(), readUsage);
 		prpass->newTextureDependency(getRenderer().getMotionVectors().getMotionVectorsRt(), readUsage);
 		prpass->newTextureDependency(getRenderer().getMotionVectors().getHistoryLengthRt(), readUsage);
 		prpass->newTextureDependency(getRenderer().getMotionVectors().getHistoryLengthRt(), readUsage);
@@ -283,10 +282,7 @@ void IndirectDiffuse::populateRenderGraph(RenderingContext& ctx)
 
 
 			cmdb.bindSampler(0, 3, getRenderer().getSamplers().m_trilinearClamp.get());
 			cmdb.bindSampler(0, 3, getRenderer().getSamplers().m_trilinearClamp.get());
 			rgraphCtx.bindColorTexture(0, 4, getRenderer().getGBuffer().getColorRt(2));
 			rgraphCtx.bindColorTexture(0, 4, getRenderer().getGBuffer().getColorRt(2));
-
-			TextureSubresourceInfo hizSubresource;
-			hizSubresource.m_mipmapCount = 1;
-			rgraphCtx.bindTexture(0, 5, getRenderer().getDepthDownscale().getHiZRt(), hizSubresource);
+			rgraphCtx.bindTexture(0, 5, getRenderer().getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
 			rgraphCtx.bindColorTexture(0, 6, getRenderer().getDownscaleBlur().getRt());
 			rgraphCtx.bindColorTexture(0, 6, getRenderer().getDownscaleBlur().getRt());
 			rgraphCtx.bindColorTexture(0, 7, m_runCtx.m_mainRtHandles[kRead]);
 			rgraphCtx.bindColorTexture(0, 7, m_runCtx.m_mainRtHandles[kRead]);
 			rgraphCtx.bindColorTexture(0, 8, getRenderer().getMotionVectors().getMotionVectorsRt());
 			rgraphCtx.bindColorTexture(0, 8, getRenderer().getMotionVectors().getMotionVectorsRt());
@@ -355,10 +351,7 @@ void IndirectDiffuse::populateRenderGraph(RenderingContext& ctx)
 		}
 		}
 
 
 		prpass->newTextureDependency(m_runCtx.m_mainRtHandles[readIdx], readUsage);
 		prpass->newTextureDependency(m_runCtx.m_mainRtHandles[readIdx], readUsage);
-
-		TextureSubresourceInfo hizSubresource;
-		hizSubresource.m_mipmapCount = 1;
-		prpass->newTextureDependency(getRenderer().getDepthDownscale().getHiZRt(), readUsage, hizSubresource);
+		prpass->newTextureDependency(getRenderer().getDepthDownscale().getRt(), readUsage, DepthDownscale::kQuarterInternalResolution);
 		prpass->newTextureDependency(m_runCtx.m_mainRtHandles[!readIdx], writeUsage);
 		prpass->newTextureDependency(m_runCtx.m_mainRtHandles[!readIdx], writeUsage);
 
 
 		prpass->setWork([this, &ctx, dir, readIdx](RenderPassWorkContext& rgraphCtx) {
 		prpass->setWork([this, &ctx, dir, readIdx](RenderPassWorkContext& rgraphCtx) {
@@ -367,9 +360,7 @@ void IndirectDiffuse::populateRenderGraph(RenderingContext& ctx)
 
 
 			cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
 			cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_trilinearClamp.get());
 			rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_mainRtHandles[readIdx]);
 			rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_mainRtHandles[readIdx]);
-			TextureSubresourceInfo hizSubresource;
-			hizSubresource.m_mipmapCount = 1;
-			rgraphCtx.bindTexture(0, 2, getRenderer().getDepthDownscale().getHiZRt(), hizSubresource);
+			rgraphCtx.bindTexture(0, 2, getRenderer().getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
 
 
 			if(g_preferComputeCVar.get())
 			if(g_preferComputeCVar.get())
 			{
 			{

+ 2 - 5
AnKi/Renderer/IndirectSpecular.cpp

@@ -148,10 +148,7 @@ void IndirectSpecular::populateRenderGraph(RenderingContext& ctx)
 		ppass->newTextureDependency(m_runCtx.m_rts[kRead], readUsage);
 		ppass->newTextureDependency(m_runCtx.m_rts[kRead], readUsage);
 		ppass->newTextureDependency(getRenderer().getGBuffer().getColorRt(1), readUsage);
 		ppass->newTextureDependency(getRenderer().getGBuffer().getColorRt(1), readUsage);
 		ppass->newTextureDependency(getRenderer().getGBuffer().getColorRt(2), readUsage);
 		ppass->newTextureDependency(getRenderer().getGBuffer().getColorRt(2), readUsage);
-
-		TextureSubresourceInfo hizSubresource;
-		hizSubresource.m_mipmapCount = min(g_ssrDepthLodCVar.get() + 1, getRenderer().getDepthDownscale().getMipmapCount());
-		ppass->newTextureDependency(getRenderer().getDepthDownscale().getHiZRt(), readUsage, hizSubresource);
+		ppass->newTextureDependency(getRenderer().getDepthDownscale().getRt(), readUsage);
 
 
 		if(getRenderer().getProbeReflections().getHasCurrentlyRefreshedReflectionRt())
 		if(getRenderer().getProbeReflections().getHasCurrentlyRefreshedReflectionRt())
 		{
 		{
@@ -201,7 +198,7 @@ void IndirectSpecular::run(const RenderingContext& ctx, RenderPassWorkContext& r
 
 
 	TextureSubresourceInfo hizSubresource;
 	TextureSubresourceInfo hizSubresource;
 	hizSubresource.m_mipmapCount = depthLod + 1;
 	hizSubresource.m_mipmapCount = depthLod + 1;
-	rgraphCtx.bindTexture(0, 4, getRenderer().getDepthDownscale().getHiZRt(), hizSubresource);
+	rgraphCtx.bindTexture(0, 4, getRenderer().getDepthDownscale().getRt(), hizSubresource);
 
 
 	rgraphCtx.bindColorTexture(0, 5, getRenderer().getDownscaleBlur().getRt());
 	rgraphCtx.bindColorTexture(0, 5, getRenderer().getDownscaleBlur().getRt());
 
 

+ 3 - 2
AnKi/Renderer/LensFlare.cpp

@@ -79,7 +79,8 @@ void LensFlare::populateRenderGraph(RenderingContext& ctx)
 	ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("Lens flare indirect");
 	ComputeRenderPassDescription& rpass = rgraph.newComputeRenderPass("Lens flare indirect");
 
 
 	rpass.newBufferDependency(m_runCtx.m_indirectBuffHandle, BufferUsageBit::kStorageComputeWrite);
 	rpass.newBufferDependency(m_runCtx.m_indirectBuffHandle, BufferUsageBit::kStorageComputeWrite);
-	rpass.newTextureDependency(getRenderer().getDepthDownscale().getHiZRt(), TextureUsageBit::kSampledCompute, kHiZQuarterSurface);
+	rpass.newTextureDependency(getRenderer().getDepthDownscale().getRt(), TextureUsageBit::kSampledCompute,
+							   DepthDownscale::kEighthInternalResolution);
 
 
 	rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
 	rpass.setWork([this, &ctx](RenderPassWorkContext& rgraphCtx) {
 		CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
 		CommandBuffer& cmdb = *rgraphCtx.m_commandBuffer;
@@ -102,7 +103,7 @@ void LensFlare::populateRenderGraph(RenderingContext& ctx)
 		rgraphCtx.bindStorageBuffer(0, 1, m_runCtx.m_indirectBuffHandle);
 		rgraphCtx.bindStorageBuffer(0, 1, m_runCtx.m_indirectBuffHandle);
 		// Bind neareset because you don't need high quality
 		// Bind neareset because you don't need high quality
 		cmdb.bindSampler(0, 2, getRenderer().getSamplers().m_nearestNearestClamp.get());
 		cmdb.bindSampler(0, 2, getRenderer().getSamplers().m_nearestNearestClamp.get());
-		rgraphCtx.bindTexture(0, 3, getRenderer().getDepthDownscale().getHiZRt(), kHiZQuarterSurface);
+		rgraphCtx.bindTexture(0, 3, getRenderer().getDepthDownscale().getRt(), DepthDownscale::kEighthInternalResolution);
 
 
 		cmdb.dispatchCompute(flareCount, 1, 1);
 		cmdb.dispatchCompute(flareCount, 1, 1);
 	});
 	});

+ 2 - 2
AnKi/Renderer/LightShading.cpp

@@ -178,7 +178,7 @@ void LightShading::run(const RenderingContext& ctx, RenderPassWorkContext& rgrap
 		cmdb.bindSampler(0, 1, getRenderer().getSamplers().m_trilinearClamp.get());
 		cmdb.bindSampler(0, 1, getRenderer().getSamplers().m_trilinearClamp.get());
 		rgraphCtx.bindColorTexture(0, 2, getRenderer().getIndirectDiffuse().getRt());
 		rgraphCtx.bindColorTexture(0, 2, getRenderer().getIndirectDiffuse().getRt());
 		rgraphCtx.bindColorTexture(0, 3, getRenderer().getIndirectSpecular().getRt());
 		rgraphCtx.bindColorTexture(0, 3, getRenderer().getIndirectSpecular().getRt());
-		rgraphCtx.bindColorTexture(0, 4, getRenderer().getDepthDownscale().getHiZRt());
+		rgraphCtx.bindColorTexture(0, 4, getRenderer().getDepthDownscale().getRt());
 		rgraphCtx.bindTexture(0, 5, getRenderer().getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 		rgraphCtx.bindTexture(0, 5, getRenderer().getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 		rgraphCtx.bindColorTexture(0, 6, getRenderer().getGBuffer().getColorRt(0));
 		rgraphCtx.bindColorTexture(0, 6, getRenderer().getGBuffer().getColorRt(0));
 		rgraphCtx.bindColorTexture(0, 7, getRenderer().getGBuffer().getColorRt(1));
 		rgraphCtx.bindColorTexture(0, 7, getRenderer().getGBuffer().getColorRt(1));
@@ -354,7 +354,7 @@ void LightShading::populateRenderGraph(RenderingContext& ctx)
 
 
 	// Apply indirect
 	// Apply indirect
 	pass.newTextureDependency(getRenderer().getIndirectDiffuse().getRt(), readUsage);
 	pass.newTextureDependency(getRenderer().getIndirectDiffuse().getRt(), readUsage);
-	pass.newTextureDependency(getRenderer().getDepthDownscale().getHiZRt(), readUsage);
+	pass.newTextureDependency(getRenderer().getDepthDownscale().getRt(), readUsage);
 	pass.newTextureDependency(getRenderer().getIndirectSpecular().getRt(), readUsage);
 	pass.newTextureDependency(getRenderer().getIndirectSpecular().getRt(), readUsage);
 
 
 	// Fog
 	// Fog

+ 0 - 1
AnKi/Renderer/Renderer.cpp

@@ -343,7 +343,6 @@ Error Renderer::populateRenderGraph(RenderingContext& ctx)
 	// Import RTs first
 	// Import RTs first
 	m_downscaleBlur->importRenderTargets(ctx);
 	m_downscaleBlur->importRenderTargets(ctx);
 	m_tonemapping->importRenderTargets(ctx);
 	m_tonemapping->importRenderTargets(ctx);
-	m_depthDownscale->importRenderTargets(ctx);
 	m_vrsSriGeneration->importRenderTargets(ctx);
 	m_vrsSriGeneration->importRenderTargets(ctx);
 	m_gbuffer->importRenderTargets(ctx);
 	m_gbuffer->importRenderTargets(ctx);
 
 

+ 7 - 6
AnKi/Renderer/RtShadows.cpp

@@ -168,7 +168,8 @@ void RtShadows::populateRenderGraph(RenderingContext& ctx)
 	ANKI_TRACE_SCOPED_EVENT(RRtShadows);
 	ANKI_TRACE_SCOPED_EVENT(RRtShadows);
 
 
 #define ANKI_DEPTH_DEP \
 #define ANKI_DEPTH_DEP \
-	getRenderer().getDepthDownscale().getHiZRt(), TextureUsageBit::kSampledTraceRays | TextureUsageBit::kSampledCompute, kHiZHalfSurface
+	getRenderer().getDepthDownscale().getRt(), TextureUsageBit::kSampledTraceRays | TextureUsageBit::kSampledCompute, \
+		DepthDownscale::kQuarterInternalResolution
 
 
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
 
@@ -341,7 +342,7 @@ void RtShadows::populateRenderGraph(RenderingContext& ctx)
 			rgraphCtx.bindImage(kSet, 3, m_runCtx.m_intermediateShadowsRts[0]);
 			rgraphCtx.bindImage(kSet, 3, m_runCtx.m_intermediateShadowsRts[0]);
 			rgraphCtx.bindColorTexture(kSet, 4, m_runCtx.m_historyRt);
 			rgraphCtx.bindColorTexture(kSet, 4, m_runCtx.m_historyRt);
 			cmdb.bindSampler(kSet, 5, getRenderer().getSamplers().m_trilinearClamp.get());
 			cmdb.bindSampler(kSet, 5, getRenderer().getSamplers().m_trilinearClamp.get());
-			rgraphCtx.bindTexture(kSet, 6, getRenderer().getDepthDownscale().getHiZRt(), kHiZHalfSurface);
+			rgraphCtx.bindTexture(kSet, 6, getRenderer().getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
 			rgraphCtx.bindColorTexture(kSet, 7, getRenderer().getMotionVectors().getMotionVectorsRt());
 			rgraphCtx.bindColorTexture(kSet, 7, getRenderer().getMotionVectors().getMotionVectorsRt());
 			rgraphCtx.bindColorTexture(kSet, 8, getRenderer().getMotionVectors().getHistoryLengthRt());
 			rgraphCtx.bindColorTexture(kSet, 8, getRenderer().getMotionVectors().getHistoryLengthRt());
 			rgraphCtx.bindColorTexture(kSet, 9, getRenderer().getGBuffer().getColorRt(2));
 			rgraphCtx.bindColorTexture(kSet, 9, getRenderer().getGBuffer().getColorRt(2));
@@ -415,7 +416,7 @@ void RtShadows::populateRenderGraph(RenderingContext& ctx)
 			rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_intermediateShadowsRts[0]);
 			rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_intermediateShadowsRts[0]);
 			rgraphCtx.bindColorTexture(0, 2, m_runCtx.m_currentMomentsRt);
 			rgraphCtx.bindColorTexture(0, 2, m_runCtx.m_currentMomentsRt);
 			rgraphCtx.bindColorTexture(0, 3, getRenderer().getMotionVectors().getHistoryLengthRt());
 			rgraphCtx.bindColorTexture(0, 3, getRenderer().getMotionVectors().getHistoryLengthRt());
-			rgraphCtx.bindTexture(0, 4, getRenderer().getDepthDownscale().getHiZRt(), kHiZHalfSurface);
+			rgraphCtx.bindTexture(0, 4, getRenderer().getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
 
 
 			rgraphCtx.bindImage(0, 5, m_runCtx.m_intermediateShadowsRts[1]);
 			rgraphCtx.bindImage(0, 5, m_runCtx.m_intermediateShadowsRts[1]);
 			rgraphCtx.bindImage(0, 6, m_runCtx.m_varianceRts[1]);
 			rgraphCtx.bindImage(0, 6, m_runCtx.m_varianceRts[1]);
@@ -471,7 +472,7 @@ void RtShadows::populateRenderGraph(RenderingContext& ctx)
 				cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
 				cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
 				cmdb.bindSampler(0, 1, getRenderer().getSamplers().m_trilinearClamp.get());
 				cmdb.bindSampler(0, 1, getRenderer().getSamplers().m_trilinearClamp.get());
 
 
-				rgraphCtx.bindTexture(0, 2, getRenderer().getDepthDownscale().getHiZRt(), kHiZHalfSurface);
+				rgraphCtx.bindTexture(0, 2, getRenderer().getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
 				rgraphCtx.bindColorTexture(0, 3, m_runCtx.m_intermediateShadowsRts[readRtIdx]);
 				rgraphCtx.bindColorTexture(0, 3, m_runCtx.m_intermediateShadowsRts[readRtIdx]);
 				rgraphCtx.bindColorTexture(0, 4, m_runCtx.m_varianceRts[readRtIdx]);
 				rgraphCtx.bindColorTexture(0, 4, m_runCtx.m_varianceRts[readRtIdx]);
 
 
@@ -512,7 +513,7 @@ void RtShadows::populateRenderGraph(RenderingContext& ctx)
 
 
 			rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_historyRt);
 			rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_historyRt);
 			rgraphCtx.bindImage(0, 2, m_runCtx.m_upscaledRt);
 			rgraphCtx.bindImage(0, 2, m_runCtx.m_upscaledRt);
-			rgraphCtx.bindTexture(0, 3, getRenderer().getDepthDownscale().getHiZRt(), kHiZHalfSurface);
+			rgraphCtx.bindTexture(0, 3, getRenderer().getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
 			rgraphCtx.bindTexture(0, 4, getRenderer().getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 			rgraphCtx.bindTexture(0, 4, getRenderer().getGBuffer().getDepthRt(), TextureSubresourceInfo(DepthStencilAspectBit::kDepth));
 
 
 			dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y());
 			dispatchPPCompute(cmdb, 8, 8, getRenderer().getInternalResolution().x(), getRenderer().getInternalResolution().y());
@@ -528,7 +529,7 @@ void RtShadows::runDenoise(const RenderingContext& ctx, RenderPassWorkContext& r
 
 
 	cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
 	cmdb.bindSampler(0, 0, getRenderer().getSamplers().m_nearestNearestClamp.get());
 	rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_intermediateShadowsRts[(horizontal) ? 0 : 1]);
 	rgraphCtx.bindColorTexture(0, 1, m_runCtx.m_intermediateShadowsRts[(horizontal) ? 0 : 1]);
-	rgraphCtx.bindTexture(0, 2, getRenderer().getDepthDownscale().getHiZRt(), kHiZHalfSurface);
+	rgraphCtx.bindTexture(0, 2, getRenderer().getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
 	rgraphCtx.bindColorTexture(0, 3, getRenderer().getGBuffer().getColorRt(2));
 	rgraphCtx.bindColorTexture(0, 3, getRenderer().getGBuffer().getColorRt(2));
 	rgraphCtx.bindColorTexture(0, 4, m_runCtx.m_currentMomentsRt);
 	rgraphCtx.bindColorTexture(0, 4, m_runCtx.m_currentMomentsRt);
 	rgraphCtx.bindColorTexture(0, 5, getRenderer().getMotionVectors().getHistoryLengthRt());
 	rgraphCtx.bindColorTexture(0, 5, getRenderer().getMotionVectors().getHistoryLengthRt());

+ 3 - 3
AnKi/Renderer/ShadowmapsResolve.cpp

@@ -76,7 +76,7 @@ void ShadowmapsResolve::populateRenderGraph(RenderingContext& ctx)
 		});
 		});
 
 
 		rpass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kImageComputeWrite);
 		rpass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kImageComputeWrite);
-		rpass.newTextureDependency((m_quarterRez) ? getRenderer().getDepthDownscale().getHiZRt() : getRenderer().getGBuffer().getDepthRt(),
+		rpass.newTextureDependency((m_quarterRez) ? getRenderer().getDepthDownscale().getRt() : getRenderer().getGBuffer().getDepthRt(),
 								   TextureUsageBit::kSampledCompute, TextureSurfaceInfo(0, 0, 0, 0));
 								   TextureUsageBit::kSampledCompute, TextureSurfaceInfo(0, 0, 0, 0));
 		rpass.newTextureDependency(getRenderer().getShadowMapping().getShadowmapRt(), TextureUsageBit::kSampledCompute);
 		rpass.newTextureDependency(getRenderer().getShadowMapping().getShadowmapRt(), TextureUsageBit::kSampledCompute);
 
 
@@ -99,7 +99,7 @@ void ShadowmapsResolve::populateRenderGraph(RenderingContext& ctx)
 		});
 		});
 
 
 		rpass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kFramebufferWrite);
 		rpass.newTextureDependency(m_runCtx.m_rt, TextureUsageBit::kFramebufferWrite);
-		rpass.newTextureDependency((m_quarterRez) ? getRenderer().getDepthDownscale().getHiZRt() : getRenderer().getGBuffer().getDepthRt(),
+		rpass.newTextureDependency((m_quarterRez) ? getRenderer().getDepthDownscale().getRt() : getRenderer().getGBuffer().getDepthRt(),
 								   TextureUsageBit::kSampledFragment, TextureSurfaceInfo(0, 0, 0, 0));
 								   TextureUsageBit::kSampledFragment, TextureSurfaceInfo(0, 0, 0, 0));
 		rpass.newTextureDependency(getRenderer().getShadowMapping().getShadowmapRt(), TextureUsageBit::kSampledFragment);
 		rpass.newTextureDependency(getRenderer().getShadowMapping().getShadowmapRt(), TextureUsageBit::kSampledFragment);
 
 
@@ -131,7 +131,7 @@ void ShadowmapsResolve::run(RenderPassWorkContext& rgraphCtx)
 
 
 	if(m_quarterRez)
 	if(m_quarterRez)
 	{
 	{
-		rgraphCtx.bindTexture(0, 7, getRenderer().getDepthDownscale().getHiZRt(), TextureSubresourceInfo(TextureSurfaceInfo(0, 0, 0, 0)));
+		rgraphCtx.bindTexture(0, 7, getRenderer().getDepthDownscale().getRt(), DepthDownscale::kQuarterInternalResolution);
 	}
 	}
 	else
 	else
 	{
 	{

+ 3 - 2
AnKi/Renderer/Utils/HzbGenerator.cpp

@@ -134,7 +134,8 @@ void HzbGenerator::populateRenderGraphInternal(ConstWeakArray<DispatchInput> dis
 		{
 		{
 			const DispatchInput& in = dispatchInputsCopy[dispatch];
 			const DispatchInput& in = dispatchInputsCopy[dispatch];
 
 
-			const U32 hzbMipCount = min(kMaxSpdMips, computeMaxMipmapCount2d(in.m_dstHzbRtSize.x(), in.m_dstHzbRtSize.y()));
+			const U32 hzbMipCount =
+				min(kMaxMipsSinglePassDownsamplerCanProduce, computeMaxMipmapCount2d(in.m_dstHzbRtSize.x(), in.m_dstHzbRtSize.y()));
 
 
 			const U32 mipsToCompute = hzbMipCount;
 			const U32 mipsToCompute = hzbMipCount;
 
 
@@ -157,7 +158,7 @@ void HzbGenerator::populateRenderGraphInternal(ConstWeakArray<DispatchInput> dis
 
 
 			cmdb.setPushConstants(&pc, sizeof(pc));
 			cmdb.setPushConstants(&pc, sizeof(pc));
 
 
-			for(U32 mip = 0; mip < kMaxSpdMips; ++mip)
+			for(U32 mip = 0; mip < kMaxMipsSinglePassDownsamplerCanProduce; ++mip)
 			{
 			{
 				TextureSubresourceInfo subresource;
 				TextureSubresourceInfo subresource;
 				if(mip < mipsToCompute)
 				if(mip < mipsToCompute)

+ 0 - 2
AnKi/Renderer/Utils/HzbGenerator.h

@@ -35,8 +35,6 @@ private:
 		UVec2 m_dstHzbRtSize;
 		UVec2 m_dstHzbRtSize;
 	};
 	};
 
 
-	static constexpr U32 kMaxSpdMips = 12;
-
 	ShaderProgramResourcePtr m_genPyramidProg;
 	ShaderProgramResourcePtr m_genPyramidProg;
 	ShaderProgramPtr m_genPyramidGrProg;
 	ShaderProgramPtr m_genPyramidGrProg;
 
 

+ 9 - 26
AnKi/Shaders/DepthDownscaleCompute.ankiprog

@@ -13,13 +13,11 @@
 
 
 [[vk::push_constant]] ConstantBuffer<DepthDownscaleUniforms> g_uniforms;
 [[vk::push_constant]] ConstantBuffer<DepthDownscaleUniforms> g_uniforms;
 
 
-[[vk::binding(0)]] RWTexture2D<Vec4> g_dstUavs[12u];
-[[vk::binding(1)]] globallycoherent RWTexture2D<Vec4> g_dstUav5;
-[[vk::binding(2)]] globallycoherent RWStructuredBuffer<U32> g_spdCounter;
-[[vk::binding(3)]] RWStructuredBuffer<F32> g_clientBuff;
+[[vk::binding(0)]] RWTexture2D<Vec4> g_dstUavs[kMaxMipsSinglePassDownsamplerCanProduce];
+[[vk::binding(1)]] globallycoherent RWStructuredBuffer<U32> g_spdCounter;
 
 
-[[vk::binding(4)]] SamplerState u_linearAnyClampSampler;
-[[vk::binding(5)]] Texture2D g_srcTex;
+[[vk::binding(2)]] SamplerState u_linearAnyClampSampler;
+[[vk::binding(3)]] Texture2D g_srcTex;
 
 
 // Include SPD
 // Include SPD
 #define A_GPU 1
 #define A_GPU 1
@@ -39,28 +37,13 @@ AF4 SpdLoadSourceImage(AU2 p, AU1 slice)
 AF4 SpdLoad(AU2 p, AU1 slice)
 AF4 SpdLoad(AU2 p, AU1 slice)
 {
 {
 	ANKI_MAYBE_UNUSED(slice);
 	ANKI_MAYBE_UNUSED(slice);
-	return AF4(g_dstUav5[UVec2(p)].r, 0.0, 0.0, 0.0);
+	return AF4(g_dstUavs[5][p].r, 0.0, 0.0, 0.0);
 }
 }
 
 
 void SpdStore(AU2 p, AF4 value, AU1 mip, AU1 slice)
 void SpdStore(AU2 p, AF4 value, AU1 mip, AU1 slice)
 {
 {
 	ANKI_MAYBE_UNUSED(slice);
 	ANKI_MAYBE_UNUSED(slice);
-
-	if(mip == 5u)
-	{
-		g_dstUav5[UVec2(p)] = Vec4(value.x, 0.0, 0.0, 0.0);
-	}
-	else
-	{
-		g_dstUavs[mip][UVec2(p)] = Vec4(value.x, 0.0, 0.0, 0.0);
-	}
-
-	// Store the last mip to the buffer as well
-	if(mip == g_uniforms.m_mipmapCount - 1u)
-	{
-		const U32 idx = p.y * g_uniforms.m_lastMipWidth + p.x;
-		g_clientBuff[idx] = value.x;
-	}
+	g_dstUavs[mip][p] = Vec4(value.x, 0.0, 0.0, 0.0);
 }
 }
 
 
 void SpdIncreaseAtomicCounter(AU1 slice)
 void SpdIncreaseAtomicCounter(AU1 slice)
@@ -92,8 +75,8 @@ void SpdStoreIntermediate(AU1 x, AU1 y, AF4 value)
 
 
 AF4 SpdReduce4(AF4 v0, AF4 v1, AF4 v2, AF4 v3)
 AF4 SpdReduce4(AF4 v0, AF4 v1, AF4 v2, AF4 v3)
 {
 {
-	const F32 maxDepth = max(v0.x, max(v1.x, max(v2.x, v3.x)));
-	return AF4(maxDepth, 0.0, 0.0, 0.0);
+	const F32 avg = (v0.x + v1.x + v2.x + v3.x) / 4.0f;
+	return AF4(avg, 0.0, 0.0, 0.0);
 }
 }
 
 
 #define SPD_LINEAR_SAMPLER 1
 #define SPD_LINEAR_SAMPLER 1
@@ -108,7 +91,7 @@ AF4 SpdReduce4(AF4 v0, AF4 v1, AF4 v2, AF4 v3)
 {
 {
 	const U32 slice = 0u;
 	const U32 slice = 0u;
 	const UVec2 offset = UVec2(0, 0);
 	const UVec2 offset = UVec2(0, 0);
-	SpdDownsample(AU2(svGroupId.xy), AU1(svGroupIndex), AU1(g_uniforms.m_mipmapCount), AU1(g_uniforms.m_workgroupCount), slice, offset);
+	SpdDownsample(AU2(svGroupId.xy), AU1(svGroupIndex), AU1(g_uniforms.m_mipmapCount), AU1(g_uniforms.m_threadgroupCount), slice, offset);
 }
 }
 
 
 #pragma anki end
 #pragma anki end

+ 4 - 29
AnKi/Shaders/DepthDownscaleRaster.ankiprog

@@ -3,8 +3,6 @@
 // Code licensed under the BSD License.
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 // http://www.anki3d.org/LICENSE
 
 
-#pragma anki mutator REDUCTION_SAMPLER 0 1
-
 #pragma anki start vert
 #pragma anki start vert
 #include <AnKi/Shaders/QuadVert.hlsl>
 #include <AnKi/Shaders/QuadVert.hlsl>
 #pragma anki end
 #pragma anki end
@@ -12,34 +10,11 @@
 #pragma anki start frag
 #pragma anki start frag
 #include <AnKi/Shaders/Common.hlsl>
 #include <AnKi/Shaders/Common.hlsl>
 
 
-[[vk::binding(0)]] Texture2D g_inputTex;
-[[vk::binding(1)]] SamplerState g_sampler;
-[[vk::binding(2)]] RWStructuredBuffer<F32> g_clientBuff;
-
-struct Uniforms
-{
-	Vec3 m_padding;
-	U32 m_lastMipWidth;
-};
-[[vk::push_constant]] ConstantBuffer<Uniforms> g_uniforms;
+[[vk::binding(0)]] Texture2D<Vec4> g_inputTex;
+[[vk::binding(1)]] SamplerState g_linearAnyClampSampler;
 
 
-F32 main([[vk::location(0)]] Vec2 uv : TEXCOORD, Vec4 svPosition : SV_POSITION) : SV_TARGET0
+F32 main([[vk::location(0)]] Vec2 uv : TEXCOORD) : SV_TARGET0
 {
 {
-	F32 output;
-#if REDUCTION_SAMPLER
-	output = g_inputTex.SampleLevel(g_sampler, uv, 0.0).x;
-#else
-	const Vec4 depths = g_inputTex.GatherRed(g_sampler, uv);
-	output = max(depths.x, max(depths.y, max(depths.z, depths.w)));
-#endif
-
-	if(g_uniforms.m_lastMipWidth != 0u)
-	{
-		const UVec2 p = UVec2(svPosition.xy);
-		const U32 idx = p.y * g_uniforms.m_lastMipWidth + p.x;
-		g_clientBuff[idx] = output;
-	}
-
-	return output;
+	return g_inputTex.SampleLevel(g_linearAnyClampSampler, uv, 0.0).x;
 }
 }
 #pragma anki end
 #pragma anki end

+ 2 - 3
AnKi/Shaders/HzbGenPyramid.ankiprog

@@ -18,7 +18,7 @@ struct Uniforms
 
 
 [[vk::push_constant]] ConstantBuffer<Uniforms> g_uniforms;
 [[vk::push_constant]] ConstantBuffer<Uniforms> g_uniforms;
 
 
-[[vk::binding(0)]] globallycoherent RWTexture2D<Vec4> g_dstUavs[12u];
+[[vk::binding(0)]] globallycoherent RWTexture2D<Vec4> g_dstUavs[kMaxMipsSinglePassDownsamplerCanProduce];
 [[vk::binding(1)]] globallycoherent RWStructuredBuffer<U32> g_spdCounter;
 [[vk::binding(1)]] globallycoherent RWStructuredBuffer<U32> g_spdCounter;
 [[vk::binding(2)]] Texture2D<Vec4> g_srcTex;
 [[vk::binding(2)]] Texture2D<Vec4> g_srcTex;
 
 
@@ -59,8 +59,7 @@ AF4 SpdLoadSourceImage(AU2 p, AU1 slice)
 AF4 SpdLoad(AU2 p, AU1 slice)
 AF4 SpdLoad(AU2 p, AU1 slice)
 {
 {
 	ANKI_MAYBE_UNUSED(slice);
 	ANKI_MAYBE_UNUSED(slice);
-	const F32 f = g_dstUavs[5][p].r;
-	return AF4(f, 0.0, 0.0, 0.0);
+	return AF4(g_dstUavs[5][p].r, 0.0, 0.0, 0.0);
 }
 }
 
 
 void SpdStore(AU2 p, AF4 value, AU1 mip, AU1 slice)
 void SpdStore(AU2 p, AF4 value, AU1 mip, AU1 slice)

+ 2 - 0
AnKi/Shaders/Include/Common.h

@@ -702,6 +702,8 @@ constexpr U32 kMaxShadowCascades = 4u;
 constexpr F32 kShadowsPolygonOffsetFactor = 1.25f;
 constexpr F32 kShadowsPolygonOffsetFactor = 1.25f;
 constexpr F32 kShadowsPolygonOffsetUnits = 2.75f;
 constexpr F32 kShadowsPolygonOffsetUnits = 2.75f;
 
 
+constexpr U32 kMaxMipsSinglePassDownsamplerCanProduce = 12u;
+
 struct DrawIndirectArgs
 struct DrawIndirectArgs
 {
 {
 	U32 m_vertexCount;
 	U32 m_vertexCount;

+ 1 - 6
AnKi/Shaders/Include/MiscRendererTypes.h

@@ -72,13 +72,8 @@ struct LensFlareSprite
 struct DepthDownscaleUniforms
 struct DepthDownscaleUniforms
 {
 {
 	Vec2 m_srcTexSizeOverOne;
 	Vec2 m_srcTexSizeOverOne;
-	U32 m_workgroupCount;
+	U32 m_threadgroupCount;
 	U32 m_mipmapCount;
 	U32 m_mipmapCount;
-
-	U32 m_lastMipWidth;
-	F32 m_padding0;
-	F32 m_padding1;
-	F32 m_padding2;
 };
 };
 
 
 // Screen space reflections uniforms
 // Screen space reflections uniforms